事件傳播機(jī)制绳矩、阻止傳播平项、取消默認(rèn)事件危虱、事件代理

1羊娃、事件傳播機(jī)制

事件流描述的是從頁面中接收事件的順序,比如有一個嵌套的div埃跷,我們點(diǎn)擊了內(nèi)層div,這時這個click事件是內(nèi)層先觸發(fā)還是外層先觸發(fā)呢蕊玷,目前事件的傳播機(jī)制主要有三種:
1、冒泡事件: 事件開始時弥雹,是由目標(biāo)元素最先觸發(fā)垃帅,然后逐級像上傳播,直到根節(jié)點(diǎn)
2剪勿、捕獲事件:捕獲事件和冒泡事件相反贸诚,由根節(jié)點(diǎn)先觸發(fā)事件,然后逐級向內(nèi)傳播厕吉,直到目標(biāo)元素
3酱固、DOM事件:DOM2事件規(guī)定事件流分為三個階段:首先為捕獲階段,為截取事件提供機(jī)會头朱。然后是實(shí)際目標(biāo)接受階段运悲,最后是冒泡階段

舉個栗子:操作一下可以更直觀的理解

<style>
    .container,
    .box,
    .target{
      border: 1px solid;
      padding: 10px;
    }  
 </style>
 <div class="container">
        container
        <div class="box">
          box
          <div class="target">target</div>
        </div>
  </div>
冒泡事件:
function $(selector){
     return document.querySelector(selector)
}

 $(".container").addEventListener('click', function(e){
            console.log('container....冒泡階段')
        },false)

        $('.box').addEventListener('click',function(e){
            console.log('box....冒泡階段')
        },false)

        $('.target').addEventListener('click',function(e){
            console.log('target....冒泡階段')
        },false)
冒泡階段.jpg
— 通過例子可以看出冒泡階段是由內(nèi)部目標(biāo)元素先觸發(fā)事件,然后逐級像外傳播的项钮,直到根元素
捕獲事件:
$(".container").addEventListener('click', function(e){
            console.log('container....捕獲階段')
        },true)

        $('.box').addEventListener('click',function(e){
            console.log('box....捕獲階段')
        },true)

        $('.target').addEventListener('click',function(e){
            console.log('target....捕獲階段')
        },true)
捕獲階段.jpg
— 捕獲階段是外部根元素先觸發(fā)事件班眯,然后像內(nèi)逐級傳播,最后到達(dá)目標(biāo)元素

2烁巫、阻止傳播

DOM2級事件定義了兩個方法用于處理指定和刪除事件處理程序的操作:
1署隘、addEventListener
2、removeEventListener

所有的DOM節(jié)點(diǎn)都包含這兩個方法亚隙,并且它們都接受三個參數(shù):
1定踱、事件類型
2、事件處理方法
3恃鞋、布爾參數(shù)崖媚,如果是true表示在捕獲階段調(diào)用事件處理程序,如果是false恤浪,則是在事件冒泡階段處理

3畅哑、取消默認(rèn)事件

冒泡和捕獲是事件的兩種行為,使用event.stopPropagation()起到阻止捕獲和冒泡階段中當(dāng)前事件的進(jìn)一步傳播水由。使用event.preventDefault()可以取消默認(rèn)事件荠呐。

阻止事件冒泡與捕獲:w3c的方法是e.stopPropagation(),IE則是使用e.cancelBubble = true。stopPropagation作為事件對象(Event)的一個方法泥张,作用是阻止目標(biāo)元素的冒泡事件呵恢,但是會不阻止默認(rèn)行為。

var handler = function (e) {
    alert(e.type);
    e.stopPropagation();
}

addEvent(document.body, 'click', function () { alert('Clicked body')});
var btnClick = document.getElementById('btnClick');
addEvent(btnClick, 'click', handler);

若是注釋掉e.stopPropagation(); 在點(diǎn)擊button的時候媚创,由于事件冒泡渗钉,body的click事件也會觸發(fā),但是調(diào)用這句后钞钙,事件會停止傳播

