九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
前端開發(fā)學習指南 | 轉自菜鳥教程

 這篇文章很長,但的確是一篇非常干的干貨,講訴了 HTML、JavaScript、CSS、jQuery使用的一些規(guī)范與建議,前端的同學可以認真閱讀此文,并比較自己平時的一些習慣,看是否有改進的地方……


HTML

咋地了, DOCTYPE?

不定義DOCTYPE是一種可以被判死刑的罪行。 以前你可能用的是下面的DOCTYPE,不過你要知道現(xiàn)在已經(jīng)有更簡潔清晰的代碼取而代之了。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    "http://w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

理想的狀況是用HTML5 DOCTYPE,所有現(xiàn)代的瀏覽器都支持它,即使是不支持HTML5的瀏覽器,例如IE6,IE7,也會由此轉入標準模式。 參見來源

<!DOCTYPE html>

編寫合法且語義清晰的標記

用整潔、語義清晰的HTML編寫網(wǎng)站代碼是我們一直孜孜以求的。有時我們會發(fā)現(xiàn)前人配置頁面的方式限制了我們,或者有時我們編寫的是HTML格式的email模板。但永遠不要偏離HTML的規(guī)范,即使是為了解決特定瀏覽器兼容性的bug。

所有的標題應該從<h2>開始分層級創(chuàng)建,文字段落應該總是放在<p>標簽里,諸如此類。如果你編寫的HTML的語義清晰,產(chǎn)生的頁面會更整潔、簡練,而且易于被搜索引擎爬蟲解析。這是你能做到的最簡單的SEO修補方式。

來看看下面的段落,你覺得哪個更整潔?是這個?

<span class="sectionHeading">A Heading</span><br /> <br />Lorem ipsum dolor sit amet. ...<br /> <br />

還是這個?

<h2>A Heading</h2><p>    Lorem ipsum dolor sit amet. ...</p>

鼠標中鍵點擊的應變方式

現(xiàn)代web應用最令人郁悶的可用性缺陷之一是超鏈接功能的變種。一些看起來像是超鏈接的元素可能是通過Javascript映射的單擊功能,這就破壞了鼠標中鍵點擊(在新的tab中打開鏈接頁面)的功能。即使它們能在新的標簽頁打開,它們只帶有一個 # 的href又會把你帶回到同樣的頁面。

深刻詮釋了該問題的一個現(xiàn)代熱門網(wǎng)站的例子就是Twitter。在它的整個應用里,鼠標中鍵點擊用戶名或頭像會得到完全不同的結果。

<!-- 舊的方式,破壞網(wǎng)頁語義 --><a href="#"></a><!-- 如果鼠標點擊不能產(chǎn)生一個頁面,那就不是超鏈接 --><span class="link" role="link"></span>

另一個替代方案是使用 # 引導的路徑,它會把普通的url映射為 # 引導的鏈接,然后通過AJAX來獲取頁面片段。提供此功能的庫應該能夠在鼠標中鍵點擊的時候正常顯示頁面,或者在左鍵點擊時把該頁面內(nèi)容加載到指定的區(qū)域。不過這樣也要慎重行事,有很多人都認為 #鏈接正在破壞web應用。

用Microformats格式表示聯(lián)系人信息

Microformat是一種便于機器讀取聯(lián)系人信息的方式。hCard類(不是vCard)用來定義元素里包含的內(nèi)容類型。這些內(nèi)容會被瀏覽器提取并突出顯示。

<span class="tel">    <span class="type">home</span>:    <span class="value">+1.415.555.1212</span></span>

如果你曾經(jīng)瀏覽采用此格式的網(wǎng)頁,你會注意到類似skype的程序可以輕松檢測到網(wǎng)頁上的哪些數(shù)字是電話號碼。在iOS設備上的Safari瀏覽器也可以做到類似的事情。

有關Microformat的更多信息請參閱http://microformats.org/wiki/hcard

圖片需要設 'Alt' 文本

<img> 標簽需要 alt 文本,以便檢查并滿足可讀性的要求。 在 alt 屬性中的文本必須能夠說明圖片顯示的內(nèi)容或要達到的效果,除非該圖片不重要。

如果圖片只是一個列表中的著重號或者其他無關緊要的圖標,最好是給 alt 屬性一個空字符串,但還是留著它。這樣屏幕閱讀器會忽略它,而不是把"著重號"連讀20次。

<img src="dog.gif" alt="Fido and I at the park!" /><!-- 很好,描述清晰 --><img src="bullet.gif" alt="bullet" /><!-- 不好,顯得多余 --><img src="bullet.gif" alt="" /><!-- 好 -->

只對表格數(shù)據(jù)用table標簽

table標簽永遠只應該用在表格數(shù)據(jù)的展示上。唯一的例外是當編寫HTML格式的郵件時,這種情況下可能table是某些坑爹的郵件客戶端唯一支持的樣式了。

為了可讀性,表格頭永遠要使用 <th> 元素。同時切記要設置cellpadding, cellspacingborder 的值為 0 , 因為這些樣式由CSS來控制更容易確保一致性。

<table cellpadding="0" cellspacing="0" border="0">    <thead>        <tr>            <th>                Cell Header            </th>        </tr>    </thead>    <tbody>        <tr>            <td>                Cell Item            </td>        </tr>    </tbody></table>

使用 jQuery 和 jQuery UI Widgets

jQuery 和 jQuery UI 被做成盡可能在不同瀏覽器上表現(xiàn)出幾乎相同的外觀和功能。jQuery UI 被設計為符合 WAI WCAG 2.0 及 WAI ARIA, 因此采用該框架可以避免在你的站點上運行的插件或腳本的所有不確定性。


JavaScript

代碼留空和格式

