成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

好文推薦:javascript: 事件委托解析

Wuv1Up / 2793人閱讀

摘要:前言之前不太明白事件委托??戳诉@個(gè)帖子,跟著代碼操作了一遍,終于明白了事件委托。推薦理由一步一步,漸進(jìn)式分析來(lái)說(shuō)明事件委托。為簽收快遞,有兩種辦法一是三個(gè)人在公司門(mén)口等快遞二是委托給前臺(tái)代為簽收。

前言:之前不太明白事件委托。 看了這個(gè)帖子,跟著代碼操作了一遍,終于明白了事件委托。所以轉(zhuǎn)載。
推薦理由:一步一步,漸進(jìn)式分析來(lái)說(shuō)明事件委托。

什么叫事件委托呢?它還有一個(gè)名字叫事件代理

JavaScript高級(jí)程序設(shè)計(jì)上講:事件委托就是利用事件冒泡,只指定一個(gè)事件處理程序,就可以管理某一類(lèi)型的所有事件。

網(wǎng)上的各位大牛們講事件委托基本上都用了同一個(gè)例子,就是取快遞來(lái)解釋這個(gè)現(xiàn)象,大家認(rèn)真領(lǐng)會(huì)一下事件委托到底是一個(gè)什么原理:

有三個(gè)同事預(yù)計(jì)會(huì)在周一收到快遞。為簽收快遞,有兩種辦法:一是三個(gè)人在公司門(mén)口等快遞;二是委托給前臺(tái)MM代為簽收?,F(xiàn)實(shí)當(dāng)中,我們大都采用委托的方案(公司也不會(huì)容忍那么多員工站在門(mén)口就為了等快遞)。前臺(tái)MM收到快遞后,她會(huì)判斷收件人是誰(shuí),然后按照收件人的要求簽收,甚至代為付款。這種方案還有一個(gè)優(yōu)勢(shì),那就是即使公司里來(lái)了新員工(不管多少),前臺(tái)MM也會(huì)在收到寄給新員工的快遞后核實(shí)并代為簽收。

這里其實(shí)還有2層意思的:

第一,現(xiàn)在委托前臺(tái)的同事是可以代為簽收的,即程序中的現(xiàn)有的dom節(jié)點(diǎn)是有事件的;

第二,新員工也是可以被前臺(tái)MM代為簽收的,即程序中新添加的dom節(jié)點(diǎn)也是有事件的。

為什么要用事件委托:

一般來(lái)說(shuō),dom需要有事件處理程序,我們都會(huì)直接給它設(shè)事件處理程序就好了,那如果是很多的dom需要添加事件處理呢?比如我們有100個(gè)li,每個(gè)li都有相同的click點(diǎn)擊事件,可能我們會(huì)用for循環(huán)的方法,來(lái)遍歷所有的li,然后給它們添加事件,那這么做會(huì)存在什么影響呢?

在JavaScript中,添加到頁(yè)面上的事件處理程序數(shù)量將直接關(guān)系到頁(yè)面的整體運(yùn)行性能,因?yàn)樾枰粩嗟呐cdom節(jié)點(diǎn)進(jìn)行交互,訪(fǎng)問(wèn)dom的次數(shù)越多,引起瀏覽器重繪與重排的次數(shù)也就越多,就會(huì)延長(zhǎng)整個(gè)頁(yè)面的交互就緒時(shí)間,這就是為什么性能優(yōu)化的主要思想之一就是減少DOM操作的原因;如果要用事件委托,就會(huì)將所有的操作放到j(luò)s程序里面,與dom的操作就只需要交互一次,這樣就能大大的減少與dom的交互次數(shù),提高性能;

事件委托的原理:
事件委托是利用事件的冒泡原理來(lái)實(shí)現(xiàn)的,何為事件冒泡呢?就是事件從最深的節(jié)點(diǎn)開(kāi)始,然后逐步向上傳播事件,舉個(gè)例子:頁(yè)面上有這么一個(gè)節(jié)點(diǎn)樹(shù),div>ul>li>a;比如給最里面的a加一個(gè)click點(diǎn)擊事件,那么這個(gè)事件就會(huì)一層一層的往外執(zhí)行,執(zhí)行順序a>li>ul>div,有這樣一個(gè)機(jī)制,那么我們給最外面的div加點(diǎn)擊事件,那么里面的ul,li,a做點(diǎn)擊事件的時(shí)候,都會(huì)冒泡到最外層的div上,所以都會(huì)觸發(fā),這就是事件委托,委托它們父級(jí)代為執(zhí)行事件。

