javaScript 瀏覽器事件總結(jié)

javaScript 瀏覽器事件

1.事件基本概念

事件是指文檔或者瀏覽器中發(fā)生的一些特定交互瞬間,比如打開某一個(gè)網(wǎng)頁(yè)霜幼,瀏覽器加載完成后會(huì)觸發(fā)load事件,當(dāng)鼠標(biāo)浮于某一個(gè)元素上時(shí)會(huì)觸發(fā)hover事件洗搂,當(dāng)鼠標(biāo)點(diǎn)擊某一個(gè)元素時(shí)會(huì)觸發(fā)click事件等等热康。

事件處理就是當(dāng)事件被觸發(fā)吼沛申,瀏覽器響應(yīng)這個(gè)事件的行為,而這個(gè)行為所對(duì)應(yīng)的代碼即為事件處理程序姐军。

2.事件操作:監(jiān)聽與移除監(jiān)聽

2.1監(jiān)聽事件

瀏覽器會(huì)根據(jù)一些事件作出相對(duì)應(yīng)的事件處理铁材,事件處理的前提是需要監(jiān)聽事件,監(jiān)聽事件的方法主要有以下三種:

2.1.1 HTML內(nèi)聯(lián)屬性

即在HTML元素里直接填寫與事件相關(guān)的屬性奕锌,屬性值為事件處理程序著觉。示例如下:

<button onclick="console.log('You clicked me!');"></button>

onclick對(duì)應(yīng)著click事件,所以當(dāng)按鈕被點(diǎn)擊后歇攻,便會(huì)執(zhí)行事件處理程序固惯,即控制臺(tái)輸出“You clicked me!”缴守。

不過我們需要指出的是葬毫,這種方式將HTML代碼與JavaScript代碼耦合在一起,不利于代碼的維護(hù)屡穗,所以應(yīng)該盡量避免使用這樣的方式贴捡。

2.1.2 DOM屬性綁定

通過直接設(shè)置某個(gè)DOM節(jié)點(diǎn)的屬性來指定事件和事件處理程序,上代碼

const btn = document.getElementById("btn");
btn.onclick = function(e) {
    console.log("You clicked me!")
}

上面示例中村砂,首先獲得btn這個(gè)對(duì)象烂斋,通過給這個(gè)對(duì)象添加onclick屬性的方式來監(jiān)聽click事件,這個(gè)屬性值對(duì)應(yīng)的就是事件處理程序础废。這段程序也被成為DOM 0級(jí)事件處理程序汛骂。

2.1.3 事件監(jiān)聽函數(shù)

標(biāo)準(zhǔn)的事件監(jiān)聽函數(shù)如下:

const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
    console.log("You click me!");
}, false);

上面的示例表示先獲得表示節(jié)點(diǎn)的btn對(duì)象,然后在這個(gè)對(duì)象上面添加了一個(gè)事件監(jiān)聽器评腺,當(dāng)監(jiān)聽到click事件發(fā)生時(shí)帘瞭,則調(diào)用回調(diào)函數(shù),即在控制臺(tái)輸出“You clicked me!”蒿讥。addEventListener函數(shù)包含了第三個(gè)參數(shù)false蝶念,第三個(gè)參數(shù)的含義在后面的事件觸發(fā)三個(gè)階段之后再講解。這段程序也被稱作DOM 2級(jí)事件處理程序芋绸。IE9+媒殉、FireFox、Safari摔敛、Chrome 和 Opera 都是支持 DOM 2 級(jí)事件處理程序的廷蓉,對(duì)于 IE8 及以下版本,則用 attacEvent() 函數(shù)綁定事件马昙。

所以我們得寫一段具有兼容性的代碼:

function addEventHandler(obj, eventName, handler) {
    if (document.addEventListener) {
        obj.addEventListener(eventName, handler, false);
    } else if (document.attachEvent) {
        obj.attachEvent("on" + eventName, handler);
    } else {
        obj["on" + eventName] = handler;
    }
}
2.2移除事件監(jiān)聽

