亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Javascript的事件委托

系統(tǒng) 1922 0

原文: http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/#

?

傳統(tǒng)的事件處理

所謂事件委托即使用單個(gè)Event Handler來(lái)管理頁(yè)面上特定的一類事件。這并不是什么新的idea,但對(duì)于Web應(yīng)用的性能而言,是很重要的。比如,有時(shí)候,你可能會(huì)寫(xiě)如下的代碼:

    document.getElementById("help-btn").onclick = function(event){
    openHelp();
};

document.getElementById("save-btn").onclick = function(event){
    saveDocument();
};

document.getElementById("undo-btn").onclick = function(event){
    undoChanges();
}; 
  

它為頁(yè)面上每一個(gè)可交互的元素提供了一個(gè)Event Handler。在一個(gè)小型的Web應(yīng)用中,這可能問(wèn)題不明顯。但如果這是一個(gè)大型的網(wǎng)站,存在大量的交互,這么多的handler可能就會(huì)出現(xiàn)性能問(wèn)題了。可以想象,為了處理數(shù)以百計(jì)的交互,我們需要將大量的DOM元素和時(shí)間處理代碼綁定起來(lái)。這會(huì)占用大量的內(nèi)存,進(jìn)而導(dǎo)致整個(gè)應(yīng)用運(yùn)行變慢。而事件委托就可以用來(lái)解決這個(gè)問(wèn)題。

事件冒泡和捕獲(Event Bubbling / Capturing)

在早期Web開(kāi)發(fā)的年代,瀏覽器廠商需要考慮一個(gè)問(wèn)題:當(dāng)用戶在Web頁(yè)面上點(diǎn)擊一個(gè)區(qū)域,如何判斷他實(shí)際正在進(jìn)行互交互的元素。與之相關(guān)的是我們?nèi)绾味x交互。在一個(gè)元素內(nèi)點(diǎn)擊的操作是有二義性的。如下圖所示,如果用戶點(diǎn)擊了一個(gè)button元素,這個(gè)交互發(fā)生在button內(nèi)部,同時(shí)我們也可以說(shuō)它發(fā)生在body元素的內(nèi)部,同時(shí)還在html元素的內(nèi)部。

????? 在這個(gè)問(wèn)題被提出來(lái)的時(shí)候,當(dāng)時(shí)的兩個(gè)主要瀏覽器(Netscape Navigator 和 Internet Explorer)采取了不同方式來(lái)解決這個(gè)問(wèn)題。Netscape使用了一種叫做事件捕捉的機(jī)制,事件首先發(fā)生在DOM樹(shù)上最高層的元素上,然后逐層往下傳遞到最深的被影響的元素上。所以,在上述例子中,點(diǎn)擊事件首先由document元素來(lái)處理,然后是html元素,接下來(lái)是body,最后才是button元素。

????? Internet Explorer正好使用了完全相反的方式。他們稱之為事件冒泡:最底層的元素應(yīng)該首先接受到這個(gè)時(shí)間,然后才是它的父節(jié)點(diǎn),祖父節(jié)點(diǎn)……一直到最高層的document元素。值得注意的是,雖然document和<html>元素對(duì)應(yīng)的是頁(yè)面上同一個(gè)可視元素,但它們?cè)贒OM樹(shù)上卻是父子關(guān)系。Event Bubbling的終點(diǎn)是document元素。

在定義DOM的時(shí)候,W3C顯然注意到了兩種不同方式各自的好處,因此我們現(xiàn)在使用的DOM Level 2事件機(jī)制中同時(shí)包含了這兩種方式。一開(kāi)始document元素接收到這個(gè)事件,進(jìn)入捕獲階段,將其傳遞到最底層的元素。在這個(gè)元素的處理邏輯完成以后,進(jìn)入冒泡階段,將其傳遞回到document。在DOM Level2事件API中,addEventListener方法接受三個(gè)參數(shù):要處理的事件名,事件處理函數(shù),一個(gè)bool值(true表示在捕獲階段處理事件,而false表示在冒泡階段處理事件)。多數(shù)Web開(kāi)發(fā)人員經(jīng)常會(huì)被告知使用false作為參數(shù)值,以保持和IE中的attachEvent方法相同的行為。比如:

    //bubbling phase handler
document.addEventListener("click", handleClick, false);

//capturing phase handler
document.addEventListener("click", handleClick, true);
  

