欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于編寫(xiě)性能高效的javascript事件的技術(shù)

 更新時(shí)間:2014年11月28日 16:52:02   投稿:mdxy-dxy  
這篇文章主要介紹了關(guān)于編寫(xiě)性能高效的javascript事件的技術(shù) ,需要的朋友可以參考下

如何能做出高效的web前端程序是我每次做前端開(kāi)發(fā)都會(huì)不自覺(jué)去考慮的問(wèn)題。幾年前雅虎里牛逼的前端工程師們出了一本關(guān)于提升web前端性能的書(shū)籍,轟動(dòng)了整個(gè)web開(kāi)發(fā)技術(shù)界,讓神秘的web前端優(yōu)化問(wèn)題成為了大街的白菜,web前端優(yōu)化變成了菜鳥(niǎo)和大牛都能回答的簡(jiǎn)單問(wèn)題,當(dāng)整個(gè)業(yè)界都知道了驚天秘密的答案,那么現(xiàn)有的優(yōu)化技術(shù)已經(jīng)不能對(duì)你開(kāi)發(fā)的網(wǎng)站產(chǎn)生的質(zhì)的飛越,為了讓我們開(kāi)發(fā)的網(wǎng)站性能比別人的網(wǎng)站更加優(yōu)秀,我們需要更加深入的獨(dú)立思考,儲(chǔ)備更加優(yōu)秀的技能。

Javascript里的事件系統(tǒng)是我想到的第一個(gè)突破點(diǎn)。為什么會(huì)是javascript的事件系統(tǒng)呢?我們都知道web前端包含三個(gè)技術(shù):html、css和javascript,html和css如何結(jié)合真是一目了然:style、class、id以及html標(biāo)簽,這個(gè)沒(méi)啥好講的,但是javascript是如何切入到html和css中間,讓三者融合呢?最后我發(fā)現(xiàn)這個(gè)切入點(diǎn)就是javascript的事件系統(tǒng),不管我們寫(xiě)多長(zhǎng)多復(fù)雜的javascript代碼,最終都是通過(guò)事件系統(tǒng)體現(xiàn)在html和css上,因此我就在想既然事件系統(tǒng)是三者融合的切入點(diǎn),那么一個(gè)頁(yè)面里,特別是當(dāng)今越來(lái)越復(fù)雜的網(wǎng)頁(yè)里必然會(huì)有大量事件操作,沒(méi)有這些事件我們精心編寫(xiě)的javascript代碼只有刀槍入庫(kù),英雄無(wú)用武之地了。既然頁(yè)面會(huì)存在大量事件函數(shù),那么我們按習(xí)慣寫(xiě)事件函數(shù),會(huì)存在影響效率的問(wèn)題嗎?我研究下來(lái)的答案是真有效率問(wèn)題,而且還是嚴(yán)重的效率問(wèn)題。

為了說(shuō)清楚我的答案,我要先詳細(xì)講解下javascript的事件系統(tǒng)。

事件系統(tǒng)是javascript和html以及css融合的切入點(diǎn),這個(gè)切人點(diǎn)好比java里的main函數(shù),一切神奇都是由這里開(kāi)始,那么瀏覽器是如何完成這種切入呢?我研究下來(lái)一共有3種方式,它們分別是:

方式一:html事件處理

  html事件處理就是將事件函數(shù)直接寫(xiě)在html標(biāo)簽里,因?yàn)檫@種寫(xiě)法和html標(biāo)簽緊耦合,所以稱為html事件處理。例如下面代碼:

復(fù)制代碼 代碼如下:

<input type="button" id="btn" name="btn" onclick="alert('Click Me!')"/>  

  如果click事件函數(shù)復(fù)雜了,這么寫(xiě)代碼肯定會(huì)帶來(lái)不便,因此我們常常把函數(shù)寫(xiě)在外部,onclick直接調(diào)用函數(shù)名,例如:

復(fù)制代碼 代碼如下:

<input type="button" id="btn" name="btn" onclick="btnClk()"/>
function btnClk(){
         alert("click me!");  
}

上面這個(gè)寫(xiě)法是一種很美的寫(xiě)法,所以時(shí)下還是很多人會(huì)不自覺(jué)的使用它,但是也許很多人不知道,后一種寫(xiě)法其實(shí)沒(méi)有前一種寫(xiě)法健壯,這個(gè)也是我前不久在研究非阻塞加載腳本技術(shù)時(shí)候碰到的問(wèn)題,因?yàn)楦鶕?jù)前端優(yōu)化的原則,javascript代碼往往是位于頁(yè)面的底部,當(dāng)頁(yè)面有被腳本阻塞時(shí)候,html標(biāo)簽里引用的函數(shù)可能還沒(méi)執(zhí)行到,這個(gè)時(shí)候我們點(diǎn)擊頁(yè)面按鈕,結(jié)果會(huì)報(bào)出“XXX函數(shù)未定義的錯(cuò)誤”,在javascript里這樣的錯(cuò)誤是會(huì)被try,catch所捕獲,因此為了讓代碼更加健壯,我們會(huì)有如下的改寫(xiě):

復(fù)制代碼 代碼如下:

<input type="button" id="btn" name="btn" onclick="try{btnClk();}catch(e){}"/>  

  看到上面代碼豈是一個(gè)惡心能描述的。

       方式二:DOM0級(jí)事件處理

       DOM0級(jí)事件處理是當(dāng)今所有瀏覽器都支持的事件處理,不存在任何兼容性問(wèn)題,看到這樣一句話都會(huì)讓每個(gè)做web前端的人們激動(dòng)不已。DOM0事件處理的規(guī)則是:每個(gè)DOM元素都有自己的事件處理屬性,該屬性可以賦值一個(gè)函數(shù),例如下面的代碼:

復(fù)制代碼 代碼如下:

var btnDOM = document.getElementById("btn");
btnDOM.onclick = function(){
         alert("click me!");           
}

DOM0級(jí)事件處理的事件屬性都是采用“on+事件名稱”的方式定義,整個(gè)屬性都是小寫(xiě)字母。我們知道DOM元素在javascript代碼里就是一個(gè)javascript對(duì)象,因此從javascript對(duì)象角度理解DOM0級(jí)事件處理就非常容易,例如下面代碼:

復(fù)制代碼 代碼如下:

btnDOM.onclick = null;  

  那么按鈕的點(diǎn)擊事件被取消了。

  再看下面的代碼:

復(fù)制代碼 代碼如下:

btnDOM.onclick = function(){
         alert("click me!");           
}
 
btnDOM.onclick = function(){
         alert("click me1111!");           
}

后面一個(gè)函數(shù)會(huì)將第一個(gè)函數(shù)覆蓋。

  方式三:DOM2事件處理和IE事件處理

  DOM2事件處理是標(biāo)準(zhǔn)化的事件處理方案,但是IE瀏覽器自己搞了一套,功能和DOM2事件處理相似,但是代碼寫(xiě)起來(lái)就不太一樣了。

  在講解方式三之前,我必須要補(bǔ)充一些概念,否則是無(wú)法講清楚方式三的內(nèi)涵。

  第一個(gè)概念是:事件流

在頁(yè)面開(kāi)發(fā)里我們常常會(huì)碰到這樣的情況,一個(gè)頁(yè)面的工作區(qū)間在javascript可以用document表示,頁(yè)面里有個(gè)div,div等于是覆蓋在document元素上,div里面有個(gè)button元素,button元素是覆蓋在div上,也等于覆蓋著document上,所以問(wèn)題來(lái)了,當(dāng)我們點(diǎn)擊這個(gè)按鈕時(shí)候,這個(gè)點(diǎn)擊行為其實(shí)不僅僅發(fā)生在button之上,div和document都被作用了點(diǎn)擊操作,按邏輯這三個(gè)元素都是可以促發(fā)點(diǎn)擊事件的,而事件流正是描述上述場(chǎng)景的概念,事件流的意思是:從頁(yè)面接收事件的順序。