在為某個(gè)元素綁定了一個(gè)事件后苦酱,如果想解除綁定售貌,則需要removeEventListener方法。

const handler = function() {
    // hanlder logic
}
const btn = document.getElementById("btn");

btn.addEventListener("click", handler);
btn.removeEventListener("click", handler);

需要注意的是疫萤,綁定事件的回調(diào)函數(shù)不能是匿名函數(shù),必須是一個(gè)已經(jīng)被聲明的函數(shù)敢伸,因?yàn)榻獬录壎〞r(shí)需要傳遞這個(gè)回調(diào)函數(shù)的引用扯饶。

同樣,IE8 及以下版本也不支持上面的方法池颈,而是用 detachEvent 代替尾序。

const handler = function() {
    // hnalder logic
}
const btn = document.getElementById("btn");

btn.attachEvent("onclick", handler);
btn.detachEvent("onclick", handler);

同樣,可以寫一段具有兼容性的刪除事件函數(shù):

function removeEventHandler(obj, eventName, handler) {
    if (document.removeEventListener) {
        obj.removeEventListener(eventName, handler, false);
    } else if (document.detachEvent) {
        obj.detachEvent("on" + eventName, handler);
    } else {
        obj["on" + eventName] = null;
    }
}
DOM事件級(jí)別

DOM級(jí)別一共可以分為四個(gè)級(jí)別:DOM0級(jí)躯砰、DOM1級(jí)每币、DOM2級(jí)DOM3級(jí)琢歇。而DOM事件分為3個(gè)級(jí)別:DOM 0級(jí)事件處理兰怠,DOM2級(jí)事件處理和DOM3級(jí)事件處理。由于DOM1級(jí)中沒有事件的相關(guān)內(nèi)容李茫,所以沒有DOM1級(jí)事件揭保。

DOM0級(jí)事件

el.onclick=function(){}

var btn = document.getElementById("btn");
btn.onclick = function() {
    alert(this.innerHTML);
}

當(dāng)希望為同一個(gè)元素、標(biāo)簽綁定多個(gè)同類型事件的時(shí)候(如給上面的這個(gè)btn元素綁定3個(gè)點(diǎn)擊事件)魄宏,是不背允許的秸侣。DOM0事件綁定,給元素的事件行為綁定方法宠互,這些方法都是在當(dāng)前元素事件行為的冒泡階段(或者目標(biāo)階段)執(zhí)行的味榛。

DOM 2級(jí)事件

el.addEventListener(event-name,callback,useCapture)

  • event-name: 事件名稱,可以是標(biāo)準(zhǔn)的DOM事件予跌。
  • callback:回調(diào)函數(shù)搏色,當(dāng)事件觸發(fā)時(shí),函數(shù)會(huì)被注入一個(gè)參數(shù)為當(dāng)前事件對(duì)象event匕得。
  • useCpature:默認(rèn)是false继榆,代表事件句柄在冒泡執(zhí)行階段執(zhí)行(或者說注冊(cè)的是冒泡事件),true表示事件句柄在捕獲階段執(zhí)行(或者說注冊(cè)的是捕獲事件)
var btn = document.getElementById('btn');
btn.addEventListener("click", test, false);
function test(e) {
    e = e || window.event;
    alert((e.target || e.srcElement).innerHTML);
    btn.removeEventListner("click", test);
}

IE9以下的IE瀏覽器不支持 addEventListener()和removeEventListener()汁掠,使用 attachEvent()與detachEvent() 代替略吨,因?yàn)镮E9以下是不支持事件捕獲的,所以也沒有第三個(gè)參數(shù)考阱,第一個(gè)事件名稱前要加on翠忠。可以對(duì)此做個(gè)兼容性處理乞榨。

DOM 3級(jí)事件