事件委托怎么實(shí)現(xiàn):

在介紹事件委托的方法之前,我們先來(lái)看一段一般方法的例子:

子節(jié)點(diǎn)實(shí)現(xiàn)相同的功能:

  • 111
  • 222
  • 333
  • 444
window.onload = function(){ 
    var oUl = document.getElementById("ul1"); 
    var aLi = oUl.getElementsByTagName("li"); 
    for(var i=0;i

上面的代碼的意思很簡(jiǎn)單,相信很多人都是這么實(shí)現(xiàn)的,我們看看有多少次的dom操作,首先要找到ul,然后遍歷li,然后點(diǎn)擊li的時(shí)候,又要找一次目標(biāo)的li的位置,才能執(zhí)行最后的操作,每次點(diǎn)擊都要找一次li;
那么我們用事件委托的方式做又會(huì)怎么樣呢?

window.onload = function(){
    var oUl = document.getElementById("ul1");
   oUl.onclick = function(){
        alert(123);
    }
}

這里用父級(jí)ul做事件處理,當(dāng)li被點(diǎn)擊時(shí),由于冒泡原理,事件就會(huì)冒泡到ul上,因?yàn)閡l上有點(diǎn)擊事件,所以事件就會(huì)觸發(fā),當(dāng)然,這里當(dāng)點(diǎn)擊ul的時(shí)候,也是會(huì)觸發(fā)的,那么問(wèn)題就來(lái)了,如果我想讓事件代理的效果跟直接給節(jié)點(diǎn)的事件效果一樣怎么辦,比如說(shuō)只有點(diǎn)擊li才會(huì)觸發(fā),不怕,我們有絕招:
Event對(duì)象提供了一個(gè)屬性叫target,可以返回事件的目標(biāo)節(jié)點(diǎn),我們成為事件源,也就是說(shuō),target就可以表示為當(dāng)前的事件操作的dom,但是不是真正操作dom,當(dāng)然,這個(gè)是有兼容性的,標(biāo)準(zhǔn)瀏覽器用e.target,IE瀏覽器用event.srcElement,此時(shí)只是獲取了當(dāng)前節(jié)點(diǎn)的位置,并不知道是什么節(jié)點(diǎn)名稱(chēng),這里我們用nodeName來(lái)獲取具體是什么標(biāo)簽名,這個(gè)返回的是一個(gè)大寫(xiě)的,我們需要轉(zhuǎn)成小寫(xiě)再做比較(習(xí)慣問(wèn)題):

window.onload = function(){
  var oUl = document.getElementById("ul1");
  oUl.onclick = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeName.toLowerCase() == "li"){
            alert(123);
         alert(target.innerHTML);
    }
  }
}

上面的例子是說(shuō)li操作的是同樣的效果,要是每個(gè)li被點(diǎn)擊的效果都不一樣,那么用事件委托還有用嗎?

window.onload = function(){
            var oBox = document.getElementById("box");
            oBox.onclick = function (ev) {
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLocaleLowerCase() == "input"){
                    switch(target.id){
                        case "add" :
                            alert("添加");
                            break;
                        case "remove" :
                            alert("刪除");
                            break;
                        case "move" :
                            alert("移動(dòng)");
                            break;
                        case "select" :
                            alert("選擇");
                            break;
                    }
                }
            }

        }

現(xiàn)在講的都是document加載完成的現(xiàn)有dom節(jié)點(diǎn)下的操作,那么如果是新增的節(jié)點(diǎn)的方法是什么?


    
  • 111
  • 222
  • 333
  • 444
window.onload = function(){
            var oBtn = document.getElementById("btn");
            var oUl = document.getElementById("ul1");
            var aLi = oUl.getElementsByTagName("li");
            var num = 4;

            //事件委托,添加的子元素也有事件
            oUl.onmouseover = function(ev){
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLowerCase() == "li"){
                    target.style.background = "red";
                }

            };
            oUl.onmouseout = function(ev){
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLowerCase() == "li"){
                    target.style.background = "#fff";
                }

            };

            //添加新節(jié)點(diǎn)
            oBtn.onclick = function(){
                num++;
                var oLi = document.createElement("li");
                oLi.innerHTML = 111*num;
                oUl.appendChild(oLi);
            };
        }