第二個(gè)概念:事件冒泡和事件捕獲

事件冒泡是微軟公司提出解決事件流問(wèn)題的方案,而事件捕獲則是網(wǎng)景公司提出的事件流解決方案,它們的原理如下圖:

冒泡事件由div開(kāi)始,其次是body,最后是document,事件捕獲則是倒過(guò)來(lái)的先是document,其次是body,最后是目標(biāo)元素div,相比之下,微軟公司的方案更加人性化符合人們的操作習(xí)慣,網(wǎng)景的方案就很別扭了,這是瀏覽器大戰(zhàn)的惡果,網(wǎng)景慢了一步就以犧牲用戶習(xí)慣的代碼解決事件流的問(wèn)題。

       微軟公司結(jié)合冒泡事件設(shè)計(jì)了一套新的事件系統(tǒng),業(yè)界習(xí)慣稱為ie事件處理,ie事件處理方式如下面代碼所示:

復(fù)制代碼 代碼如下:

var btnDOM = document.getElementById("btn");
btnDOM.attachEvent("onclick",function(){
         alert("Click Me!");
});

在ie下通過(guò)DOM元素的attachEvent方法添加事件,和DOM0事件處理相比,添加事件的方式由屬性變成了方法,所以我們添加事件就需要往方法里傳遞參數(shù),attachEvent方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)是事件類型,事件類型的命名和DOM0事件處理里的事件命名一樣,第二個(gè)參數(shù)是事件函數(shù)了,使用方法的好處就是如果我們?cè)跒橥粋€(gè)元素添加個(gè)點(diǎn)擊事件,如下所示:

復(fù)制代碼 代碼如下:

btnDOM.attachEvent("onclick",function(){
         alert("Click Me!");
});
btnDOM.attachEvent("onclick",function(){
         alert("Click Me,too!");
});

運(yùn)行之,兩個(gè)對(duì)話框都能正常彈出來(lái),方法讓我們可以為DOM元素添加多個(gè)不同的點(diǎn)擊事件。如果我們不要某個(gè)事件呢?我們?cè)撛趺醋隽?,ie為刪除事件提供了detachEvent方法,參數(shù)列表和attachEvent一樣,如果我們要?jiǎng)h除某個(gè)點(diǎn)擊事件,只要傳遞和添加事件一樣的參數(shù)即可,如下代碼所示:

復(fù)制代碼 代碼如下:

btnDOM.detachEvent("onclick",function(){
         alert("Click Me,too!");
});

運(yùn)行之,后果很嚴(yán)重,我們很迷惑,第二個(gè)click居然沒(méi)有被刪除,這是怎么回事?前面我講到刪除事件要傳入和添加事件一樣的參數(shù),但是在javascript的匿名函數(shù)里,兩個(gè)匿名函數(shù)哪怕代碼完全一樣,javascript都會(huì)在內(nèi)部使用不同變量存儲(chǔ),結(jié)果就是我們看到的現(xiàn)象無(wú)法刪除點(diǎn)擊事件的,因此我們的代碼要這么寫(xiě):

復(fù)制代碼 代碼如下:

var ftn = function(){
         alert("Click Me,too!");
};
btnDOM.attachEvent("onclick",ftn);
btnDOM.detachEvent("onclick",ftn);

這樣添加的方法和刪除的方法就是指向了同一個(gè)對(duì)象,所以事件刪除成功了。這里的場(chǎng)景告訴我們寫(xiě)事件要有個(gè)良好的習(xí)慣即操作函數(shù)要獨(dú)立定義,不要用匿名函數(shù)用成了習(xí)慣。

接下來(lái)就是DOM2事件處理,它的原理如下圖所示:

DOM2是標(biāo)準(zhǔn)化的事件,使用DOM2事件,事件傳遞首先從捕獲方式開(kāi)始即從document開(kāi)始,再到body,div是一個(gè)中介點(diǎn),事件到了中介點(diǎn)時(shí)候事件就處于目標(biāo)階段,事件進(jìn)入目標(biāo)階段后事件就開(kāi)始冒泡處理方式,最后事件在document上結(jié)束。(捕獲事件的起點(diǎn)以及冒泡事件的終點(diǎn),我本文都是指向document,實(shí)際情況是有些瀏覽器會(huì)從window開(kāi)始捕獲,window結(jié)束冒泡,不過(guò)我覺(jué)得開(kāi)發(fā)時(shí)候不管瀏覽器本身怎么設(shè)定,我們關(guān)注document更具開(kāi)發(fā)意義,所以我這里一律都是使用document)。人們習(xí)慣把目標(biāo)階段歸為冒泡的一部分,這主要是因?yàn)殚_(kāi)發(fā)里冒泡事件使用的更加廣泛。

  DOM2事件處理很折騰,每次事件促發(fā)時(shí)候都會(huì)把所有元素遍歷兩遍,這點(diǎn)和ie事件相比性能就差多了,ie只有冒泡,所以ie只需要遍歷一次,不過(guò)遍歷少了并不代表ie的事件體系效率更高,從開(kāi)發(fā)設(shè)計(jì)角度同時(shí)支持兩種事件系統(tǒng)會(huì)給我們開(kāi)發(fā)帶來(lái)更大的靈活度,從這個(gè)角度而言DOM2事件還是很有可取之處。DOM2事件的代碼如下:

復(fù)制代碼 代碼如下:

var btnDOM = document.getElementById("btn");
btnDOM.addEventListener("click",function(){
         alert("Click Me!");
},false);
var ftn = function(){
         alert("Click Me,too!");
};
btnDOM.addEventListener("click",ftn,false);

DOM2事件處理里添加事件使用的是addEventListener,它接收三個(gè)參數(shù)比ie事件處理多一個(gè),前兩個(gè)的意思和ie事件處理方法的兩個(gè)參數(shù)一樣,唯一的區(qū)別就是第一個(gè)參數(shù)里要去掉on這個(gè)前綴,第三個(gè)參數(shù)是個(gè)布爾值,如果它的取值是true,那么事件就按照捕獲方式處理,取值為false,事件就是按照冒泡處理,有第三個(gè)參數(shù)我們可以理解為什么DOM2事件處理里要把事件元素跑個(gè)兩遍,目的就是為了兼容兩種事件模型,不過(guò)這里要請(qǐng)注意下,不管我們選擇是捕獲還是冒泡,兩遍遍歷是永遠(yuǎn)進(jìn)行,如果我們選擇一種事件處理方式,那么另外一個(gè)事件處理流程里就不會(huì)促發(fā)任何事件處理函數(shù),這和汽車掛空擋空轉(zhuǎn)的道理一樣。通過(guò)DOM2事件方法的設(shè)計(jì),我們知道DOM2事件在運(yùn)行時(shí)候只能執(zhí)行兩種事件處理方式中的一種,不可能兩個(gè)事件流體系同時(shí)促發(fā),所以雖然元素遍歷兩遍,但是事件函數(shù)絕不可能被促發(fā)兩遍,注意我這里指不促發(fā)兩遍是指一個(gè)事件函數(shù),其實(shí)我們可以模擬兩個(gè)事件流模型同時(shí)執(zhí)行的情況,例如下面代碼:

復(fù)制代碼 代碼如下:

btnDOM.addEventListener("click",ftn,true);
btnDOM.addEventListener("click",ftn,false);

但這種寫(xiě)法是多事件處理,相當(dāng)于我們點(diǎn)擊兩次按鈕。

  DOM2也提供了刪除事件的函數(shù),這個(gè)函數(shù)就是removeEventListener,寫(xiě)法如下:

復(fù)制代碼 代碼如下:

btnDOM.removeEventListener("click",ftn,false);

使用和ie事件的一樣即參數(shù)要和定義事件的參數(shù)一致,不過(guò)removeEventListener使用時(shí)候,第三個(gè)參數(shù)不傳,默認(rèn)是刪除冒泡事件,因?yàn)榈谌齻€(gè)參數(shù)不傳默認(rèn)都是false,例如:

復(fù)制代碼 代碼如下:

btnDOM.addEventListener("click",ftn,true);
btnDOM.removeEventListener("click",ftn);

運(yùn)行之,發(fā)現(xiàn)事件沒(méi)有被刪除成功。

  最后我要說(shuō)的是DOM2事件處理在ie9包括ie9以上的版本都得到了很好的支持,ie8以下是不支持DOM2事件的。

  下面我們對(duì)三種事件方式做個(gè)比較,比較如下:

  比較一:方式一為一方和其他兩種方式比較

  方式一的寫(xiě)法是html和javascript結(jié)合在一起,你中有我我中有你,把這種方式深化一下就是html和javascript混合開(kāi)發(fā),用一個(gè)軟件術(shù)語(yǔ)表達(dá)就是代碼耦合,代碼耦合不好,而且是非常不好,這是菜鳥(niǎo)程序員的級(jí)別,所以方式一完敗,另外兩種方式完勝。

  比較二:方式二和方式三

  它們兩個(gè)寫(xiě)法差不多,有時(shí)真的很難說(shuō)誰(shuí)好誰(shuí)壞,縱觀上述內(nèi)容我們發(fā)現(xiàn)方式二和方式三的最大區(qū)別就是:使用方式二一個(gè)DOM元素某個(gè)事件有且只有一次,而方式三則可以讓DOM元素某個(gè)事件擁有多個(gè)事件處理函數(shù),在DOM2事件處理里,方式三還能讓我們精確控制事件流的方式,因此方式三的功能比方式二更加的強(qiáng)大,所以相比之下方式三略勝一籌。

  下面就是本文的重點(diǎn):事件系統(tǒng)的性能問(wèn)題,解決性能問(wèn)題必須找到一個(gè)著力點(diǎn),這里我從兩個(gè)著力點(diǎn)來(lái)思考事件系統(tǒng)的性能問(wèn)題,它們分別是:減少遍歷次數(shù)和內(nèi)存消耗。

  首先是遍歷次數(shù),不管是捕獲事件流還是冒泡事件流,都會(huì)遍歷元素,而是都是從最上層的window或document開(kāi)始的遍歷,假如頁(yè)面DOM元素父子關(guān)系很深,那么遍歷的元素越多,像DOM2事件處理這種,遍歷危害程度就越大了,如何解決這個(gè)事件流遍歷問(wèn)題了?我的回答是沒(méi)有,這里有些朋友也許會(huì)有疑問(wèn),怎么會(huì)沒(méi)有了?事件系統(tǒng)里有個(gè)事件對(duì)象即event,這個(gè)對(duì)象有阻止冒泡或捕獲事件的方法,我怎么說(shuō)沒(méi)有呢?這位朋友的疑問(wèn)很有道理,但是如果我們要使用該方法減少遍歷,那么我們代碼就要處理父子元素的關(guān)系,爺孫元素關(guān)系,如果頁(yè)面元素嵌套很多,這就是沒(méi)法完成的任務(wù),所以我的回答是沒(méi)法改變遍歷的問(wèn)題,只能去適應(yīng)它。

  看來(lái)減少遍歷是沒(méi)法解決事件系統(tǒng)性能問(wèn)題了,那么現(xiàn)在只有從內(nèi)存消耗考慮了。我常聽(tīng)人說(shuō)C#很好用,對(duì)于web前端開(kāi)發(fā)它就更好用了,我們可以直接在C#的IDE拖一個(gè)按鈕到頁(yè)面,按鈕到了頁(yè)面之后javascript代碼會(huì)自動(dòng)為該按鈕添加個(gè)事件,當(dāng)然里面的事件函數(shù)是個(gè)空函數(shù),于是我想我們可以按這種方式在頁(yè)面放置100個(gè)按鈕,一個(gè)代碼都不行就有了100個(gè)按鈕事件處理,超級(jí)方便,最后我們對(duì)其中一個(gè)按鈕添加具體的按鈕事件,讓頁(yè)面跑起來(lái),請(qǐng)問(wèn)大家這個(gè)頁(yè)面效率會(huì)高嗎?在javascript里,每個(gè)函數(shù)都是一個(gè)對(duì)象,每個(gè)對(duì)象都會(huì)耗費(fèi)內(nèi)存,所以這無(wú)用的99個(gè)事件函數(shù)代碼肯定消耗了很多寶貴的瀏覽器內(nèi)存。當(dāng)然現(xiàn)實(shí)開(kāi)發(fā)環(huán)境里我們不會(huì)這么干的,但是在當(dāng)今ajax流行,單頁(yè)面開(kāi)發(fā)瘋狂普及的時(shí)代,一個(gè)網(wǎng)頁(yè)上的事件都是超級(jí)多的,這就意味我們每個(gè)事件都有一個(gè)事件函數(shù),但是我們每次操作都只會(huì)促發(fā)一個(gè)事件,此時(shí)其他事件都是躺著睡覺(jué),起不到任何作用同時(shí)還要消耗計(jì)算機(jī)的內(nèi)存。

  我們需要一種方案改變這種情況,現(xiàn)實(shí)中的確有這種方案。為了清晰描述這個(gè)方案,我要先補(bǔ)充一些背景知識(shí),在講述DOM2事件處理里我提到了目標(biāo)對(duì)象這個(gè)概念,拋開(kāi)DOM2事件處理方式,在捕獲事件處理和冒泡事件處理里也有目標(biāo)對(duì)象的概念,目標(biāo)對(duì)象就是事件具體操作的DOM元素,例如點(diǎn)擊按鈕操作里按鈕就是目標(biāo)對(duì)象,不管哪個(gè)事件處理方式,事件函數(shù)都會(huì)包含一個(gè)event對(duì)象,event對(duì)象有個(gè)屬性target,target是永遠(yuǎn)指向目標(biāo)對(duì)象的,event對(duì)象還有個(gè)屬性就是currentTarget,這個(gè)屬性指向的是捕獲或冒泡事件流動(dòng)到的DOM元素。由上文描述我們知道,不管是捕獲事件還是冒泡事件,事件流都會(huì)流動(dòng)到document上,假如我們?cè)赿ocument上添加點(diǎn)擊事件,頁(yè)面上的按鈕不添加點(diǎn)擊事件,這時(shí)候我們點(diǎn)擊按鈕,我們知道document上的點(diǎn)擊事件會(huì)促發(fā),這里有個(gè)細(xì)節(jié)就是促發(fā)document點(diǎn)擊事件時(shí)候,event的target的指向是button而不是document,那么我們可以這樣寫(xiě)代碼:

復(fù)制代碼 代碼如下:

<input type="button" id="btn" name="btn" value="BUTTON"/>
<a href="#" id="aa">aa</a>
document.addEventListener("click",function(evt){
         var target = evt.target;
         switch(target.id){
                   case "btn":
                            alert("button");
                            break;
                   case "aa":
                            alert("a");
                            break;
         }
},false);

運(yùn)行之,我們發(fā)現(xiàn)效果和我們單獨(dú)寫(xiě)按鈕事件一樣。但是它的好處是不言而喻的,一個(gè)函數(shù)搞定了整個(gè)頁(yè)面的事件函數(shù),而且沒(méi)有事件函數(shù)被空閑,簡(jiǎn)直完美,這個(gè)方案還有個(gè)專業(yè)名稱:事件委托。jQuery的delegate方法就是按這個(gè)原理做的。其實(shí)事件委托的效率不僅僅體現(xiàn)在事件函數(shù)的減少,它還能減少dom遍歷操作,例如上面例子里我們?cè)赿ocument上添加函數(shù),document是頁(yè)面里的頂層對(duì)象,讀取它的效率是很高的,到了具體的對(duì)象事件我們也沒(méi)有通過(guò)dom操作而是使用事件對(duì)象的target屬性,所有這些只能用一句話概括:真是快,沒(méi)理由的快。

  事件委托還能給我們帶來(lái)一個(gè)很棒副產(chǎn)品,使用過(guò)jQuery的朋友都應(yīng)該用過(guò)live方法,live方法特點(diǎn)是你可以為頁(yè)面元素添加事件操作,哪怕這個(gè)元素目前在頁(yè)面還不存在,你也可以添加它的事件,理解了事件委托機(jī)制,live的原理就很好理解了,其實(shí)jQuery的live就是通過(guò)事件委托做的,同時(shí)live還是一種高效的事件添加方式。

  理解了事件委托,我們會(huì)發(fā)現(xiàn)jQuery的bind方法是個(gè)低效的方法,因?yàn)樗褂迷嫉氖录x方式,所以bind我們要慎用,其實(shí)jQuery的開(kāi)發(fā)者也注意到這個(gè)問(wèn)題,新版的jQuery里都有一個(gè)on方法,on方法包含了bind、live和delegate方法所有功能,所以我建議看了本文的朋友要摒棄以前使用添加事件的方式,多使用on函數(shù)添加事件。

  事件委托還有個(gè)好處,上文里事件委托的例子我是在document上添加事件,這里我要做個(gè)比較,在jQuery里我們習(xí)慣把DOM元素事件的定義放在ready方法里,如下所示:

復(fù)制代碼 代碼如下:

$(document).ready(function(){
    XXX.bind("click",function(){});
});

ready函數(shù)是在頁(yè)面DOM文檔加載完畢后執(zhí)行,它比onload函數(shù)先執(zhí)行,這種提前好處很多,好處之一也是帶來(lái)性能提升,jQuery這種事件定義也算是個(gè)標(biāo)準(zhǔn)做法,我相信有些朋友一定又把某些事件綁定放在ready外面,最后發(fā)現(xiàn)按鈕會(huì)無(wú)效,這種無(wú)效場(chǎng)景有時(shí)一剎那,過(guò)會(huì)兒就好了,所以我們常常忽視了該問(wèn)題的原理,不在ready函數(shù)綁定事件,這個(gè)操作其實(shí)是在DOM加載完畢之前綁定事件,而這個(gè)時(shí)間段下,很有可能某些元素還沒(méi)在頁(yè)面構(gòu)造好,所以事件綁定會(huì)出現(xiàn)無(wú)效情況,因此ready定義事件的道理就是保證頁(yè)面所有元素加載完畢后在定義DOM元素的事件,但是使用事件委托時(shí)可以避免問(wèn)題的發(fā)生,例如將事件綁定在document,document代表整個(gè)頁(yè)面,所以它加載完畢的時(shí)間可謂最早,所以在document上實(shí)現(xiàn)事件委托,就很難發(fā)生事件無(wú)效的情況,也很難發(fā)生瀏覽器報(bào)出“XXX函數(shù)未定義”的問(wèn)題了??偨Y(jié)一下這個(gè)特點(diǎn):事件委托代碼可以運(yùn)行在頁(yè)面加載的任何階段,這點(diǎn)對(duì)提升網(wǎng)頁(yè)性能還是增強(qiáng)網(wǎng)頁(yè)效果上都會(huì)給開(kāi)發(fā)人員提供更大自由度。

  好了本文寫(xiě)畢。晚安。

相關(guān)文章

最新評(píng)論