在DOM 2級(jí)事件的基礎(chǔ)上添加了更多的事件類型秽之。

  • UI事件当娱,當(dāng)用戶預(yù)頁(yè)面的元素交互時(shí)觸發(fā),如:load考榨、scroll
  • 焦點(diǎn)事件跨细,當(dāng)元素獲得或失去焦點(diǎn)時(shí)觸發(fā),如:blur河质、focus
  • 鼠標(biāo)事件冀惭,當(dāng)用戶通過誰(shuí)啊哦在頁(yè)面執(zhí)行操作時(shí)觸發(fā)如:dblclick、mouseup
  • 滾輪事件掀鹅,當(dāng)使用鼠標(biāo)滾輪或類似設(shè)備時(shí)觸發(fā)散休,如:mousewheel
  • 文本事件,當(dāng)在文檔中輸入文本時(shí)觸發(fā)乐尊,如:textinput
  • 鍵盤事件戚丸,當(dāng)用戶通過鍵盤在頁(yè)面上執(zhí)行操作時(shí)觸發(fā),如:keydown扔嵌、keypress
  • 合成事件限府,當(dāng)為IME(輸入法編輯器)輸入字符時(shí)觸發(fā),如:compositionstart
  • 變動(dòng)事件对人,當(dāng)?shù)讓覦OM結(jié)構(gòu)發(fā)生變化時(shí)觸發(fā),如:DOMsubtreeModified谣殊。
  • 同時(shí)DOM 3級(jí)事件也允許使用者自定義一些事件。

總結(jié):

  • DOM2級(jí)的好處是可以添加多個(gè)事件處理程序牺弄;DOM0級(jí)對(duì)每個(gè)事件支持持一個(gè)事件處理程序姻几;
  • 通過DOM2級(jí)添加的匿名函數(shù)無法移除,addEventListenerremoveEventListenerhandler必須同名
  • 作用域:DOM 0的handler會(huì)在所屬元素的作用域內(nèi)運(yùn)行势告,IE的handler會(huì)在全局作用域運(yùn)行蛇捌,this === window
  • 觸發(fā)順序:添加多個(gè)事件時(shí),DOM2會(huì)按照添加順序執(zhí)行咱台,IE會(huì)以相反的順序執(zhí)行

3.事件觸發(fā)過程

事件流描述了頁(yè)面接收事件的順序÷绨瑁現(xiàn)代瀏覽器事件流包含三個(gè)過程,分別是捕獲階段回溺、目標(biāo)階段和冒泡階段春贸。

下面詳細(xì)地講解這三個(gè)過程。

3.1捕獲階段

當(dāng)我們對(duì) DOM元素進(jìn)行操作時(shí)遗遵,比如鼠標(biāo)點(diǎn)擊萍恕、懸浮等,就會(huì)有一個(gè)事件傳輸?shù)竭@個(gè)DOM元素车要,這個(gè)事件從Window開始允粤,依次經(jīng)過document、html、body类垫,再不斷經(jīng)過過子節(jié)點(diǎn)直到到達(dá)目標(biāo)元素司光,從 Window到達(dá)目標(biāo)元素父節(jié)點(diǎn)的過程稱為捕獲階段,注意此時(shí)還未到達(dá)目標(biāo)節(jié)點(diǎn)悉患。

3.2目標(biāo)階段

捕獲階段結(jié)束時(shí)残家,事件到達(dá)了目標(biāo)節(jié)點(diǎn)的父節(jié)點(diǎn),最終到達(dá)目標(biāo)節(jié)點(diǎn)购撼,并在目標(biāo)節(jié)點(diǎn)上觸發(fā)了這個(gè)時(shí)間跪削,這就是目標(biāo)階段

需要注意的是迂求,事件觸發(fā)的目標(biāo)節(jié)點(diǎn)為最底層的節(jié)點(diǎn)。比如下面這個(gè)例子:

<div>
    <p>
        你猜晃跺,目標(biāo)在這里還是<span>哪里</span>
    </p>