上面是用事件委托的方式,新添加的子元素是帶有事件效果的,我們可以發(fā)現(xiàn),當(dāng)用事件委托的時(shí)候,根本就不需要去遍歷元素的子節(jié)點(diǎn),只需要給父級(jí)元素添加事件就好了,其他的都是在js里面的執(zhí)行,這樣可以大大的減少dom操作,這才是事件委托的精髓所在。

總結(jié):
那什么樣的事件可以用事件委托,什么樣的事件不可以用呢?
適合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。
值得注意的是,mouseover和mouseout雖然也有事件冒泡,但是處理它們的時(shí)候需要特別的注意,因?yàn)樾枰?jīng)常計(jì)算它們的位置,處理起來(lái)不太容易,另外如focus,blur之類(lèi)的,本身就沒(méi)用冒泡的特性,自然就不能用事件委托了。

作者: 熠熠生陽(yáng)
鏈接:http://www.imooc.com/article/...
來(lái)源:慕課網(wǎng)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/89729.html

相關(guān)文章

  • [ 好文分享 ] jQuery最佳實(shí)踐

    摘要:所以,最佳選擇是。事實(shí)上,這種處理完全不必要。這樣的設(shè)計(jì),使得讀取局部變量比讀取全局變量快得多。請(qǐng)看下面兩段代碼,第一段代碼是讀取全局變量第二段代碼是讀取局部變量第二段代碼讀取變量的時(shí)候,不用前往上一層作用域,所以要比第一段代碼快五六倍。 轉(zhuǎn)自:http://www.ruanyifeng.com/blog/2011/08/jquery_best_practices.html ...

    mzlogin 評(píng)論0 收藏0
  • 新鮮出爐的8月前端面試題

    摘要:前言最近參加了幾場(chǎng)面試,積累了一些高頻面試題,我把面試題分為兩類(lèi),一種是基礎(chǔ)試題主要考察前端技基礎(chǔ)是否扎實(shí),是否能夠?qū)⑶岸酥R(shí)體系串聯(lián)。 前言 最近參加了幾場(chǎng)面試,積累了一些高頻面試題,我把面試題分為兩類(lèi),一種是基礎(chǔ)試題: 主要考察前端技基礎(chǔ)是否扎實(shí),是否能夠?qū)⑶岸酥R(shí)體系串聯(lián)。一種是開(kāi)放式問(wèn)題: 考察業(yè)務(wù)積累,是否有自己的思考,思考問(wèn)題的方式,這類(lèi)問(wèn)題沒(méi)有標(biāo)準(zhǔn)答案。 基礎(chǔ)題 題目的答...

    qingshanli1988 評(píng)論0 收藏0
  • JavaScript 事件對(duì)內(nèi)存和性能的影響

    摘要:事件對(duì)內(nèi)存和性能的影響雖說(shuō)事件處理程序可以為現(xiàn)代頁(yè)面添加很強(qiáng)的交互能力,但是不分青紅皂白就添加大量的事件處理程序絕對(duì)是一種愚蠢的行為。最適合采用事件委托的事件包括和。提交提交某個(gè)表單的操作代碼移除事件處理程序提交中。。。 JavaScript 事件對(duì)內(nèi)存和性能的影響 雖說(shuō)事件處理程序可以為現(xiàn)代 Web 頁(yè)面添加很強(qiáng)的交互能力,但是不分青紅皂白就添加大量的事件處理程序絕對(duì)是一種愚蠢的行為...

    Ajian 評(píng)論0 收藏0
  • 簡(jiǎn)單說(shuō) JavaScript中的事件委托(下)

    摘要:說(shuō)明上次我們說(shuō)了一些,關(guān)于中事件委托的基礎(chǔ)知識(shí),這次我們繼續(xù)來(lái)看??蛇x類(lèi)型,一個(gè)選擇器,用于指定哪些后代元素可以觸發(fā)綁定的事件。類(lèi)型,指定的事件處理函數(shù)。 說(shuō)明 上次我們說(shuō)了一些,關(guān)于 JavaScript中事件委托的 基礎(chǔ)知識(shí),這次我們繼續(xù)來(lái)看。 解釋 先來(lái)一段代碼 1 2 ul.onclick...

    MasonEast 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<