任何關于代碼格式、留空和大括號位置的討論都會引起激烈辯論。對此,我想最簡單的規(guī)則就是,除非你愿意把整個代碼文件重新格式化,不然還是尊重并保持已有代碼文件的格式。這意味著如果你看到一個JS文件里的大括號沒有換行寫,那你的代碼也要繼續(xù)保持大括號不換行。如果你的代碼沒有和代碼文件里的其他部分保持一致,那么你的代碼就不應該通過代碼審查流程。

一致的代碼格式讓代碼更加易讀,同時也意味著代碼容易用查找/替換命令進行修改。謝天謝地,我們自己形成的編程習慣和jQuery正式推薦的方式非常相似。細微的差異也是有的,不過,那些是個人問題或者我們覺得沒法維護的一些東西。參閱jQuery核心樣式指南

字符間距

// 不好if(blah==="foo"){    foo("bar");}// 好 :)if (blah === "foo") {    foo("bar");}

大括號不換行

// 不好if (foo){    bar();}// 好 :)if (foo) {    bar();}

總是用大括號

// 不好if (foo)    bar();// 好 :)if (foo) {    bar();}

字符串處理

引用字符串永遠要用雙引號。 有些人非常喜歡用C語言風格的字符串(單引號),但這種習慣會導致腳本內(nèi)部的風格沖突。C語言風格的字符串處理要求空字符串和單字符包在單引號里,而短語和單詞必須包在雙引號內(nèi)。

注釋

往代碼里玩命加注釋的需求是由各種經(jīng)理、主管及其他很少接觸代碼的人們引領的。這種需求無非是雇員們考核指標中的一個勾選欄,花在這上面的時間基本沒有帶來什么回報。如果那些從善如流的開發(fā)者能遵循本文檔中提出的建議,他們的代碼會變得相當易于閱讀,一目了然,以至于再用注釋描述這些代碼會多余得令人尷尬。來看下面的例子。在這里,布爾變量被作為問題提出,而函數(shù)也有直觀的命名。

if (user.hasPermission) {    editPage();}

至少在這個場景中,注釋是完全沒有必要的。

注釋重要的情況

一個項目里,永遠會有某些部分難以查閱和理解。比如一個復雜的正則表達式,或者一個對角度進行計算或在度和弧度單位之間切換的數(shù)學函數(shù)。沒有上面的注釋,初級或中級的讀者將對腳本的含義毫無頭緒。

// 校驗美國電話號碼的正則表達式,號碼格式是 (XXX) XXX-XXXX (減號、空格和括號都是可選的,可以有也可以沒有)var phoneRegEx = /^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/;

總是使用 === 比較符

使用 == 比較符可以讓令人郁悶的bug消失于無形。它允許在 JavaScript花園 中有清楚解釋的弱類型。使用嚴格的 === 比較符不會執(zhí)行類型強制轉換,從而能夠嚴格地評估兩個對象之間的差別。再說一遍,更多詳細信息請參見 JavaScript花園。