</div>

當(dāng)我們點(diǎn)擊“哪里“的時(shí)候揩局,目標(biāo)節(jié)點(diǎn)是<span></span>,點(diǎn)擊這里的時(shí)候掀虎,目標(biāo)節(jié)點(diǎn)是<p></p>凌盯,而當(dāng)我們點(diǎn)擊<p></p>區(qū)域之外,<div></div>區(qū)域之內(nèi)烹玉,目標(biāo)節(jié)點(diǎn)就是<div></div>驰怎。

3.3 冒泡階段

當(dāng)事件到達(dá)目標(biāo)節(jié)點(diǎn)之后,就會(huì)沿著原路返回二打,這個(gè)過程有點(diǎn)類似于水泡從水底浮出水面的過程县忌,所以稱這個(gè)過程為冒泡階段

現(xiàn)在再看addEventListener(eventName, handler, useCapture)函數(shù)继效。第三個(gè)參數(shù)是useCapture症杏,代表是否在捕獲階段進(jìn)行事件處理,如果是false瑞信,則在冒泡階段進(jìn)行事件處理厉颤,如果是true則在捕獲階段進(jìn)行處理,默認(rèn)是false凡简。

冒泡事件的流程剛好是事件捕獲的逆過程逼友。我們來看個(gè)事件冒泡的例子:

<div id="outer">
    <div id="inner">
        
    </div>
</div>
<script>
    window.onclick = function() {
        console.log('window');
    };
    document.onclick = function() {
        console.log('document');
    };
    document.documentElement.onclick = function() {
        console.log('html');
    };
    document.body.onclick = function() {
        console.log('body');
    };
    outer.onclick = function(ev) {
        console.log('outer');
    };
    inner.onclick = function(ev) {
        console.log('inner');
    }
</script>
// 輸出為 inner outter body html dcoument window

4.事件委托

JavaScript中,事件的委托表示給元素的父級(jí)或者祖級(jí)秤涩,甚至頁(yè)面帜乞,由他們來綁定事件,然后利用事件冒泡的基本原理溉仑,通過事件目標(biāo)對(duì)象進(jìn)行檢測(cè)挖函,然后執(zhí)行相關(guān)操作饥漫。

事件委托有兩個(gè)優(yōu)點(diǎn):

  • 減少內(nèi)存消耗摊溶,提高性能

假設(shè)有一個(gè)列表,列表之中有大量的列表項(xiàng),我們需要在點(diǎn)擊每個(gè)列表項(xiàng)的時(shí)候響應(yīng)一個(gè)事件壕鹉。

<ul id="list">
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
  ......
  <li>item n</li>
</ul>

如果給每個(gè)列表項(xiàng)都一一綁定函數(shù),那么對(duì)內(nèi)存的消耗是非常大的养涮,需要消耗更多性能鸭丛。借助事件委托,我們只需要給父容器ul綁定方法即可梳庆,這樣不管點(diǎn)擊哪一個(gè)后代元素暖途,都會(huì)根據(jù)冒泡傳播的傳遞機(jī)制,把容器的click行為處罰膏执,然后把對(duì)應(yīng)的方法執(zhí)行驻售,根據(jù)事件源,我們可以知道點(diǎn)擊的是誰(shuí)更米,從而完成不同的事欺栗。

  • 動(dòng)態(tài)綁定事件

在很多時(shí)候,我們需要通過用戶操作動(dòng)態(tài)的增刪列表項(xiàng)元素征峦,如果一開始給每個(gè)子元素綁定事件迟几,那么在列表發(fā)生變化時(shí),就需要從新給新增的元素綁定事件栏笆,給即將刪去的元素解綁事件类腮,如果用事件委托就會(huì)省去很多這樣的麻煩。

接下來我們來實(shí)現(xiàn)上例中父元素#list下的li元素的事件委托到他的父層元素上:

// 給父層元素綁定事件
document.getElementById('list').addEventListener('click', function(e) {
    // 兼容性處理
    var event = e || window.event;
    var target = event.target || event.srcElement;
    // 判斷是否匹配目標(biāo)元素
    if (target.nodeName.toLocaleLowerCase === 'li') {
        console.log('the content is:', target.innerHTML);
    }
});

5.事件對(duì)象

DOM0DOM2的事件處理程序都會(huì)自動(dòng)傳入event對(duì)象蛉加,即觸發(fā)DOM上的某個(gè)事件時(shí)蚜枢,會(huì)產(chǎn)生一個(gè)事件對(duì)象,里面包含著所有和事件有關(guān)的信息七婴。IE中的event對(duì)象取決于指定的事件處理程序的方法祟偷。

IE的handler會(huì)在全局作用域運(yùn)行,this === window所以在IE中會(huì)有window.event打厘、event兩種情況修肠。

另外在IE中,事件對(duì)象的屬性也不一樣户盯,對(duì)應(yīng)關(guān)系如下:

srcElement => target returnValue => preventDefault() cancelBubble => stopPropagation() IE不支持事件捕獲嵌施,因而只能取消事件冒泡,但stopPropagtion可以同時(shí)取消事件捕獲和冒泡莽鸭。

只有在事件處理程序期間吗伤,event對(duì)象才會(huì)存在,一旦事件處理程序執(zhí)行完成硫眨,event對(duì)象就會(huì)被銷毀足淆。

1、event.preventDefault()

如果調(diào)用這個(gè)方法,默認(rèn)事件行為將不在觸發(fā)巧号。什么是默認(rèn)事件呢族奢?例如表單 - 點(diǎn)擊提交按鈕跳轉(zhuǎn)頁(yè)面、a標(biāo)簽?zāi)J(rèn)頁(yè)面跳轉(zhuǎn)或是錨點(diǎn)定位等丹鸿。

很多時(shí)候我們使用a標(biāo)簽僅僅是想當(dāng)做一個(gè)普通的按鈕越走,點(diǎn)擊實(shí)現(xiàn)一個(gè)功能,不想頁(yè)面跳轉(zhuǎn)靠欢,也不想錨點(diǎn)定位廊敌。

// 方法一
<a href="javascript:;">鏈接</a>

也可以通過JS方法來阻止,給其click事件綁定方法门怪,當(dāng)我們點(diǎn)擊A標(biāo)簽的時(shí)候骡澈,先觸發(fā)click事件,其次才會(huì)執(zhí)行自己的默認(rèn)行為

// 方法二
<a id="test" >鏈接</a>
<script>
    test.onclick = function(e) {
        e = e || window.event;
        return false;
    }
</script>

// 方法三
<a id="test" >鏈接</a>
<script>
    test.onclick = function(e) {
        e = e || window.event;
        e.preventDefalut();
    }
</script>

接下來我們看個(gè)例子:輸入框最多只能輸入六個(gè)字符掷空,如何實(shí)現(xiàn)秧廉?

// 例子5
<input type="text" id="tempInp">
<script>
    tempInp.onkeydown = function(ev) {
        ev = ev || window.event;
        let val = this.value.trim();
        let len = val.lenght;
        if (len >= 6) {
            this.value = val.substr(0, 6);
            //阻止默認(rèn)行為去除特殊按鍵(DELETE\BACK-SPACE\方向鍵...)
            let code = ev.which || ev.keyCode;
            if (!/^(46|8|37|38|39|40)$/.test(code)) {
                ev.preventDefault()
            }
        }
    }
</script>

2.event.stopPropagation() & event.stopImmediatePropagation()

event.stopPropagation()方法阻止事件冒泡到父元素,阻止任何父事件處理程序被執(zhí)行(一般我們認(rèn)為stopPropagation是用來阻止事件冒泡的拣帽,其實(shí)該函數(shù)也可以阻止捕獲事件)。上面提到事件冒泡階段是指事件從目標(biāo)節(jié)點(diǎn)紫霞而上的向window對(duì)象傳播的階段嚼锄。我們?cè)谏厦娴睦又械?code>inner元素click事件上减拭,添加event.stopPropagation()這句話后,就阻止了父事件的執(zhí)行区丑,最后只打印了'inner'拧粪。