使用形如 element.onclick = function(){} 的方式來(lái)綁定事件的方式,即DOM Level 1的事件機(jī)制,是在冒泡階段處理事件的(向前兼容性)。大多數(shù)瀏覽器(除了IE)都支持DOM Level 2事件機(jī)制,也就是說(shuō)同時(shí)支持事件捕獲和冒泡。IE仍然使用的是其專有的,僅支持冒泡方式的事件處理機(jī)制。

?

事件委托的關(guān)鍵就是使用事件冒泡的特性在DOM最高層的元素來(lái)處理它們(通常是document)。當(dāng)然,不是所有的事件都支持冒泡(如onsubmit,onfocus,onblur這一類不和輸入設(shè)備直接相關(guān)的時(shí)間等),但是鼠標(biāo)和鍵盤(pán)事件都可以(包括onclick)。而且,很幸運(yùn)的是,這些通常是你會(huì)感興趣的。重新考慮之前的例子,你可以在document的事件處理函數(shù)中,檢查事件的目標(biāo)元素,并完成相應(yīng)的邏輯。

    document.onclick = function(event){
    //IE doesn't pass in the event object
    event = event || window.event;
    
    //IE uses srcElement as the target
    var target = event.target || event.srcElement;    

    switch(target.id){
        case "help-btn":
            openHelp();
            break;
        case "save-btn":
            saveDocument();
            break;
        case "undo-btn":
            undoChanges();
            break;
        //others?
    }
};

  

事件委托可以讓同一事件的處理入口都匯集到一個(gè)函數(shù)中。所有的click事件現(xiàn)在都會(huì)先被單個(gè)函數(shù)所處理,并根據(jù)時(shí)間的對(duì)象元素委托給合適的函數(shù)。同樣的,我們把它應(yīng)用于 mousedown , mouseup , mousemove , mouseover , mouseout , dblclick , keyup , keydown , 和 keypress 事件. 這里要注意的一點(diǎn)就是, 由于mouseover 和mouseout事件的特性(僅當(dāng)鼠標(biāo)移出容器時(shí)才會(huì)觸發(fā) mouseout),事件代理對(duì)它們來(lái)說(shuō)并不是很實(shí)用。

當(dāng)然,你也可以通過(guò)事件捕獲來(lái)完成Event delegation,但這僅在支持事件捕獲的瀏覽器中有效,也就是說(shuō)IE不支持該方式。

好處

對(duì)于一個(gè)web應(yīng)用來(lái)說(shuō),事件代理具有以下幾點(diǎn)好處:

  1. 較少的事件處理函數(shù).
  2. 占用更少的內(nèi)存.
  3. 減少了Javascript和DOM之間的耦合.
  4. 在改變?cè)氐膇nnerHTML時(shí),不用去移除綁定事件處理函數(shù) .

相比于傳統(tǒng)的事件處理方式,事件委托提高了大型web應(yīng)用的總體性能。它對(duì)于Javascript庫(kù)至關(guān)重要,如 YUI jQuery 已經(jīng)使用了這種機(jī)制。實(shí)現(xiàn)事件委托并不難,但是在用戶界面的性能上的提高確實(shí)非常顯著的。這在你將大量的事件處理函數(shù)合并為一個(gè)的時(shí)候,尤其明顯。試試事件委托機(jī)制吧!

?

Javascript的事件委托


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 欧美性大战久久久久久久蜜桃 | 精品一区二区三区在线视频观看 | 玖玖国产在线观看 | 99久久精品无码一区二区毛片 | 热久久精品 | 欧美精品亚洲二区 | 亚洲夜色 | 日本伊人色综合网站 | 亚洲精品区一区二区三区四 | 91久久夜色精品国产九色 | 国产欧美国产精品第一区 | 国内精品视频在线播放一区 | 久草视频在线网 | 奇米影视7777777 | 亚欧毛片 | 狠狠色婷婷丁香六月 | 免费一级欧美片在线观看 | 免费福利视频在线观看 | 久久综合爱 | www.中文字幕在线观看 | 日本一区二区三区免费看 | 欧美日韩成人在线 | 国产三级不卡 | 久久久久嫩草影院精品 | 天天操人人爱 | 国产亚洲精品久久久久久无 | 四虎avtom影院 | 久久国产美女 | 奇米色影院 | 欧美一区二区精品 | 一级欧美毛片成人免费视频 | 亚洲午夜久久久精品影院视色 | 激情五月开心婷婷 | 成人凹凸短视频在线观看 | 点击进入不卡毛片免费观看 | 亚洲国产综合人成综合网站00 | 久久精品国产精品亚洲红杏 | 亚洲区精品久久一区二区三区 | 欧美日韩一二三区免费视频观看 | 国产精品福利在线观看 | 亚洲精品国产精品一区二区 |