JS一步一步來說說事件委托(或者叫事件代理)

一步一步來說說事件委托(或者有的資料叫事件代理)

  • js中事件冒泡我們知道杨何,子元素身上的事件會冒泡到父元素身上唧躲。
  • 事件代理就是政模,本來加在子元素身上的事件,加在了其父級身上热某。
  • 那就產(chǎn)生了問題:父級那么多子元素,怎么區(qū)分事件本應該是哪個子元素的胳螟?
  • 答案是:event對象里記錄的有“事件源”昔馋,它就是發(fā)生事件的子元素。
  • “事件源”它存在兼容性問題糖耸,在老的IE下秘遏,事件源是 window.event.srcElement,其他瀏覽器是 event.target
    用事件委托有什么好處呢嘉竟?
  • 第一個好處是效率高邦危,比如,不用for循環(huán)為子元素添加事件了
  • 第二個好處是舍扰,js新生成的子元素也不用新為其添加事件了倦蚪,程序邏輯上比較方便

還是用一個例子來說明吧

例子1. 頁面有個ul包含著4個li,鼠標移動到li上边苹,li背景變成紅色陵且,移出,背景恢復原色个束。

如果按照以前的寫法慕购,代碼如下:

        <ul id="ul1">
            <li>111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
        </ul>
        
        <script type="text/javascript">
            window.onload = function(){
                var oUl = document.getElementById('ul1');
                var aLi = oUl.children;
                console.log(aLi);
                
                //傳統(tǒng)方法,li身上添加事件茬底,需要用for循環(huán)脓钾,找到每個li
                for (var i=0;i<aLi.length;i++) {
                    aLi[i].onmouseover = function() {
                        this.style.background = 'red';
                    }
                    aLi[i].onmouseout = function(){
                        this.style.background = '';
                    }
                }//for結束

                
            }
        </script>

現(xiàn)在用事件委托的方式,onmouseover桩警、onmouseout方法要加在ul身上了可训,再通過找事件源的方式昌妹,改變li背景,代碼如下:

上面ul的html代碼不變握截,js部分變?yōu)?/p>

<script type="text/javascript">
            window.onload = function(){
                var oUl = document.getElementById('ul1');                
                oUl.onmouseover = function(ev){
                    var ev = ev || window.event;
                    var oLi = ev.srcElement || ev.target;
                    oLi.style.background = 'red';                    
                }
                
                oUl.onmouseout = function(ev){
                    var ev = ev || window.event;
                    var oLi = ev.srcElement || ev.target;
                    oLi.style.background = '';                    
                }
                
            }
</script>

效果如下:


image

但是會發(fā)現(xiàn)飞崖,鼠標移到了ul身上而不是某個li身上時,獲取的事件源是ul谨胞,那么整個ul背景將變紅固歪,這不是想要的結果,怎么辦胯努?

答曰:加個判斷牢裳。通過事件源的nodeName判斷是不是li,是才做出反應叶沛,不是不理它蒲讯。為了防止nodeName在不同瀏覽器獲取的字母大小寫不同,加個toLowerCase()

所以灰署,上面的js代碼更改如下:

<script type="text/javascript">
            window.onload = function(){
                var oUl = document.getElementById('ul1');
                
                oUl.onmouseover = function(ev){
                    var ev = ev || window.event;
                    var oLi = ev.srcElement || ev.target;
                    if(oLi.nodeName.toLowerCase() == 'li'){
                        oLi.style.background = 'red';
                    }
                                        
                }
                
                oUl.onmouseout = function(ev){
                    var ev = ev || window.event;
                    var oLi = ev.srcElement || ev.target;
                    if(oLi.nodeName.toLowerCase() == 'li'){
                        oLi.style.background = '';
                    }                
                }

                
            }
</script>
image

這就不用for循環(huán)寫一堆了判帮,下面再來說說第二個好處:js新生成的子元素也不用新為其添加事件了,程序邏輯上比較方便

上面的文件溉箕,假如我再新添加個按鈕晦墙,點擊按鈕,ul里就新增加個li肴茄,如果用傳統(tǒng)的方法晌畅,for循環(huán)為li添加事件,問題就出現(xiàn)了寡痰,最開始有的4個li是有onmouseover和onmouseout事件的踩麦,但是后來動態(tài)生成的li里沒有這兩個事件處理函數(shù),因為for循環(huán)的時候它還沒生成氓癌。怎么辦呢谓谦?只能在按鈕點擊后,生成li贪婉,然后再為生成的li再綁定事件反粥,真是麻煩的很。而事件委托的方式就沒事疲迂,當后來動態(tài)生成的li出現(xiàn)的時候才顿,不用做改變,移到它身上尤蒿,還是變色的郑气,因為事件是綁定在ul身上的。

新浪微博里腰池,當你發(fā)一條新微博出去尾组,發(fā)出去的信息在頁面上顯示忙芒,鼠標移動到新發(fā)的信息的人頭像上時,依然會有很多事件讳侨,如果用原來的方式呵萨,就要做很多處理,事件委托的話跨跨,就很方便了潮峦!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市勇婴,隨后出現(xiàn)的幾起案子忱嘹,更是在濱河造成了極大的恐慌,老刑警劉巖耕渴,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拘悦,死亡現(xiàn)場離奇詭異,居然都是意外死亡萨螺,警方通過查閱死者的電腦和手機窄做,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門愧驱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慰技,“玉大人,你說我怎么就攤上這事组砚∥巧蹋” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵糟红,是天一觀的道長艾帐。 經(jīng)常有香客問我,道長盆偿,這世上最難降的妖魔是什么柒爸? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮事扭,結果婚禮上捎稚,老公的妹妹穿的比我還像新娘。我一直安慰自己求橄,他們只是感情好今野,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著罐农,像睡著了一般条霜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上涵亏,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天宰睡,我揣著相機與錄音蒲凶,去河邊找鬼。 笑死夹厌,一個胖子當著我的面吹牛豹爹,可吹牛的內容都是我干的。 我是一名探鬼主播矛纹,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼臂聋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了或南?” 一聲冷哼從身側響起孩等,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎采够,沒想到半個月后肄方,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蹬癌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年权她,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逝薪。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡隅要,死狀恐怖,靈堂內的尸體忽然破棺而出董济,到底是詐尸還是另有隱情步清,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布虏肾,位于F島的核電站廓啊,受9級特大地震影響,放射性物質發(fā)生泄漏封豪。R本人自食惡果不足惜谴轮,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吹埠。 院中可真熱鬧第步,春花似錦、人聲如沸藻雌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胯杭。三九已至驯杜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間做个,已是汗流浹背鸽心。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工滚局, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人顽频。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓藤肢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親糯景。 傳聞我的和親對象是個殘疾皇子嘁圈,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內容