inner.onclick = function(ev) {
    console.log('inner');
    ev.stopPropagation();
}

stopImmediatePropagation 既能阻止事件向父元素冒泡,也能阻止元素同事件類型的其它監(jiān)聽器被觸發(fā)沧侥。而 stopPropagation 只能實(shí)現(xiàn)前者的效果可霎。我們來看個(gè)例子:

<body>
  <button id="btn">click me to stop propagation</button>
</body>
<script>
    const btn = document.querySelector('#btn');
    btn.addEventListener('click', event => {
      console.log('btn click 1');
      event.stopImmediatePropagation();
    });
    btn.addEventListener('click', event => {
      console.log('btn click 2');
    });
    document.body.addEventListener('click', () => {
      console.log('body click');
    });
// btn click 1
</script>

如上所示,使用stopImmediatePropagation后宴杀,點(diǎn)擊按鈕時(shí)癣朗,不僅body綁定事件不會(huì)觸發(fā),與此同時(shí)按鈕的另一個(gè)點(diǎn)擊事件也不觸發(fā)旺罢。

event.target & event.currentTarget

event.target指向引起觸發(fā)事件的元素旷余,而event.currentTarget則是事件綁定的元素,只有被點(diǎn)擊的那個(gè)目標(biāo)元素的event.target才會(huì)等于event.currentTarget扁达。也就是說正卧,event.currentTarget始終是監(jiān)聽事件這,而event.target是事件的真正發(fā)出者跪解。

6.捕獲與冒泡的順序問題

當(dāng)有很多層交互嵌套時(shí)炉旷,事件捕獲和時(shí)間冒泡的先后順序看起來是不好確定的。下面分5種情況討論給它們的順序,以及如何規(guī)避意外情況的發(fā)生窘行。

1饥追、在外層div注冊(cè)事件,點(diǎn)擊內(nèi)層div來觸發(fā)事件時(shí)抽高,捕獲事件總是要比冒泡事件先觸發(fā)(與代碼順序無關(guān))

假設(shè)判耕,有這樣的html結(jié)構(gòu):

<div id="test" class="test">
    <div id="testInner" class="test-inner">
        
    </div>
</div>

然后,我們?cè)谕鈱觗iv上注冊(cè)兩個(gè)click事件翘骂,分別是捕獲事件和冒泡事件壁熄,代碼如下:

const btn = document.getElementById("test");

// 捕獲事件
btn.addEventListener("click", function(e) {
    alert("capture is ok");
}, true);

// 冒泡事件
btn.addEventListener("click", function(e) {
    alert("bubble is ok");
}, false)

點(diǎn)擊內(nèi)層的div,先彈出capture is ok碳竟,后彈出bubble is ok草丧。只有當(dāng)真正觸發(fā)事件的 DOM元素是內(nèi)層時(shí),外層DOM元素才有機(jī)會(huì)模擬捕獲事件和冒泡事件莹桅。

2昌执、當(dāng)在觸發(fā)事件的DOM元素上注冊(cè)事件時(shí),那個(gè)先注冊(cè)就先執(zhí)行那個(gè)

html 結(jié)構(gòu)同上诈泼,js代碼如下:

const btnInner = document.getElementById("testInner");

// 冒泡事件
btnInner.addEventListener("click", function(e) {
    alert("bubble is ok");
}, false);

// 捕獲事件
btnInner.addEventListener("click", function(e) {
    alert("caapture is ok");
}, true);

在本例中懂拾,冒泡事件先注冊(cè),所以先執(zhí)行铐达。所以岖赋,點(diǎn)擊內(nèi)層div,先彈出bubble is ok,再?gòu)棾?code>caputre is ok瓮孙。

