事件委托

事件委托,其實之前有用過放案,但是就是百度了一下,并不了解它的優(yōu)點到低好在哪里矫俺。今天突發(fā)奇想就了解了一下吱殉。
那下來總結(jié)一下吧。


  • 什么是事件委托厘托?
    事件委托友雳,也叫事件代理。利用了事件冒泡铅匹,可以用一個事件處理方法押赊,管理處理一類事件。
  • 事件委托的好處包斑?
    比如我們要給所有的li設(shè)置相同的onclick事件流礁,首先想到的就是用for循環(huán)遍歷了吧,但是每一次遍歷就會進行一次dom操作罗丰。而添加到頁面上的事件數(shù)量將直接關(guān)系到頁面的整體運行性能神帅,訪問dom的次數(shù)越多,引起瀏覽器重繪與重排的次數(shù)也就越多萌抵,就會延長整個頁面的交互就緒時間找御。所以事件委托的好處就在于大大減少了dom操作的次數(shù),提高性能绍填。
  • 事件委托原理
    利用事件冒泡原理霎桅,就是從事件最深的節(jié)點開始,逐步向上傳播事件讨永。
    eg: div > ul > li > a 想要給a加一個點擊事件時滔驶,它的執(zhí)行順序就是
    a> li >ul > div,給里面的元素 a,li,ul添加事件時,最后都會冒泡到最外層的div上住闯,所以都會觸發(fā)瓜浸,委托它們的父級代替它們執(zhí)行。
  • 事件委托怎么寫比原?
    Event對象提供了一個屬性叫target插佛,可以返回事件的目標(biāo)節(jié)點,稱為事件源量窘,也就是說雇寇,target就可以表示為當(dāng)前的事件操作的dom,但是不是真正操作dom,當(dāng)然锨侯,這個是有兼容性的嫩海,標(biāo)準(zhǔn)瀏覽器用ev.target,IE瀏覽器用event.srcElement囚痴,此時只是獲取了當(dāng)前節(jié)點的位置叁怪,并不知道是什么節(jié)點名稱,所以還要用nodeName來獲取具體是什么標(biāo)簽名深滚,這個返回的是一個大寫的奕谭,我們需要轉(zhuǎn)成小寫(toLowerCase())再做比較
    兼容性寫法:
function (event) {
            let ev = event || window.event;
            let target = ev.target || ev.srcElement;
}

下面看例子吧:

<ul id="ul">
     <li>111</li>
     <li>222</li>
     <li>333</li>
     <li>444</li>
 </ul>

要給上述的每個li一個點擊事件,顯示字符串123痴荐。

  • 基礎(chǔ)方法:需要遍歷這個li的對象集合血柳,然后給每個li綁定點擊事件
    window.onload = function(){
        const ul= document.getElementById("ul");
        const li = ul.getElementsByTagName('li');
        for(let i=0; i<aLi.length; i++){
            li[i].onclick = function(){
                console.log(123);
            }
        }
    }
  • 父級ul做事件處理,觸發(fā)點擊事件(但不是點擊每個結(jié)點觸發(fā)的事件)
 window.onload = function () {
        const  ul = document.getElementById("ul");
        ul.onclick = function () {
            alert("1234");
        }
    }
  • 事件委托生兆,給父級綁定事件难捌,但當(dāng)點擊每個結(jié)點時才觸發(fā)事件
  window.onload = function () {
        const  ul = document.getElementById("ul");
        ul.onclick = function (event) {
            let target = event.target;
            if(target.nodeName.toLowerCase() === 'li'){
                console.log("1234");
                console.log(target.innerHTML);
            }
        }
    }

上面的例子應(yīng)該很清晰的可以看出事件委托的優(yōu)點了,減少了遍歷和dom操作的次數(shù)鸦难。


對于不同的dom操作如何用事件委托呢根吁?下面再來看個例子,更加深的體會一下吧明刷。

   <div id="box">
       <input type="button" value="添加" id="add">
       <input type="button" value="刪除" id="remove">
       <input type="button" value="選擇" id="chose">
       <input type="button" value="移動" id="move">
   </div>

要實現(xiàn)點擊對應(yīng)的按鈕婴栽,顯示他要執(zhí)行的操作。

  • 基本方法: 給每個按鈕都綁定相應(yīng)的點擊事件
            var add = document.getElementById("add");
            var remove = document.getElementById("remove");
            var move = document.getElementById("move");
            var chose = document.getElementById("chose");
            add.onclick = function(){
                alert('添加');
            };
            remove.onclick = function(){
                alert('刪除');
            };
            move.onclick = function(){
                alert('移動');
            };
            chose.onclick = function(){
                alert('選擇');
            }
        }
  • 事件委托:給父級元素綁定點擊事件辈末,點擊不同的按鈕愚争,通過選擇,觸發(fā)事件
  window.onload = function () {
       const  box = document.getElementById("box");
       box.onclick = function (event) {
           let target = event.target;
           switch (target.id.toLowerCase()) {
               case 'add':
                   console.log('添加');
                   break;
               case 'remove':
                   console.log('刪除');
                   break;
               case 'chose':
                   console.log('選擇');
                   break;
               case 'move':
                   console.log("移動");
                   break;
           }
       }
    }