取消默認(rèn)事件的方法:w3c的方法是e.preventDefault()鳄橘,IE則是使用e.returnValue = false;
要阻止事件的默認(rèn)行為芒炼,可以使用preventDefault()方法瘫怜,比如我們可以阻止鏈接導(dǎo)航這一默認(rèn)行為

document.querySelector('#btn').onclick = function (e) {
    e.preventDefault();
}

4、事件代理

事件代理又稱為“事件委托”本刽。意思是把原本需要綁定在子元素上的事件委托給父元素鲸湃,讓父元素負(fù)責(zé)監(jiān)聽的職務(wù),委托代理的原理是DOM元素的事件冒泡子寓。

假如有這樣一個HTML片段

    <div class="container">
       <div class="box">box1</div>
       <div class="box">box2</div>
       <div class="box">box3</div>
    </div>
    <button id="add">add</button>

點(diǎn)擊每個class為box的元素暗挑,都會在控制臺打印出他們的內(nèi)容。
點(diǎn)擊id為add的按鈕别瞭,可以增加一個class=box的div元素。同樣點(diǎn)擊他們可以打印出他們的內(nèi)容
我們常常會這樣寫

       function $(selector){
            return document.querySelector(selector)
        }
        function $$(selector){
            return document.querySelectorAll(selector)
        }

        $$('.box').forEach(function(val){
            val.addEventListener('click',function(){
                console.log(this.innerText)
            })
        })

        var i= 4
        $('#add').onclick=function(){
            var box=document.createElement('div')
            box.innerText='box' + (i++)
            box.classList.add('box')
            $('.container').appendChild(box)
        }

打印結(jié)果:


例圖.jpg

會發(fā)現(xiàn)只有box1,box2,box3可以在控制臺打印出來株憾,新建的box4蝙寨,box5卻不行。因?yàn)樽铋_始頁面上只有3個class為box的元素嗤瞎,所以js只為這三個元素綁定了click事件墙歪,后面我們add新的div需要重新添加click事件才會有效果,這就很頭疼了贝奇。這個時候我們就需要事件委托了:

        function $(selector){
            return document.querySelector(selector)
        }
        function $$(selector){
            return document.querySelectorAll(selector)
        }

        var i= 4
        $('#add').onclick=function(){
            var box=document.createElement('div')
            box.innerText='box' + (i++)
            box.classList.add('box')
            $('.container').appendChild(box)
        }

        $('.container').onclick=function(e){
            if(e.target.classList.contains('box')){
                console.log(e.target.innerText)
            }
        }

打印結(jié)果:


委托代理.jpg

這樣就再也不用擔(dān)心新建元素內(nèi)容出不來嘍~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末虹菲,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子掉瞳,更是在濱河造成了極大的恐慌毕源,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陕习,死亡現(xiàn)場離奇詭異霎褐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)该镣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門冻璃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事省艳∧锓祝” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵跋炕,是天一觀的道長赖晶。 經(jīng)常有香客問我,道長枣购,這世上最難降的妖魔是什么嬉探? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮棉圈,結(jié)果婚禮上涩堤,老公的妹妹穿的比我還像新娘。我一直安慰自己分瘾,他們只是感情好胎围,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著德召,像睡著了一般白魂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上上岗,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天福荸,我揣著相機(jī)與錄音,去河邊找鬼肴掷。 笑死敬锐,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的呆瞻。 我是一名探鬼主播台夺,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼痴脾!你這毒婦竟也來了颤介?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤赞赖,失蹤者是張志新(化名)和其女友劉穎滚朵,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體前域,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡始绍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了话侄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亏推。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡学赛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吞杭,到底是詐尸還是另有隱情盏浇,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布芽狗,位于F島的核電站绢掰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏童擎。R本人自食惡果不足惜滴劲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望顾复。 院中可真熱鬧班挖,春花似錦、人聲如沸芯砸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽假丧。三九已至双揪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間包帚,已是汗流浹背渔期。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留渴邦,地道東北人疯趟。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像几莽,于是被迫代替她去往敵國和親迅办。 傳聞我的和親對象是個殘疾皇子宅静,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359