var zeroAsAString = "0";if (zeroAsAString == 0) {    // 這樣也能判斷為true,呵呵...}if (zeroAsAString === 0) {    // 判斷為false}

例外

在和null進行比較的時候,允許使用 == 比較符,因為它會檢測null和undefined兩個屬性。如果你不完全理解這個原理,那我還是建議你用 === 比較符為好。

var foo = null;// foo 是 null, 但 bar 是 undefined ,因為它尚未被聲明if (foo == null && bar == null) {    // 上面的判斷還是成立的}

使用 .parseInt() 的時候,總是指定第二個 'radix' 參數(shù)

把字符串解析為整數(shù)的時候,有個好習慣是指定第二個基數(shù)參數(shù) -- 它會確定該字符串被轉換成幾進制。當字符串以 0 開頭的時候,缺省情況下會觸發(fā) 16 進制作為基數(shù)。大部分初級和中級用戶只會用到 10 這個基數(shù)。 感謝 Jo?o Moreno 記錄的這個 勘誤。

alert( parseInt("08") ); // alerts: 2alert( parseInt("08", 10) ); // alerts: 8

避免比較 true 和 false

直接比較 true 和 false 的值是沒有必要的。有時候也許明確一下有好處,但它還是額外的代碼。

if (foo === true) {    // 用了 === 倒是不錯,可這是多余的}if (foo) {    // 贊!}if (!bar) {    // 反過來也贊}

避免污染全局命名空間

過分依賴全局變量是我們組所有人 -- 特別是我自己 -- 特別有負罪感的一件事。關于為啥全局變量不好的討論是相當直接的:這增加了腳本和變量沖突的概率,而且源文件和命名空間本身都會充斥著數(shù)不清的命名模糊的變量。

Douglas Crockford 堅信一個Javascript應用的代碼質量可以用其中使用的全局變量數(shù)來評價,越少越好。由于并不是什么都可以定義成local的(不過要誠實,其實你現(xiàn)在考慮的那個是可以的,別偷懶),你需要想辦法整理你的變量以避免沖突,并把命名空間的膨脹減到最小。最簡單的方法就是采用單變量或者把用到這些全局變量的模塊盡可能減少。 Crockford提到YUI只用了一個全局變量,YAHOO。他在他的博文 "全局統(tǒng)治" 中討論了更多的細節(jié)問題。

考慮這種情況:對于小型web應用,全局變量通常用于保存應用級的設置,可以用你的項目名或者settings作為命名去定義一個對象,這樣總的來說會更好。

// 被污染的全局命名空間var settingA = true;var settingB = false;var settingC = "test";// 用 settings 作為對象命名var settings = {    settingA: true,    settingB: false,    settingC: "test"}

不過,如果我們可以通過避免使用全局變量來減少沖突概率,但是把命名空間標準化成一樣的,豈不是會增加各個應用之間產(chǎn)生沖突的概率么?呃,這個擔憂確實有道理。所以,建議你用自己特定的應用名作為全局變量的命名空間,或者用和jQuery采取的 $.noConflict() 模式相同的方法重新分配你的命名空間.

var myAppName = {    settings: {        settingA: true    }}//訪問全局變量myAppName.settings.settingA; // true

駝峰法變量命名

JavaScript變量的駝峰法命名在大部分編程環(huán)境中都是作為標準的。有讀者在評論中提出了唯一的例外,就是要用大寫字母加下劃線來指代常量。

var X_Position = obj.scrollLeft;var xPosition = obj.scrollLeft; // 更好,更簡潔SCENE_GRAVITY = 1; // 常量

循環(huán)的性能 - 緩存數(shù)組長度

循環(huán)估計是Javascript性能調優(yōu)最重要的部分了。在一個循環(huán)內(nèi)部節(jié)省個一兩毫秒的,說不定總體就省出好幾秒來了。這里有一招就是把數(shù)組的長度緩存,這樣在循環(huán)里就無需每次迭代的時候都計算一遍了。

var toLoop = new Array(1000);for (var i = 0; i < toLoop.length; i++) {    // 敗家玩意 - 長度會反復算 1000 次你知道不?}for (var i = 0, len = toLoop.length; i < len; i++) {    // 會過日子 - 長度只計算一次,然后緩存了}

例外

如果你對一個數(shù)組做循環(huán)來查找并刪除某個元素,這就會改變數(shù)組長度。任何時候你只要會在循環(huán)內(nèi)部增加或刪除元素來改變數(shù)組的長度,你就給自己帶來了麻煩。這種情況下,你要么每次改變后重新設置數(shù)組長度,要么就別緩存它了。

循環(huán)的性能 - 使用 'break;' 和 'continue;'

跳過和跳出循環(huán)的能力對于避免開銷很大的循環(huán)周期是非常有用的。

如果你是在循環(huán)內(nèi)部查找,查找成功以后你會做什么?比如1000個元素的循環(huán)執(zhí)行到一半,你就找到了你要的東西。你不管三七二十一,即使知道后面的if語句不會再有符合的機會,還是讓循環(huán)繼續(xù)把剩下的500個元素迭代完么?不!你應該跳出循環(huán),必須的!

var bigArray = new Array(1000);for (var i = 0, len = bigArray.length; i < len; i++) {    if (i === 500) {        break;    }    console.log(i); // 這樣只會輸出 0 - 499}

另一個問題是跳過某個特定的迭代,然后繼續(xù)循環(huán)。雖然說類似于奇偶數(shù)這樣的條件可以通過把 i++ 替換成 i + 2 的辦法來管理,有些條件還是需要具體檢測,然后觸發(fā)跳過操作。任何能夠避免執(zhí)行完整的迭代過程的東西都是很有用的。

var bigArray = new Array(1000);for (var i = 0, len = bigArray.length; i < len; i++) {    if (condition) {        continue;    }    doCostlyStuff();}

函數(shù)調用不要傳輸太多的參數(shù)

對于可讀性而不是其他因素來說,下面這種方式真是糟透了:

function greet(name, language, age, gender, hairColour, eyeColour) {    alert(name);}

下面的例子預先構建了一個對象作為參數(shù),或者把內(nèi)聯(lián)對象傳遞過去,這樣就好多了。

function greet(user) {    alert(user.name);}greet({    name: "Bob",    gender: "male"});

把 'this' 映射為 'self'

在編寫面向對象(OO)Javascript代碼的時候, 必須了解 this 的作用范圍. 不管你用來構建偽類的設計模式是什么,對 this 的引用是指向一個實例的最簡單辦法。當你開始把jQuery的helper方法和你的偽類集成的時候,你就會注意到 this 的作用范圍變化。

Bob.findFriend("Barry");Person.prototype.findFriend = function(toFind) {    // this = Bob    $(this.friends).each(function() {        // this = Bob.friends[i]        if (this.name === toFind) {            // this = Barry            return this;        }    });}

在上面的例子里, this 經(jīng)歷了從對 Bob 的引用,變成對他的朋友 Barry 的引用的過程。 了解 this 的取值在一段時間發(fā)生的變化是很重要的。在原型函數(shù)內(nèi)部, this 指向所在偽類的當前實例(這里是 Bob )。而一旦我們進入 $.each() 循環(huán), this 就會重新映射為被解析數(shù)組的第 i 個元素。

解決辦法是把 this 的值重新映射為 self 或者 _self。雖然 self (不帶下劃線)并不是 保留字, 但它 確實是 window 對象的一個屬性。雖然我上面用到 self 的例子是從jQuery源代碼中挑的,但他們也認識到了這個錯誤,正打算 修正目前的狀況 ,也就是改用 _self。我個人還是喜歡用 self ,不為別的,就因為它的簡潔 -- 不過它可能會冒出一些非常令人困惑的bug??傊?,用 self 有風險,使用需謹慎。

在下面的例子中,我會更好地利用在 $.each() helper 中提供的參數(shù),同時重新映射 this 的值。

Bob.findFriend("Barry");Person.prototype.findFriend = function(toFind) {    // 就這一次用到了 "this"    var _self = this;    $(_self.friends).each(function(i,item) {        if (item.name === toFind) {            return item;        }    });}

我能用 Boolean 嗎?

布爾變量必須能夠很容易通過命名來識別??梢杂妙愃朴?is, can 或者 has 的前綴來形成一個問句。

isEditing = true;obj.canEdit = true;user.hasPermission = true;  

盡量減少重新繪制和重新布局

重新繪制和重新布局與重新渲染DOM的過程關聯(lián),這個過程會在特定屬性或元素被改變時發(fā)生。重新繪制是在某個元素的外觀被改變但沒有對布局進行調整的情況下觸發(fā)的。Nicole Sullivan 在一篇全面的 博文中把這些改變描述為諸如是否可見或背景色變化之類的樣式改變。重新布局則是開銷更大的操作,由調整頁面布局的一些改變引發(fā)。例如增加或刪除元素,改變某個元素的寬度或高度,甚至是改變?yōu)g覽器窗口的大小。最糟糕的情況是重新布局導致先輩、兄弟和孩子節(jié)點元素也需要重新布局的多米諾骨牌效應。

毫無疑問,重新繪制和重新布局應該盡量避免,但是如何做到呢?

重新布局的例子

其實也不是說下面的代碼就很糟糕啦。不過我們先假定數(shù)組 arr 有10個元素

var myList = document.getElementById("myList");for (var i = 0, len = arr.length; i < len; i++) {    myList.innerHTML += "<li>" + arr[i].title + "</li>"; //重新布局 -- 增加到元素}

在上面的 for 循環(huán)里,每次迭代會觸發(fā)一次重新布局。10次迭代就是10次重新布局。

現(xiàn)在考慮下面的代碼:

var constructedHTML = "";for (var i = 0, len = arr.length; i < len; i++) {    constructedHTML += "<li>" + arr[i].title + "</li>"; //沒有重新布局 - 增加到字符串}document.getElementById("myList").innerHTML = constructedHTML; //在這里重新布局

在這個場景里,需要增加的元素是在一個字符串里構建的。循環(huán)里邊沒有產(chǎn)生任何重新布局,因為DOM并沒有變化。只有當數(shù)組被完全循環(huán)完畢,構建的字符串被應用到某個對象的 innerHTML ,這才產(chǎn)生函數(shù)里唯一的一次重新布局。

有無數(shù)種重新布局和重新繪制是可以避免的,希望你幸運地了解了那些訣竅。這方面的閱讀材料汗牛充棟,不過大部分的材料都會引用到 Nicole Sullivan的這篇 博文 ,這是一個完美的起點。除了這里的經(jīng)驗,在涉及到"web 3.0"和HTML5時代的多種技術術語的時候,還有其他重要的經(jīng)驗教訓值得汲取。上面的分析直接適用于寫jQuery代碼。在搗騰 canvas 的時候這些原則也很重要,另外盡量保持幀頻在30-60的范圍內(nèi)。

不要用微秒來產(chǎn)生唯一的ID

自打web開發(fā)早期開始,就流行一種產(chǎn)生唯一ID的方法。具體做法是把從1970年1月1日開始計算的微秒數(shù)加到你的靜態(tài)ID后面,如下所示:

var myID = "static" + new Date().getTime();

這本來是相當萬無一失的方法,因為即便兩段這樣的代碼連續(xù)執(zhí)行,在它們執(zhí)行的間隙也會有幾毫秒??墒乾F(xiàn)在新的瀏覽器帶著新的Javascript引擎,伴隨著一直在提升的主頻。到現(xiàn)在,上面的代碼產(chǎn)生相同的毫秒數(shù)的可能性會比產(chǎn)生間隙的可能性更大。

這會導致傳統(tǒng)方法難以debug的bug。因為你的DOM是在運行中創(chuàng)建的,對頁面源代碼進行傳統(tǒng)的測試無法確定多個重復ID的錯誤。Javascript和jQuery的錯誤處理機制會把第一個匹配的作為ID并忽略其他的重復ID。所以它甚至都不會拋出JS錯誤!

這樣不行,唯一真正的方法是逐行設斷點和log,但是如果斷點的位置不對,你的毫秒數(shù)又會沖突了!

好消息是有很多產(chǎn)生唯一ID的替代方法。學究氣一點的說法是,計算機的隨機數(shù)函數(shù)其實并不是真正隨機的,因為它還是來源于系統(tǒng)時間,雖然這一點值得注意,但是隨機數(shù)沖突的可能性是微乎其微的。

var myID = "static" + Math.round(Math.random() * 10000);

我個人更偏愛人工產(chǎn)生GUID方法。從技術角度說,GUID是根據(jù)你的硬件創(chuàng)建的,不過下面的Javascript函數(shù)做得相當棒。這是我從 stack overflow 的一個帖子 里偷來的,相當順手的一個函數(shù)。

function S4() {   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);}function guid() {   return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());}

var myID = "static" + guid();

檢測特性,而不是檢測瀏覽器類型

用戶的瀏覽器是否支持地理信息?用戶的瀏覽器是否支持web works?HTML5 視頻?HTML5 音頻?答案曾經(jīng)是這樣的:

if ($.browser.msie) {    // 哦,是IE啊,那肯定不支持}

但是世界在快速變化。最新版的IE幾乎能算是現(xiàn)代瀏覽器了,但它依舊給前端開發(fā)帶來痛苦。更早版本的IE基本上和它之前的版本一樣爛,這就讓偷懶的Javascript程序員習慣于檢測 if (ie) 然后執(zhí)行一些微軟專用的破語法。現(xiàn)在IE9已經(jīng)廢棄了這些專用函數(shù),那些原來的 if (ie) 老古董就反而會壞事了。

那么,如果能檢測每個特性而不用檢測(既不可靠又能偽裝的)user-agent,你覺得咋樣?

如果你的回答是 "那相當靠譜", 那你就說對了。

Modernizr 吧,這是行業(yè)夢幻級大師Paul Irish參與開發(fā)的一個Javascript庫。該庫集廣泛應用、輕量級和海量文檔三大優(yōu)勢于一身,實施無需動腦,實為居家旅行、殺人滅口必備。它會產(chǎn)生一個 Modernizr 對象,其中包含了它所有檢測測試的結果,這樣檢測某個特性的支持與否就和下面的例子一樣簡單:

// 檢測瀏覽器是否支持canvas的老辦法if (!!document.createElement('canvas').getContext) { ... }// 用 Modernizr 檢測if (Modernizr.canvas) { ... }

使用可讀的毫秒數(shù)

毫秒數(shù)的一種方便的寫法是寫成可讀的。對于初學者這很棒,但是大部分情況下其實只是一個噱頭。

// 這是3秒,30秒還是300秒???var timeout = 30000;// 增加了額外的計算開銷,但是讀和修改會更容易var timeout = 30 * 1000;

關于jQuery代碼

像瘋狗一樣串接

jQuery最好的特性之一就是它的函數(shù)串接。你可能已經(jīng)用過一點,也許把一些簡單的調用一個接一個串起來...但是你是否曾經(jīng)像頭瘋狗一樣在DOM里上躥下跳地遍歷呢?還是花點時間來熟悉一下 .end() 函數(shù)。等你從起始選擇器開始在DOM里上躥下跳的時候,這個函數(shù)會很關鍵。

$(".quote")    .hide()    .find("a").text("Click here").bind("click",doStuff).end()    .parent().removeClass().addClass("testimonial").draggable().end()    .fadeIn("slow");

上例中,每次我們完成對某個DOM對象的操作,要反向遍歷DOM返回我們引用的原始對象的時候,就需要使用 .end() 函數(shù)。然后我們就順藤摸瓜扎回原來DOM里的位置了。

使用 data-* 屬性

你們當中那些已經(jīng)寫了很長時間Javascript(原生的,不是jQuery)代碼的同學,很可能都熟悉各種屬性吧。你們想辦法設置它們,獲取它們,或者濫用 reltitle ...

別說HTML5 或者 jQuery 沒幫上忙哦。新的描述中允許在HTML元素中使用 data- 前綴來指明包含數(shù)據(jù)的屬性,jQuery會把指定的字符串轉換成正確的Javascript數(shù)據(jù)類型,這活干的非常漂亮。我們來創(chuàng)建一個帶有某些數(shù)據(jù)屬性的 DIV 。

<div id="test" data-is-bool="true" data-some-number="123"></div>

現(xiàn)在,即使我們的值被包裝在引號里面,它們也不會被當做字符串處理:

typeof $("#test").data("isBool"); // booleantypeof $("#test").data("someNumber"); // number

特殊的大小寫

要注意,要讓這些代碼片段正常工作,(HTML里的屬性定義)必須使用小寫字母,這很重要。不過如果你是一位很強的前端開發(fā)者,你還是會想用駝峰法來命名你的數(shù)據(jù)變量。正如在Javascript里很多地方出現(xiàn)的,前置的連接符意味著下一個字母會適用于駝峰法大寫。不過,下面的例子里在HTML屬性定義中使用駝峰法是 不行的 ,會讓上面的Javascript代碼返回 undefined。

不好使 :(

<div id="test" data-isBool="true" data-someNumber="123"></div>

好使 :)

<div id="test" data-is-bool="true" data-some-number="123"></div>

'.stop()' 停止協(xié)作和監(jiān)聽

把jQuery動畫效果和鼠標事件綁定是基于web的現(xiàn)代用戶交互方式中的關鍵部分,可是這方面即便某些最有名的網(wǎng)站也做得很蹩腳。這篇文章 提供了一個實現(xiàn)動畫的直接例子并且演示了這些動畫放在一起在視覺上會產(chǎn)生多么不和諧的效果。好在這個問題可以利用一個函數(shù)前綴或在 $.animate 調用中加入一個參數(shù)來輕松解決。

在使用 $.animate 的時候, 可以在參數(shù)中加入 queue: false 來避免串接。諸如 $.fadeIn$.slideDown 這樣的動畫快捷方式不接受 queue 設置,你必須用 $.stop 這個方法預先停止這些動畫.。在特定的場景下,需要某個動畫直接停下,或跳轉到變換的最終狀態(tài)。推薦你先熟悉有關 clearQueuejumpToEnd 這兩個參數(shù)的相關 文檔 ,因為老天在上,我沒有其他辦法幫你。

$("selector").stop(true,true).fadeOut();$("selector").animate({    property: value}, {    duration: 1000,    queue: false}

優(yōu)化你的選擇器

jQuery 很高冷。它幾乎無所不能,不過它目前還沒法給你沖咖啡,我聽說在2.0版的路線圖里才有這個特性。你需要當心的一件事是別濫用它的 sizzleJS 選擇器引擎的能力。想避免這種問題可以有兩個策略:緩存選擇器結果 以及 使用高效率的選擇器。

緩存選擇器結果

是每次你要修改一點東西的時候都先進行開銷巨大的DOM查詢,還是保存一份元素的索引?選擇一目了然。

// before$(".quote a").bind("click", doStuff); // DOM查詢// now$(".quote a").addClass("quoteLink"); // DOM查詢?。?/ later$(".quote a").fadeIn("slow"); // 又一次DOM查詢?。。?/pre>

忽略串接,這樣做更好:

// beforevar $quoteLinks = $(".quote a");  // 只需一次DOM查詢$quoteLinks.bind("click", doStuff);// now$quoteLinks.addClass("quoteLink");// later$quoteLinks.fadeIn("slow");

使用高效率的選擇器

好了,jQuery/sizzleJS 可以輕松使用CSS3選擇器,但是真正的開銷是什么? 在這種場景下瀏覽器有可能會使用 document.querySelector(), 但是它也有可能分拆你的選擇器字符串,然后手工去查詢DOM。

// ID搜索是最快的查詢方式,然后它獲取孩子節(jié)點的列表,匹配其中class為'quotes'的元素$("#quoteList").children(".quotes");// 只在預先確定的bar元素下查找'foo'class$(".foo",bar); 

'for' 循環(huán)總是比 'each()' 循環(huán)快

不管未來幾年在瀏覽器開發(fā)領域會發(fā)生什么,本地的 for 循環(huán)永遠會比jQuery的 $.each() 循環(huán)快。當你思考jQuery到底是什么(把本地JS函數(shù)包裝起來的一個庫)這種高大上問題的時候,你就會開始認識到本地原生Javascript代碼永遠會更快。用庫還是用原生,這是一個運行速度和編程速度之間的權衡。

很重要的一點是,對那些可能每秒調用數(shù)百次的性能關鍵的函數(shù),總是要使用 for 循環(huán)。例如:

  • 鼠標移動
  • 時間間隔
  • 循環(huán)內(nèi)部的循環(huán)

CSS

理解盒子模型是關鍵

"盒子模型"對于理解瀏覽器如何渲染頁面是關鍵性決定性的因素。對其復雜性的全面理解有助于奇跡般地簡化你的工作。盒子模型描述了對HTML元素的物理維度進行計算的方式。如果一個塊元素具有固定寬度,比如說100px,那么應該如何確定它的 padding, border 和 margin 呢?

很多網(wǎng)站都有深入的描述,但咱們簡單點說:在遵循標準的瀏覽器中,border和padding是被放在指定寬度之外的。最好是用圖形來解釋。比如下列代碼:

.foo {    width: 150px;    height: 150px;    padding: 25px;    border: 25px solid;    margin: 20px;}

你可能估計的情況(Quirks 模式)

padding 和 border 都是往里算的,結果保持高度和寬度都是150px。

你看到的情況(遵循標準模式)

可是,實際上出來的寬度和高度都是250px。 也就是150px + (2 * 25) + (2 * 25)。

如果你覺得這個結果很奇怪,那你不是一個人(呃,你是人,只是說還有其他人也會這么想)。 現(xiàn)在手頭有個修復辦法,需要引入一個CSS屬性叫 box-sizing,這個屬性對于 IE8 及以上版本 都適用。它允許你選擇計算元素維度的確切方式,這樣就能救你于危難之中。具體支持的參數(shù)因瀏覽器而異,另外需要用到瀏覽器廠商的前綴,具體細節(jié)請參閱 caniuse.com 。

/* 舊方法 (178 + 20 + 2 = 200) */.foo {    width: 178px;    padding: 10px;    border: 1px;}/* 更好的方法 */.foo {    width: 200px;    padding: 10px;    border: 1px;        -webkit-box-sizing: border-box;        -moz-box-sizing: border-box;        box-sizing: border-box;}

雖然說你也總是可以對寬度進行心算,在各個像素數(shù)中減來減去(就像第一個方法做的那樣),但在涉及到不同的寬度單位時(比如百分比或者EM),就沒人能搞清楚到底該怎么做了。目前,除了把元素包在父元素中,以確保寬度和 padding/margin/borders 可以全部分開之外,也沒有別的解決辦法。

知道什么時候用float,什么時候用position

用table進行布局的時代過去了?,F(xiàn)在要承認我們可以集中精力去理解float和position的工作原理。這里需要掌握一套特別的思維模型,我相信這件事最好是通過動手練習來進行。

用float從DOM中提取元素并強制它們靠到左邊或右邊,那是相當靠譜。它們已成為前端開發(fā)的后table布局時代的萬金油,這可能是因為以前瀏覽器對于 display: inlineinline-block 的支持不力,還有對position的支持中冒出的 z-index bug。可現(xiàn)在就真的沒有借口了。 inline-block 已經(jīng)支持得很好了,簡單的一點修正就能讓它在 IE7 里應用。

謝天謝地,以前那些阻撓用CSS對元素進行絕對定位的爭論都消亡了。理論上,定位屬性可以讓你在頁面上以X和Y坐標放置元素,這種方式簡單直接,F(xiàn)lash開發(fā)者們都應該很熟悉。

理解 Position

用CSS定位元素的時候,理解一個事實非常重要:定位的位置總是相對于離它最近的有定位屬性的父元素而言的。人們剛開始用CSS的時候會有一個常見的誤解,認為 position: absolute; 是相對頁面的root元素定位的。 我覺得這種誤解來源于某些情況下,元素沒有任何父元素具備position樣式 -- 在這種情況下,他們的結論是對的。這樣向上遍歷DOM樹沒有找到任何有定位樣式的元素,就會定位到頁面的根元素上。

那么,如果 position: absolute; 是把元素從他們所在的流中抽取出來,那你如何相對一個元素的父元素對它進行定位呢? 方法很直接。父元素需要定義 position: relative; 樣式,然后所有的孩子元素就會按上、右、下、左的順序依次擺放。利用這個知識,你會如何實現(xiàn)下面很直觀的布局呢?

使用 float,你會需要把這些元素包在一個父元素中, 然后把.one float靠左,然后改動 .two.threefloatmargin 。最后你應該寫出類似下面的東西:

.parent {    /* ghetto clearfix */    width: 310px;    overflow: auto;}.one {    width: 200px;    height: 210px;    float: left;}.two {    width: 100px;    height: 100px;    float: right;    margin-bottom: 10px;}.three {    width: 100px;    height: 100px;    float: right;}

正如我們前面所說,使用 position 讓我們可以用很明確的方式,按照 X 和 Y 坐標把元素顯示在屏幕上。 上面用float的方式會把頁面上的長文字隔開,下面的方法則可以確保所有元素處于正常位置,無論頁面上有什么內(nèi)容。

.parent {    position: relative;    width: 310px;    height: 210px;}.one, .two, .three {    position: absolute;}.one {    top: 0;    left: 0;    width: 200px;    height: 210px;}.two {    top: 0;    right: 0;    width: 100px;    height: 100px;}.three {    bottom: 0;    right: 0;    width: 100px;    height: 100px;}

如前文所述,有些 z-index 的問題需要考慮。雖然上面的例子可能顯得有點過分,不過一旦你開始思考定位,它會打開一個各種可能性的新世界.

留空

如果我們在單行和多行CSS參數(shù)的格式之間變來變?nèi)?,CSS里的留空也會不一樣。我不打算對這個說太細。

合適的空白

/* 不好 */.selector {display:none;background:#ff0000;color:#000000;}/* 好 -- 單行 */.selector { display: none; background: #ff0000; color: #000000; }/* 好 -- 多行 */.selector {    display: none;    background: #ff0000;    color: #000000;}

大括號不換行

.selector {    display: none;    background: #ff0000;    color: #000000;}

子元素縮進

這個用不用就見仁見智了,我個人只會在單行定義的CSS文檔中用這種格式。

.selector { display: none; background: #ff0000; color: #000000; }    .selector a { text-decoration: none; }    .selector span { font-weight: bold; }

組合并縮進瀏覽器廠商前綴屬性

.selector {    background: #FFF; border: 1px solid #000; color: #EAEAEA;        -webkit-border-radius: 3px;        -moz-border-radius: 3px;        border-radius: 3px;}

CSS 速記格式

屬性分組

把屬性分組到一起是大大減少CSS文件大小的最有效方法。這里很重要的一點是要理解屬性是如何排序的(順時針 -- 上,右,下,左),以及如何進一步縮短它們(上和下,左和右)。

/* 逐個定義,太長了 */padding-top: 1px;padding-right: 2px;padding-bottom: 1px;padding-left: 2px;/* 上,右,下,左,好很多 */padding: 1px 2px 1px 2px;/* 上和下,左和右,最優(yōu) */padding: 1px 2px;

從 0px 到英雄

給值為 0 的屬性分配一個單位類型是多余的。一個元素是距離左邊 0px 還是 0 elephants 根本不重要,只要知道它是貼著左邊就行了。

/* 不好 */padding: 0px 10px;

/* 好 */padding: 0 10px;

注釋塊

對于在一個樣式表里維護多個樣式區(qū)域的任務,給大段CSS加上注釋是很好的辦法。顯然這和單行CSS風格配合使用效果更佳,不過這個效果在多行CSS風格里也不是完全沒用。注釋里用破折號、等號還是下劃線起強調作用就見仁見智了,不過下面是我喜歡的方式:

/* === HORIZONTAL NAV === */#horizNav { width: 100%; display: block; }#horizNav li { display: block; float: left; position: relative; }#horizNav li a { display: block; height: 30px; text-decoration: none; }#horizNav li ul { display: none; position: absolute; top: 30; left: 0; }/* === HOME PAGE - CAROUSEL === */#carousel { width: 960px; height: 150px; position: relative; }#carousel img { display: none; }#carousel .buttons { position: absolute; right: 10px; bottom: 10px; }

清除浮動

清除一個 <div> 過去意味著額外的DOM,因為這會涉及到增加一個額外的清除元素。更好的辦法是給父元素設置明確的寬度('auto'并不是在所有瀏覽器和場景中有效)以及把overflow屬性設為'auto'或者'hidden'。'hidden'顯然兼容性更好,但在某些兼容IE的版本里'auto'的效果好一些。

HTML:

<div class="parentElement">    <div class="childElement">        I'm floated left!    </div>    I'm normal text that wraps around the float</div>

CSS:

.parentElement {    width: 100%;    overflow: hidden;}.childElement {    float: left;}

有本項目的貢獻者提醒我注意最新的clearfix。 micro clear-fix被認為相當穩(wěn)定且跨瀏覽器兼容,足以列入最新的HTML5 boilerplate發(fā)布了。 我 強烈 建議你去看看。雖然我不是瀏覽器特定CSS和 :after 這種偽元素的狂熱粉絲,不過這個micro clearfix的確更健壯。它還能避免頂層margin縮回的問題。

垂直和水平居中

水平居中元素實際上不是什么高精尖的科技,我敢肯定你們大部分人都熟悉下面的代碼片段:

.class {    width: 960px;    margin: 0 auto;}

前端開發(fā)者們使用這種代碼很長時間了,也沒搞明白為什么這種方式對垂直居中不起作用。從我的理解說,很重要的一點是記住父元素一般會有個 height: auto; 樣式, 也沒有垂直居中元素所需的100%高度。而應用 position: absolute; 能有效地把元素轉移到定位模式,然后被設為auto的margin會自動幫助它調整位置,達到居中效果。

.exactMiddle {    width: 100px;    height: 100px;    position: absolute;    top: 0;    right: 0;    bottom: 0;    left: 0;    margin: auto;}

這種方法的不足之處包括在 IE6 和 IE7 中缺乏支持,以及當瀏覽器被縮小到比居中對象還小時不出現(xiàn)滾動條。 在 這個網(wǎng)頁 里列出了更多的方法(現(xiàn)在這個是第4個),不過現(xiàn)在這個目前是最優(yōu)方法。

在一個元素里垂直居中文字也是很直接的。如果文字是單行的,例如一個水平導航元素,你可以設置 line-height 為該元素的物理高度。

#horizNav li {    height: 32px;    line-height: 32px;}

檢測特性,而不是檢測瀏覽器類型

在前面關于Javascript特性檢測的討論中,檢測到瀏覽器是 任何版本 的 IE 然后就運用某些屬性的做法越來越成問題了。鐵人 Paul Irish 引領了使用 IE 版本檢測 方法來解決這些問題的大潮,但是 Modernizr 從那時起拯救了我們。Modernizr 在 root <html> 元素里放入一些class,描述某些特性是否得到支持. 然后前沿的樣式就可以很容易從這些class級聯(lián)出來或者刪除掉。

.my_elem {   -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.25);   -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.25);   box-shadow: 0 1px 2px rgba(0,0,0,0.25);}/* 如果 box shadow 不支持, 就應用 borders 屬性 */.no-boxshadow .my_elem {   border: 1px solid #666;   border-bottom-width: 2px;}

!important 不要亂用

依賴于 !important 標簽是個危險的現(xiàn)象。非用它不可的情況屈指可數(shù),而且是特殊情況。這些情況大抵是需要覆蓋另外一套樣式表,而你沒法或者沒權限編輯它。另一個場景是對元素的樣式硬編碼以防止Javascript在線產(chǎn)生的樣式有更大優(yōu)先級。而實際情況是 !important 往往被用做偷懶的快捷方式,讓某個樣式優(yōu)先于其他的樣式,這樣做將來會產(chǎn)生很多問題。

!important 標簽的大部分使用是可以避免的,只要更好地理解CSS選擇器優(yōu)先級以及如何更準確地定位元素。選擇器越具體,被接受為適用樣式的可能性就越大。下面來自 vanseodesign 的例子展示了具體化起作用的情況。

p { font-size: 12px; }p.bio { font-size: 14px; }

關于樣式優(yōu)先級, 他們的文章 在解釋繼承性方面比我能寫出來的文章都好,所以請給它點個贊吧。

進取性向下兼容

值得注意的是,這段是我的個人觀點,只適用于特定情況。在依賴老版本瀏覽器的大型商業(yè)項目或企業(yè)級解決方案中,進取性向下兼容的立場將不容易被接受。

進取性向下兼容的意思是如果某個特定的(老版本)瀏覽器無法渲染某個特定效果,則應直接忽略它。CSS3 按鈕就是一個好例子。諸如 border-radius, box-shadowtext-shadowgradients 這些效果會在先進的瀏覽器里顯示出來。對于版本稍微老一點的瀏覽器,可以用一個 .PNG 圖片作為無傷大雅的補救辦法,而所有解決辦法中最優(yōu)雅的應該是針對IE6提供一個PNG-Fix,或者用filter 參數(shù)來代替 gradients 和 shadows等屬性。不過,在這種情況下,進取性向下兼容方式會讓你忽略老版本瀏覽器,而在其中展示一個平面的還過得去的對象。

簡單地說,進取性向下兼容說白了就是:如果你的瀏覽器渲染不了漸變色或盒子陰影,那是你運氣不好。

雖然這不是對所有情況都理想,這種方法能確保項目按時交付,且核心產(chǎn)品是可用的,而不需依賴于對瀏覽器的破解辦法。


CSS3及HTML5

這個話題我想我已經(jīng)說的夠多了。用 Modernizr 來檢測特定的 HTML5 和 CSS3 特性是否可用。

@font-face的使用和濫用

在你考慮嵌入一套定制的字體之前,很重要的一點是你要查看 EULA 并檢查是否允許web嵌入。 字體庫廠商自然是不愿意讓設計師和開發(fā)者有能力把字體庫文件直接存放在服務器上,然后被熟練的終端用戶拷貝走。某些廠商也禁止嵌入特定的文件類型,例如 .TTF.OTF。

如果,經(jīng)過慎重考慮,你相信想要的字體是可嵌入的,那就去看一下Font Squirrel的 @font-face 生成器。它利用了 Fontspring的 防彈 @font-face 結構 并能自動生成所有需要的文件格式。

向下兼容

謝天謝地,瀏覽器對于它不支持的HTML5 和 CSS3 特性的處理已經(jīng)達到了優(yōu)雅的本色。加到 <input /> 標簽的新類型例如 "email", "search" 等等在瀏覽器本地不支持的情況下一般會向下兼容為正常的 <input type="text" />。 類似的,不支持的CSS3 特性就不會出現(xiàn),由高度和寬度媒體查詢控制的響應式布局也不會被應用。

精巧的CSS3效果應該被應用為對使用現(xiàn)代瀏覽器的用戶的一種獎勵。

在下面的"資源"小節(jié)里包括了一些有助于讓HTML5和CSS3功能在一批老版本瀏覽器中保持正常的庫。


資源

下列的資源對于代碼標準化和現(xiàn)代web頁面的互動是很重要的。它們確保了CSS3 和 HTML5 特性在以前缺乏支持能力的一批瀏覽器中能夠使用。

  • jQueryJavaScript助手庫
  • jQuery UI為用戶交互/界面做著jQuery為JavaScript做的同樣的事
  • Modernizr檢測特性,不要檢測瀏覽器!
  • RespondJS為老版本瀏覽器帶來響應式布局
  • @font-face Generator全面的字體內(nèi)嵌
  • RaphaelJS簡單易用的跨瀏覽器向量圖
  • HTML5 Boilerplate對于任何項目都是一個好的起點。不過即使是它的"精簡"版也還是有點臃腫
  • Twitter Bootstrap讓你能給簡單的web應用迅速產(chǎn)生原型和樣式

本文由 Tait Brown 編寫 (@taitems),此中文版由 coderLMN 翻譯。 

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
2014年最新前端開發(fā)面試題(面霸題庫)
HTML+CSS+JS詳解 | w3c筆記
JavaScript前端開發(fā)案例教程-第11章 jQuery
前端開發(fā)面試題 | 菜鳥教程
前端工作面試問題
我的前端學習歷程
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服