通過這個例子就更清晰的看出事件委托挤聘,減少了綁定事件的dom操作轰枝。

emmm..下面這個例子就是創(chuàng)建新節(jié)點,并給新節(jié)點綁定相同的事件

   <input type="button" value="添加" id="add">
   <ul id="ul">
       <li>111</li>
       <li>222</li>
       <li>333</li>
       <li>444</li>
   </ul>

要求鼠標(biāo)放上去為紅色组去,離開為黃色鞍陨,添加新節(jié)點,也要有這些事件

  • 基本方法:對每一個li標(biāo)簽進行遍歷操作从隆,注意要想新節(jié)點要有這些事件诚撵,得將原有的事件封裝成一個方法,創(chuàng)建新節(jié)點后键闺,調(diào)用此方法寿烟。
    window.onload = function () {
        const ul = document.getElementById("ul");
        const li = document.getElementsByTagName('li');
        const btn = document.getElementById("add");
        function addNew() {
            for(let i = 0;i<li.length;i++){
                li[i].onmouseover = function () {
                    this.style.backgroundColor = 'red';
                };
                li[i].onmouseout = function () {
                    this.style.backgroundColor ='yellow';
                }
            }
        }
        btn.onclick = function () {
            let one = document.createElement('li');
            one.innerText = '555';
            ul.appendChild(one);
            addNew();
        };
    }
  • 事件委托:給父元素綁定事件,點擊子元素觸發(fā)事件辛燥,新產(chǎn)生的節(jié)點筛武,也可以擁有相同的事件缝其,不需要別的操作
window.onload = function () {
        const ul = document.getElementById("ul");
        const li = document.getElementsByTagName('li');
        const btn = document.getElementById("add");
        ul.onmouseover = function (event) {
            let target = event.target;
            if(target.nodeName.toLowerCase() === 'li')
                target.style.backgroundColor = 'red';
        };
        ul.onmouseout= function (event) {
            let target = event.target
            if(target.nodeName.toLowerCase() === 'li')
                target.style.backgroundColor = 'yellow';
        };

        btn.onclick = function () {
            let one = document.createElement('li');
            one.innerText = '555';
            ul.appendChild(one);
        };
    };

寫了這么多例子,應(yīng)該很清晰了徘六。


事件委托其實并不是所有的事件都適合用内边。
適合用事件委托的事件:click,mousedown待锈,mouseup漠其,keydown,keyup竿音,keypress辉懒。
但是其中mouseover和mouseout都有位置計算問題,所以也不建議使用谍失。

可以參考:js事件委托或事件代理詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市莹汤,隨后出現(xiàn)的幾起案子快鱼,更是在濱河造成了極大的恐慌,老刑警劉巖纲岭,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抹竹,死亡現(xiàn)場離奇詭異,居然都是意外死亡止潮,警方通過查閱死者的電腦和手機窃判,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喇闸,“玉大人袄琳,你說我怎么就攤上這事∪颊В” “怎么了唆樊?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長刻蟹。 經(jīng)常有香客問我逗旁,道長,這世上最難降的妖魔是什么舆瘪? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任片效,我火速辦了婚禮,結(jié)果婚禮上英古,老公的妹妹穿的比我還像新娘淀衣。我一直安慰自己,他們只是感情好哺呜,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布舌缤。 她就那樣靜靜地躺著箕戳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪国撵。 梳的紋絲不亂的頭發(fā)上陵吸,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音介牙,去河邊找鬼壮虫。 笑死,一個胖子當(dāng)著我的面吹牛环础,可吹牛的內(nèi)容都是我干的囚似。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼线得,長吁一口氣:“原來是場噩夢啊……” “哼饶唤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贯钩,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤募狂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后角雷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祸穷,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年勺三,在試婚紗的時候發(fā)現(xiàn)自己被綠了雷滚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡吗坚,死狀恐怖祈远,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情刻蚯,我是刑警寧澤绊含,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站炊汹,受9級特大地震影響躬充,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜讨便,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一充甚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧霸褒,春花似錦伴找、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抖誉。三九已至,卻和暖如春衰倦,著一層夾襖步出監(jiān)牢的瞬間袒炉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工樊零, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留我磁,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓驻襟,卻偏偏與公主長得像夺艰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子沉衣,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353