Web前端開發(fā)規(guī)范文檔

Web前端開發(fā)規(guī)范文檔

規(guī)范目的:

  • 使開發(fā)流程更加規(guī)范化。

通用規(guī)范:

  • TAB鍵用兩個空格代替(WINDOWS下TAB鍵占四個空格落追,LINUX下TAB鍵占八個空格)盈滴。

  • CSS樣式屬性或者JAVASCRIPT代碼后加“;”方便壓縮工具“斷句”。

  • 文件內容編碼均統(tǒng)一為UTF-8轿钠。

  • CSS巢钓、JAVASCRIPT中的非注釋類中文字符須轉換成unicode編碼使用,
    以避免編碼錯誤時亂碼顯示病苗。

文件規(guī)范:

  • 文件名用英文單詞,多個單詞用駝峰命名法症汹。

  • 一些瀏覽器會將含有這些詞的作為廣告攔截硫朦,文件命名、ID烈菌、CLASS等所有命名避免以上詞匯阵幸。

    ``` adads芽世、advbanner诡壁、sponsor济瓢、ggguangg妹卿、guanggao

    
    

html書寫規(guī)范:

  • 為每個HTML頁面的第一行添加標準模式(standard
    mode)的聲明旺矾,確保在每個瀏覽器中擁有一致的展現。

    <!DOCTYPE html>
    

    文檔類型聲明統(tǒng)一為HTML5聲明類型夺克,編碼統(tǒng)一為UTF-8箕宙。

    <meta charset="UTF-8">
    

    <HEAD>中添加信息。

    <meta name="author" content="smile@kang.cool">//作者
    <meta name="description" content="hello">//網頁描述
    <meta name="keywords" content="a,b,c">//關鍵字,“铺纽,”分隔
    <meta http-equiv="expires" content="Wed, 26 Feb 1997 08:21:57 GMT">//設定網頁的到期時間柬帕。一旦網頁過期,必須到服務器上重新調閱
    <meta http-equiv="Pragma" content="no-cache">//禁止瀏覽器從本地機的緩存中調閱頁面內容
    <meta http-equiv="Window-target" content="_top">//用來防止別人在框架里調用你的頁面
    <meta http-equiv="Refresh" content="5;URL=http://kahn1990.com/">//跳轉頁面狡门,5指時間停留5秒 網頁搜索機器人向導陷寝。用來告訴搜索機器人哪些頁面需要索引,哪些頁面不需要索引
    <meta name="robots" content="none">//content的參數有all,none,index,noindex,follow,nofollow其馏,默認是all
    <link rel="Shortcut Icon" href="favicon.ico">//收藏圖標
    <meta http-equiv="Cache-Control" content="no-cache, must-revalidate">//網頁不會被緩存
    

    IE支持通過特定<meta>標簽來確定繪制當前頁面所應該采用的IE版本凤跑。除非有強烈的特殊需求,否則最好是設置為edge
    mode 叛复,從而通知IE采用其所支持的最新的模式仔引。

    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    
  • 非特殊情況下CSS樣式文件外鏈至HEAD之間,JAVASCRIPT文件外鏈至頁面底部褐奥。

    <!DOCTYPE html>
    <html>
    <head>
        <link rel="stylesheet" href="css/main.css">
    </head>
    <body>
        <!-- 邏輯代碼 -->
        <!-- 邏輯代碼底部 -->
        <script src="lib/jquery/jquery-2.1.1.min.js"></script>
    </body>
    </html>
    

    引入JAVASCRIPT庫文件咖耘,文件名須包含庫名稱及版本號及是否為壓縮版。

    jQuery-1.8.3.min.js
    

    引入JAVASCRIPT插件, 文件名格式為庫名稱+.+插件名稱抖僵。

    jQuery.cookie.js
    
  • HTML屬性應當按照以下給出的順序依次排列潦牛,來確保代碼的易讀性。

    class
    id 证逻、 name
    data-*
    src、for找筝、 type、 href
    title慷吊、alt
    aria-*袖裕、 role
    

    編碼均遵循XHTML標準,
    標簽、屬性溉瓶、屬性命名由小寫英文急鳄、數字和_組成,且所有標簽必須閉合堰酿,屬性值必須用雙引號"",
    避免使用中文拼音盡量簡易并要求語義化疾宏。

    CLASS --> nHeadTitle --> CLASS遵循小駝峰命名法(little camel-case)
    ID --> n_head_title --> ID遵循名稱+_
    NAME --> N_Head_Title --> NAME屬性命名遵循首個字母大寫+_
    <div class="nHeadTitle" id="n_head_title" name="N_Head_Title"></div>
    

    JAVASCRIPT獲取單個元素時,通常使用document.getElementById來獲取dom元素触创,document.getElementById兼容所有瀏覽器坎藐,但IE瀏覽器會混淆元素的ID和NAME屬性,所以要區(qū)分ID和NAME命名哼绑。

    <input type="text" name="test">
    <div id="test"></div>
    <button onclick="alert(document.getElementById('test').tagName)"></button>
    <!-- ie6下為INPUT -->
    
  • 特殊符號應使用轉意符岩馍。

    <    -->    <
    >    -->    >
    空格  -->     
    
  • 含有描述性表單元素(INPUTTEXTAREA)添加LABEL抖韩。

    <p>
        <label for="test">測試</label>
        <input type="text" id="test" />
    </p>
    
  • 多用無兼容性問題的HTML內置標簽,
    比如SPAN蛀恩、EM、STRONG茂浮、OPTGROUP双谆、LABEL等,需要自定義HTML標簽屬性時,首先考慮是否存在已有的合適標簽可替換励稳,如果沒有,
    可使用須以“data-”為前綴來添加自定義屬性佃乘,避免使用其他命名方式。

  • 語義化HTML驹尼。

  • 盡可能減少<DIV>嵌套趣避。

  • 書寫鏈接地址時避免重定向。

     //即在URL地址后面加“/”
    
  • HTML中對于屬性的定義新翎,確保全部使用雙引號程帕,絕不要使用單引號

css書寫規(guī)范:

  • 為了欺騙W3C的驗證工具,可將代碼分為兩個文件,一個是針對所有瀏覽器,一個只針對IE地啰。即將所有符合W3C的代碼寫到一個文件中,而一些IE中必須而又不能通過W3C驗證的代碼(如:
    cursor:hand;)放到另一個文件中愁拭,再用下面的方法導入。

    <!-- 放置所有瀏覽器樣式-->
    <link rel="stylesheet" type="text/css" href="">
    <!-- 只放置IE必須亏吝,而不能通過w3c的-->
    <!--[if IE]
        <link rel="stylesheet" href="">
    <![endif]-->
    
  • CSS樣式新建或修改盡量遵循以下原則岭埠。

    根據新建樣式的適用范圍分為三級:全站級、產品級、頁面級惜论。
    盡量通過繼承和層疊重用已有樣式许赃。
    不要輕易改動全站級CSS。改動后馆类,要經過全面測試混聊。
    
  • CSS屬性顯示順序。

    顯示屬性
    元素位置
    元素屬性
    元素內容屬性
    

    CSS書寫順序乾巧。

    .header {
    /* 顯示屬性 */
        display || visibility
        list-style
        position top || right || bottom || left
        z-index
        clear
        float
    /* 自身屬性 */
        width max-width || min-width
        height max-height || min-height
        overflow || clip
        margin
        padding
        outline
        border
        background
    /* 文本屬性 */
        color
        font
        text-overflow
        text-align
        text-indent
        line-height
        white-space
        vertical-align
        cursor
        content
        };
    

    兼容多個瀏覽器時句喜,將標準屬性寫在底部。

    -moz-border-radius: 15px; /* Firefox */
    -webkit-border-radius: 15px; /* Safari和Chrome */
    border-radius: 15px; /* Opera 10.5+, 以及使用了IE-CSS3的IE瀏覽器 *//標準屬性
    
  • 使用選擇器時沟于,命名比較短的詞匯或者縮寫的不允許直接定義樣式咳胃。

    .hd,.bd,.td{};//如這些命名
    

    可用上級節(jié)點進行限定。

    .recommend-mod .hd
    

    多選擇器規(guī)則之間換行旷太,即當樣式針對多個選擇器時每個選擇器占一行拙绊。

    button.btn,
    input.btn,
    input[type="button"] {…};
    

    優(yōu)化CSS選擇器。

    #header a { color: #444; };/*CSS選擇器是從右邊到左邊進行匹配*/
    

    瀏覽器將檢查整個文檔中的所有鏈接和每個鏈接的父元素泳秀,并遍歷文檔樹去查找ID為header的祖先元素,如果找不到header將追溯到文檔的根節(jié)點榄攀,解決方法如下嗜傅。

    避免使用通配規(guī)則和相鄰兄弟選擇符、子選擇符,檩赢、后代選擇符吕嘀、屬性選擇符等選擇器
    不要限定id選擇符,如div#header(提權的除外)
    不要限定類選擇器贞瞒,如ul.recommend(提權的除外)
    不要使用 ul li a 這樣長的選擇符
    避免使用標簽子選擇符偶房,如#header > li > a
    
  • 使用z-index屬性盡量z-index的值不要超過150(通用組的除外),頁面中的元素內容的z-index不能超過10(提示框等模塊除外但維持在150以下)军浆,不允許直接使用(999~9999)之間大值棕洋。

  • 盡量避免使用CSS Hack。

    property:value; /* 所有瀏覽器 */
    +property:value; /* IE7 */
    _property:value; /* IE6 */
    *property:value; /* IE6/7 */
    property:value\9; /* IE6/7/8/9乒融,即所有IE瀏覽器 */
    
    * html selector { … }; /* IE6 */
    *:first-child+html selector { … }; /* IE7 */
    html>body selector { … }; /* 非IE6 */
    @-moz-document url-prefix() { … }; /* firefox */
    @media all and (-webkit-min-device-pixel-ratio:0) { … }; /* saf3+/chrome1+ */
    @media all and (-webkit-min-device-pixel-ratio:10000),not all and (-webkit-min-device-pixel-ratio:0) { … }; /* opera */
    @media screen and (max-device-width: 480px) { … }; /* iPhone/mobile webkit */
    

    避免使用低效的選擇器掰盘。

    body > * {…};
    ul > li > a {…};
    #footer > h3 {…};
    ul#top_blue_nav {…};
    #searbar span.submit a { … }; /* 反面示例 */
    
  • 六個不要三個避免一個使用。

    不要在標簽上直接寫樣式
    不要在CSS中使用expression
    不要在CSS中使用@import
    不要在CSS中使用!important
    不要在CSS中使用“*”選擇符
    不要將CSS樣式寫為單行
    避免使用filter
    避免使用行內(inline)樣式
    避免使用“*”設置{margin: 0; padding: 0;}
    使用after或overflow的方式清浮動
    
  • 減少使用影響性能的屬性赞季。

    position:absolute;
    float:left;//如這些定位或浮動屬性
    

    減少在CSS中使用濾鏡表達式和圖片repeat,
    尤其在body當中,渲染性能極差, 如果需要用repeat的話,
    圖片的寬或高不能少于8px愧捕。

javaScript書寫規(guī)范:

  • 命名規(guī)范。

    常量名
        全部大寫并單詞間用下劃線分隔
        如:CSS_BTN_CLOSE申钩、TXT_LOADING
    
    對象的屬性或方法名
        小駝峰式(little camel-case)
        如:init次绘、bindEvent、updatePosition
        示例:Dialog.prototype = {
                    init: function () {},
                    bindEvent: function () {},
                    updatePosition: function () {}
                    …
                    };
    類名(構造器)
        -->小駝峰式但首字母大寫
        -->如:Current、DefaultConfig
    函數名
        -->小駝峰式
        -->如:current()邮偎、defaultConfig()
    變量名
        -->小駝峰式
        -->如:current管跺、defaultConfig
    私有變量名
        -->小駝峰式但需要用_開頭
        -->如:_current、_defaultConfig
    變量名的前綴
        -->續(xù)
    
  • 代碼格式钢猛。

    "()"前后需要跟空格
    "="前后需要跟空格
    ","后面需要跟空格
    JSON對象需格式化對象參數
    if伙菜、while、for命迈、do語句的執(zhí)行體用"{}"括起來
    

    "{}"格式如下贩绕。

    if (a==1) {
        //代碼
    };
    

    避免額外的逗號。

    var arr = [1,2,3,];
    

    for-in循環(huán)體中必須用hasOwnProperty方法檢查成員是否為自身成員壶愤,避免來自原型鏈上的污染淑倾。

  • 長語句可考慮斷行。

    TEMPL_SONGLIST.replace('{TABLE}', da['results'])
        .replace('{PREV_NUM}', prev)
        .replace('{NEXT_NUM}', next)
        .replace('{CURRENT_NUM}', current)
        .replace('{TOTAL_NUM}', da.page_total);
    

    為了避免和JSLint的檢驗機制沖突征椒,“.”或“+”這類操作符放在行尾娇哆。

    TEMPL_SONGLIST.replace('{TABLE}', da['results']).
        replace('{PREV_NUM}', prev).
        replace('{NEXT_NUM}', next).
        replace('{CURRENT_NUM}', current).
        replace('{TOTAL_NUM}', da.page_total);
    

    如果模塊代碼中,使用其它全局變量想跳過JSLint的檢查勃救,可以在該文件中加入/*global*/聲明碍讨。

    /*global alert: true, console: true, top: true, setTimeout: true */
    
  • 使用嚴格的條件判斷符。用===代替==蒙秒,用!==代替!=勃黍,避免掉入==造成的陷阱
    在條件判斷時,這樣的一些值表示false晕讲。

    null
    undefined與null相等
    字符串''
    數字0
    NaN
    

    在==時覆获,則會有一些讓人難以理解的陷阱。

    (function () {
        var undefined;
        undefined == null; // true
        1 == true; //true
        2 == true; // false
        0 == false; // true
        0 == ''; // true
        NaN == NaN;// false
        [] == false; // true
        [] == ![]; // true
    })();
    

    對于不同類型的 == 判斷瓢省,有這樣一些規(guī)則弄息,順序自上而下:

    undefined與null相等
    一個是number一個是string時,會嘗試將string轉換為number
    嘗試將boolean轉換為number
    0或1
    嘗試將Object轉換成number或string
    

    而這些取決于另外一個對比量勤婚,即值的類型摹量,所以對于0、空字符串的判斷蛔六,建議使用===
    荆永。===會先判斷兩邊的值類型,類型不匹配時為false国章。

  • 下面類型的對象不建議用new構造具钥。

    new Number
    new String
    new Boolean
    new Object //用{}代替
    new Array //用[]代替
    

    引用對象成員用obj.prop代替obj["prop"],除非屬性名是變量液兽。

  • 從number到string的轉換骂删。

    /** 推薦寫法*/
    var a = 1;
    typeof(a); //"number"
    console.log(a); //1
    var aa=a+'';
    typeof(aa); //"string"
    console.log(aa); //'1'
    /** 不推薦寫法*/
    new String(a)或a.toString()
    

    從string到number的轉換掌动,使用parseInt,必須顯式指定第二個參數的進制宁玫。

    /** 推薦寫法*/
    var a = '1';
    var aa = parseInt(a,10);
    typeof(a); //"string"
    console.log(a); //'1'
    typeof(aa); //"number"
    console.log(aa); //1
    

    從float到integer的轉換粗恢。

    /** 推薦寫法*/
    Math.floor/Math.round/Math.ceil
    /** 不推薦寫法*/
    parseInt
    

    字符串拼接應使用數組保存字符串片段,使用時調用join方法欧瘪。避免使用+或+=的方式拼接較長的字符串眷射,每個字符串都會使用一個小的內存片段,過多的內存片段會影響性能佛掖。

    /**推薦的拼接方式array的push妖碉、join*/
    var str=[],
        list=['測試A','測試B'];
    for (var i=0 , len=list.length; i < len; i++) {
        str.push( '<div>'+ list[i] + '</div>');
    };
    console.log(str.join('')); //<div>測試A</div><div>測試B</div>
    /** 不推薦的拼接方式+=*/
    var str = '',
        list=['測試A','測試B'];
    for (var i = 0, len = list.length; i< len; i++) {
        str+='<div>' + list[i] + '</div>';
    };
    console.log(str); //<div>測試A</div><div>測試B</div>
    
  • 盡量避免使用存在兼容性及消耗資源的方法或屬性。

    不要使用with芥被,void欧宜,evil,eval_r拴魄,innerText
    
  • 注重HTML分離, 減小reflow, 注重性能冗茸。

圖片規(guī)范:

  • 命名應用小寫英文數字匹中、_組合夏漱,便于團隊其他成員理解。

    header_btn.gif
    header_btn2.gif
    
  • 頁面元素類圖片均放入img文件夾,
    測試用圖片放于img/testimg文件夾顶捷,psd源圖放入img/psdimg文件夾麻蹋。

  • 圖片格式僅限于gifpng焊切、jpg等。

  • png圖片做圖片時,
    要求圖片格式為png-8格式,若png-8實在影響圖片質量或其中有半透明效果,
    請為ie-6單獨定義背景芳室,并盡量避免使用半透明的png圖片专肪。

  • 背景圖片請盡可能使用sprite技術, 減小http請求。

注釋規(guī)范:

  • JAVASCRIPT堪侯、CSS文件注釋需要標明作者嚎尤、文件版本、創(chuàng)建/修改時間伍宦、重大版本修改記錄芽死、函數描述、文件版本次洼、創(chuàng)建或者修改時間关贵、功能、作者等信息卖毁。

    /* * 注釋塊 */
    

    中間可添加如下信息揖曾。

    @file 文件名
    @addon 把一個函數標記為另一個函數的擴張,另一個函數的定義不在源文件中
    @argument 用大括號中的自變量類型描述一個自變量
    @author 函數/類作者的姓名
    @base 如果類是繼承得來,定義提供的類名稱
    @class 用來給一個類提供描述炭剪,不能用于構造器的文檔中
    @constructor 描述一個類的構造器
    @deprecated 表示函數/類已被忽略
    @exception 描述函數/類產生的一個錯誤
    @exec @extends 表示派生出當前類的另一個類
    @fileoverview 表示文檔塊將用于描述當前文件练链,這個標簽應該放在其它任何標簽之前
    @final 指出函數/類
    @ignore 讓jsdoc忽視隨后的代碼
    @link 類似于@link標簽,用于連接許多其它頁面
    @member 定義隨后的函數為提供的類名稱的一個成員
    @param 用大括號中的參數類型描述一個參數
    @private 表示函數/類為私有奴拦,不應包含在生成的文檔中
    @requires 表示需要另一個函數/類
    @return 描述一個函數的返回值
    @see 連接到另一個函數/類
    @throws 描述函數/類可能產生的錯誤
    @type 指定函數/成員的返回類型
    @version 函數/類的版本號
    

開發(fā)及測試工具約定:

  • 編碼格式化媒鼓,三碼統(tǒng)一。

  • 測試工具: 前期開發(fā)僅測試FireFox & IE6 & IE7 & IE8 & IE9 & Opera &
    Chrome & Safari

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末错妖,一起剝皮案震驚了整個濱河市绿鸣,隨后出現的幾起案子,更是在濱河造成了極大的恐慌站玄,老刑警劉巖枚驻,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異株旷,居然都是意外死亡再登,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門晾剖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锉矢,“玉大人,你說我怎么就攤上這事齿尽」了穑” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵循头,是天一觀的道長绵估。 經常有香客問我,道長卡骂,這世上最難降的妖魔是什么国裳? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮全跨,結果婚禮上缝左,老公的妹妹穿的比我還像新娘。我一直安慰自己浓若,他們只是感情好渺杉,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挪钓,像睡著了一般是越。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碌上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天英妓,我揣著相機與錄音挽放,去河邊找鬼。 笑死蔓纠,一個胖子當著我的面吹牛辑畦,可吹牛的內容都是我干的。 我是一名探鬼主播腿倚,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼纯出,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了敷燎?” 一聲冷哼從身側響起暂筝,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎硬贯,沒想到半個月后焕襟,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡饭豹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年鸵赖,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拄衰。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡它褪,死狀恐怖,靈堂內的尸體忽然破棺而出翘悉,到底是詐尸還是另有隱情茫打,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布妖混,位于F島的核電站老赤,受9級特大地震影響,放射性物質發(fā)生泄漏制市。R本人自食惡果不足惜诗越,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望息堂。 院中可真熱鬧,春花似錦块促、人聲如沸荣堰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽振坚。三九已至,卻和暖如春斋扰,著一層夾襖步出監(jiān)牢的瞬間渡八,已是汗流浹背啃洋。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留屎鳍,地道東北人宏娄。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像逮壁,于是被迫代替她去往敵國和親孵坚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內容

  • 基本準則 符合web標準窥淆,html語義化卖宠;html,css忧饭,JavaScript分離扛伍;代碼簡潔有序,盡可能減少冗余...
    喵嗚君閱讀 787評論 0 1
  • 一.規(guī)范目的 使開發(fā)流程更加規(guī)范化词裤。 二.通用規(guī)范 TAB鍵用兩個空格代替(WINDOWS下TAB鍵占四個空格刺洒,L...
    overflow_hidden閱讀 2,419評論 0 0
  • 在新媒體盛行的今天作媚,幾乎人人都開公眾號,但是粉絲數卻相差甚遠帅刊,無論公眾號的定位是什么領域纸泡,其本質都是,滿足讀者的認...
    Miss墨菲閱讀 262評論 8 6
  • 最近上海的雨連綿不斷赖瞒,倒也還好女揭,現在的上海,比起雨季的廈門不會太過潮濕栏饮。提起了廈門吧兔,真的有些想念它,想念那可以解憂...
    靜覺閱讀 263評論 2 2
  • 系統(tǒng)實現機制涉及的關鍵技術 1. 系統(tǒng)實現機制 采集系統(tǒng)通過Strus2實現了MVC模式袍嬉。實現機制如下: 2. 涉...
    艾剪疏閱讀 1,092評論 0 1