3唐断、當(dāng)外層div和內(nèi)層div同時(shí)注冊(cè)了捕獲事件時(shí),點(diǎn)擊內(nèi)層的div時(shí),外層div的事件一定會(huì)先觸發(fā)

const btn = document.getElementById("test");
const btnInner = document.getElementById("testInner");

btnInner.addEventListener("click", function(e) {
    alert("inner capture is ok");
}, true);

btn.addEventListener("click", function(e) {
    alert("outer capture is ok");
}, true)

雖然外層 div 的事件注冊(cè)在后面,但會(huì)先觸發(fā)杭抠。所以脸甘,結(jié)果是先彈出 outer capture is ok,再?gòu)棾?inner capture is ok偏灿。

4丹诀、同理,當(dāng)外層div和內(nèi)層div都同時(shí)注冊(cè)了冒泡事件菩混,點(diǎn)擊內(nèi)層div時(shí)忿墅,一定是內(nèi)層div事件先觸發(fā)。

const btn = document.getElementById("test");
const btnInner = document.getElementById("testInner");

btn.addEventLisntener("click", function(e) {
    alert("outer bubble is ok");
}, false);

btnInner.addEventListener("click", function(e) {
    alert("inner bubble is ok");
}, false)

先彈出inner bubble is ok沮峡,再?gòu)棾?code>outer bubble is ok疚脐。

5、阻止事件的派發(fā)

通常情況下邢疙,我們都希望點(diǎn)擊某個(gè)div時(shí)棍弄,就觸發(fā)自己的事件回調(diào)望薄。比如,明明點(diǎn)擊的是內(nèi)層div呼畸,但是外層div的事件也觸發(fā)了痕支,這就不是我們想要的了。這時(shí)蛮原,就需要阻止事件的派發(fā)卧须。

事件觸發(fā)時(shí),會(huì)默認(rèn)傳入一個(gè)event對(duì)象儒陨,這個(gè)event對(duì)象上有一個(gè)方法:stopPropagation花嘶。MDN上的解釋是:阻止捕獲和冒泡階段中,當(dāng)前事件的進(jìn)一步傳播蹦漠。所以通過此方法椭员,讓外層div接收不到事件,自然也就不會(huì)觸發(fā)了笛园。

btnInner.addEventListener("click", function(e) {
    // 阻止冒泡
    e.stopPropagation();
    alert(”inner bubble is ok“);
}, false);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末隘击,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子研铆,更是在濱河造成了極大的恐慌埋同,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棵红,死亡現(xiàn)場(chǎng)離奇詭異莺禁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)窄赋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來楼熄,“玉大人忆绰,你說我怎么就攤上這事】善瘢” “怎么了错敢?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)缕粹。 經(jīng)常有香客問我稚茅,道長(zhǎng),這世上最難降的妖魔是什么平斩? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任亚享,我火速辦了婚禮,結(jié)果婚禮上绘面,老公的妹妹穿的比我還像新娘欺税。我一直安慰自己侈沪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布晚凿。 她就那樣靜靜地躺著亭罪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歼秽。 梳的紋絲不亂的頭發(fā)上应役,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音燥筷,去河邊找鬼箩祥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛荆责,可吹牛的內(nèi)容都是我干的滥比。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼做院,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼盲泛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起键耕,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤寺滚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后屈雄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體村视,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年酒奶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蚁孔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惋嚎,死狀恐怖杠氢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情另伍,我是刑警寧澤鼻百,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站摆尝,受9級(jí)特大地震影響温艇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜堕汞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一勺爱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讯检,春花似錦邻寿、人聲如沸蝎土。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)誊涯。三九已至,卻和暖如春蒜撮,著一層夾襖步出監(jiān)牢的瞬間暴构,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工段磨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留取逾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓苹支,卻偏偏與公主長(zhǎng)得像砾隅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子债蜜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

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