javascript事件委托和jquery事件委托

元旦過后蛾扇,新年第一篇。
初衷:很多的面試都會(huì)涉及到事件委托魏滚,前前后后也看過好多博文镀首,寫的都很不錯(cuò),寫的各有千秋鼠次,自己思前想后更哄,為了以后自己的查看,也同時(shí)為現(xiàn)在找工作的前端小伙伴提供一個(gè)看似更全方位的解讀事件委托的地方來認(rèn)識(shí)了解他的原理腥寇,本篇文章匯總了兩個(gè)版本的事件委托:javascript成翩、jquery;

事件委托的定義:

利用事件冒泡,指定一個(gè)事件處理程序赦役,就可以管理某一類型的所有事件麻敌。

事件委托的優(yōu)勢:

  • 在js中添加到頁面上的事件處理程序的個(gè)數(shù)直接影響到網(wǎng)頁的運(yùn)行性能。因?yàn)槊總€(gè)事件處理函數(shù)都是一個(gè)對象掂摔,是對象就會(huì)占用內(nèi)存术羔,而內(nèi)存中對象越多,導(dǎo)致的結(jié)果就是性能越差乙漓;而訪問dom的次數(shù)越多级历,就會(huì)引起結(jié)構(gòu)的重繪或者重排的次數(shù)也隨之增多,會(huì)延遲整個(gè)頁面的交互就緒時(shí)間叭披;
  • 對于在頁面進(jìn)行處理過后新增的dom元素寥殖,運(yùn)用事件委托可以為新增的dom元素一并增減事件處理程序;

在下面的代碼中p標(biāo)簽要實(shí)現(xiàn)的效果是鼠標(biāo)點(diǎn)擊p標(biāo)簽的時(shí)候背景色變?yōu)榧t色涩蜘,以下是js嚼贡、jq的處理方法

<body>
    <div id="nodes">
      <P class="node_p">第一個(gè)p</P>
      <P class="node_p">第二個(gè)p</P>
      <P class="node_p">第三個(gè)p</P>
      <div id="childDiv">
          <p>這是子集菜單</p>
          <div>我是子集的div
              <p>我是子集的p</p>
          </div>
      </div>
    </div>
    <button>點(diǎn)擊加一</button>
  </body>

一、js事件委托

在js中不用事件委托的情況:獲取頁面中所有的p標(biāo)簽然后用for循環(huán)遍歷給每一個(gè)元素增加事件處理函數(shù)

let nodes = document.getElementById("nodes");
    let ps = document.getElementsByTagName("p");
    console.log(ps);
    let btn = document.getElementsByTagName("button")[0];
    let inner = 33;

    btn.onclick = function() {
      inner++;
      let p = document.createElement("p");
      p.innerHTML = inner + "新增的p標(biāo)簽啊";
      nodes.appendChild(p);
      console.log(ps);
    };
    for (let i= 0;i<ps.length;i++){
        ps[i].onclick= function(){
            this.style.background = 'red'
        }  
    }

這時(shí)候在瀏覽器中運(yùn)行之后進(jìn)行測試同诫,發(fā)現(xiàn)如圖一所示的結(jié)果粤策;


圖一

那么js不用事件委托怎么給新增加的標(biāo)簽添加事件處理函數(shù)呢?解決方案如下:

let nodes = document.getElementById("nodes");
    let ps = document.getElementsByTagName("p");
    console.log(ps);
    let btn = document.getElementsByTagName("button")[0];
    let inner = 33;

    btn.onclick = function () {
        inner++;
        let p = document.createElement("p");
        p.innerHTML = inner + "新增的p標(biāo)簽啊";
        nodes.appendChild(p);
        addEvent();//將新dom元素增加到頁面后再執(zhí)行循環(huán)函數(shù)
        console.log(ps);
    };

    function addEvent() {
        for (let i = 0; i < ps.length; i++) {
            ps[i].onclick = function () {
                this.style.background = 'red'
            }
        }
    }
    addEvent() //先執(zhí)行一遍循環(huán)

這時(shí)候?yàn)g覽器中運(yùn)行如圖二所示:


圖二

這時(shí)候雖然解決了為新增dom元素增加事件處理函數(shù)的問題剩辟,但是仔細(xì)考慮他的性能卻是比之前都有所下降,究其原因就是又增加了一個(gè)事件處理函數(shù)(對象),又一次占用了內(nèi)存贩猎;所以熊户,這個(gè)時(shí)候就會(huì)用到事件委托,這時(shí)候事件委托的優(yōu)勢也有所體現(xiàn)出來:

let nodes = document.getElementById("nodes");
    let ps = document.getElementsByTagName("p");
    console.log(ps);
    let btn = document.getElementsByTagName("button")[0];
    let inner = 33;

    btn.onclick = function () {
        inner++;
        let p = document.createElement("p");
        p.innerHTML = inner + "新增的p標(biāo)簽啊";
        nodes.appendChild(p);
        console.log(ps);
    };
//事件委托吭服,為nodes指定一個(gè)事件處理函數(shù)嚷堡,處理nodes下為p標(biāo)簽的所有元素的cilck事件
    nodes.onclick= function(e){
        let ev = e || window.event
        let target = ev.target || ev.srcElement //srcElement IE瀏覽器
        //這里要判被處理元素節(jié)點(diǎn)的名字,也可以增加相應(yīng)的判斷條件 target.nodeName.toLowerCase() == 'p'||target.nodeName.toLowerCase() == 'span',但是要注意不要使用父級元素的名稱艇棕,因?yàn)樵冱c(diǎn)擊子元素之間的空氣的時(shí)候蝌戒,由于事件冒泡他會(huì)給父級元素也增加相應(yīng)的事件處理函數(shù);因?yàn)榉祷氐墓?jié)點(diǎn)名稱一般都是大寫沼琉,所以這時(shí)要用toLowerCase()處理一下北苟;
        if(target.nodeName.toLowerCase() == 'p'){ 
            target.style.background = 'green'
        }
    }

這時(shí)候?yàn)g覽器中運(yùn)行的結(jié)果如圖三所示:


圖三

二、jquery事件委托:

相較于js事件委托打瘪,jquery事件委托的優(yōu)勢:執(zhí)行事件委托的時(shí)候只有子元素會(huì)觸發(fā)事件函數(shù)友鼻,而代為執(zhí)行的父元素不會(huì)觸發(fā)事件函數(shù),因此不用去判斷元素節(jié)點(diǎn)的名稱闺骚;(注意這里的事件委托用的方法on,如果用bind方法父元素會(huì)觸發(fā)事件函數(shù))
這里nodes節(jié)點(diǎn)下所有標(biāo)簽為p的子節(jié)點(diǎn)都被賦予事件處理函數(shù)彩扔;這里的子節(jié)點(diǎn)還可以是多個(gè)類似' p,span',需要注意這里面也不可以寫同nodes一樣的標(biāo)簽,否則點(diǎn)擊元素之間的間隔會(huì)給nodes下的div賦予事件處理函數(shù)僻爽;如例二:
例一:

let inner = 33;
//這里nodes節(jié)點(diǎn)下所有標(biāo)簽為p的子節(jié)點(diǎn)都被賦予事件處理函數(shù)虫碉;這里的子節(jié)點(diǎn)還可以是多個(gè)類似' p,span',需要注意這里面也不可以寫同nodes一樣的標(biāo)簽,否則點(diǎn)擊元素之間的間隔會(huì)給nodes下的div賦予事件處理函數(shù)
$('#nodes').on('click','p',function(e){
        let target = $(e.target)
        target.css('backgroundColor','red')
    })
    $('button').click(()=>{
        inner++;
        $('#nodes').append($('<p>我是新增加的p標(biāo)簽'+inner+'</p>'))
    })

瀏覽器運(yùn)行的效果如圖四所示:

圖四

例二:

<body>
    <div id="nodes">
        <P class="node_p">第一個(gè)p</P>
        <P class="node_p">第二個(gè)p</P>
        <P class="node_p">第三個(gè)p</P>
        <span class="node_p">span</span>
        <div id="childDiv">
            <p>這是子集菜單</p>
            <div>我是子集的div
                <p>我是子集的p</p>
            </div>
        </div>
    </div>
    <button>點(diǎn)擊加一</button>
</body>
<script>
let inner =33;
$('#nodes').on('click','p,div,span',function(e){
        let target = $(e.target)
        target.css('backgroundColor','red')
    })
    $('button').click(()=>{
        inner++;
        $('#nodes').append($('<p>我是新增加的p標(biāo)簽'+inner+'</p>'))
    })
</script>

瀏覽器運(yùn)行效果如圖五所示:


圖五

事件委托不僅僅只是為處理一種dom操作類型胸梆,他可以進(jìn)行增刪改查等功能:

js事件委托:不同操作

<body>
    <div id="events">
        <input type="button" id='addHandle' value='增加'>
        <input type="button" id='deleteHandle' value='減少'>
    </div>
    <div id="content">

    </div>
</body>
<script src='http://code.jquery.com/jquery-2.1.1.min.js'></script>
<script>
    let events = document.getElementById('events');
    let content = document.getElementById('content');
    events.onclick=function(e){
        let ev = e || window.event;
        let target = ev.target || ev.srcElement;
        if(target.nodeName.toLowerCase()=='input'){
            switch(target.id){
                case 'addHandle':
                return addEvent();
                break
                case 'deleteHandle':
                return deleteEvent();
                break
            }
        }
    }
    function addEvent(){
        let add = document.createElement('p')
        add.innerHTML = '這是增加按鈕'
        content.appendChild(add)
    }
    function deleteEvent(){
        let del = document.createElement('p')
        del.innerHTML = '這是刪除按鈕'
        content.appendChild(del)
    }
</script>

瀏覽器中的效果如圖六所示:


圖六

jquery事件委托:不同操作

$('#events').on('click','input',(e)=>{
        let target = $(e.target);
        switch(target[0].id){
                case 'addHandle':
                return addEvent();
                break
                case 'deleteHandle':
                return deleteEvent();
                break
        }
    })
    function addEvent(){
        $('#content').append($('<div>這是增加按鈕</div>'))
    }
    function deleteEvent(){
        $('#content').append($('<div>這是刪除按鈕</div>'))
    }

瀏覽器中的效果如圖七所示:


圖七

本文如有不實(shí)之處敦捧,還望大神指點(diǎn)一二,歡迎討論乳绕!

2019我在路上绞惦,加油!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洋措,一起剝皮案震驚了整個(gè)濱河市济蝉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌菠发,老刑警劉巖王滤,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異滓鸠,居然都是意外死亡雁乡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門糜俗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踱稍,“玉大人曲饱,你說我怎么就攤上這事≈樵拢” “怎么了扩淀?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長啤挎。 經(jīng)常有香客問我驻谆,道長,這世上最難降的妖魔是什么庆聘? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任胜臊,我火速辦了婚禮,結(jié)果婚禮上伙判,老公的妹妹穿的比我還像新娘象对。我一直安慰自己,他們只是感情好澳腹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布织盼。 她就那樣靜靜地躺著,像睡著了一般酱塔。 火紅的嫁衣襯著肌膚如雪沥邻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天羊娃,我揣著相機(jī)與錄音唐全,去河邊找鬼。 笑死蕊玷,一個(gè)胖子當(dāng)著我的面吹牛邮利,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垃帅,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼延届,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了贸诚?” 一聲冷哼從身側(cè)響起方庭,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酱固,沒想到半個(gè)月后械念,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡运悲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年龄减,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片班眯。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡希停,死狀恐怖烁巫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宠能,我是刑警寧澤程拭,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站棍潘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏崖媚。R本人自食惡果不足惜亦歉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望畅哑。 院中可真熱鬧肴楷,春花似錦、人聲如沸荠呐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泥张。三九已至呵恢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間媚创,已是汗流浹背渗钉。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钞钙,地道東北人鳄橘。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像芒炼,于是被迫代替她去往敵國和親瘫怜。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5本刽? 答:HTML5是最新的HTML標(biāo)準(zhǔn)鲸湃。 注意:講述HT...
    kismetajun閱讀 27,485評論 1 45
  • ??JavaScript 與 HTML 之間的交互是通過事件實(shí)現(xiàn)的。 ??事件椅贱,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,490評論 1 11
  • (續(xù)jQuery基礎(chǔ)(1)) 第5章 DOM節(jié)點(diǎn)的復(fù)制與替換 (1)DOM拷貝clone() 克隆節(jié)點(diǎn)是DOM的常...
    凜0_0閱讀 1,338評論 0 8
  • $HTML别瞭, HTTP窿祥,web綜合問題 1、前端需要注意哪些SEO 2蝙寨、 的title和alt有什么區(qū)別 3晒衩、HT...
    Hebborn_hb閱讀 4,599評論 0 20
  • 一家企業(yè)經(jīng)營獲利以后嗤瞎,利潤的分配是有規(guī)定順序的。首先听系,要彌補(bǔ)以前年度的虧損(若有)贝奇;其次,要按照當(dāng)年稅后利潤的10...
    是個(gè)人類閱讀 2,601評論 0 1