如何阻止事件冒泡和默認事件?

這個問題也是老生常談了,寫這篇文章的主要目的是進行下梳理,了解自己知識點的掌握程度,也希望對大家有所幫助。

在說如何阻止事件冒泡和默認事件之前先來說說什么是事件冒泡和默認事件(行為)?

事件冒泡:

在一個對象上觸發(fā)某類事件(比如點擊事件),如果此對象定義了此事件的處理程序,那么此事件就會調(diào)用這個處理程序,如果沒有定義此事件處理程序或者事件返回true,那么這個事件會向這個對象的父級對象傳播,從里到外,直至它被處理(父級對象所有同類事件都將被激活),或者它到達了對象層次的最頂層,即document對象(有些瀏覽器是window)。

IE5冒泡會到document終止,IE6的話在冒泡到document之前還會冒泡到html,Mozilla1.0及更高版本則會冒泡到window終止。

Netscape4.0使用了另一種稱為捕獲型事件(eventcapturing)的解決方案、事件的捕獲和冒泡剛好相反的兩種過程——捕獲型事件中,事件從最不精確的對象(document對象)開始觸發(fā),然后到最精確(也可以在窗口級別捕獲事件,不過必須由開發(fā)人員特別指定)。Netscape4.0不會將頁面上的很多元素暴露給事件。

DOM事件流:

DOM(文檔對象模型)結(jié)構(gòu)是一個樹型結(jié)構(gòu),當一個HTML元素產(chǎn)生一個事件時,該事件會在元素結(jié)點與根節(jié)點之間按特定的順序傳播,路徑所經(jīng)過的節(jié)點都會收到該事件,這個傳播過程可稱為DOM事件流。事件順序有兩種類型:事件捕捉和事件冒泡。

一個標準的DOM事件模型:

DOM標準同時支持兩種事件模型,即捕獲型事件與冒泡型事件,但是,捕獲型事件先發(fā)生。兩種事件流都會觸發(fā)DOM中的所有對象,從document對象開始,也在document對象結(jié)束(大部分兼容標準的瀏覽器會繼續(xù)將事件是捕捉/冒泡延續(xù)到window對象)。在與DOM兼容的瀏覽器中點擊

元素時,事件流的進行如下圖:

注意因為事件的目標(

元素)是最精確的元素(于是,在DOM樹中最深),實際上它會接收兩次事件,一次在捕獲過程中,另一次在冒泡過程中。DOM事件模型的最獨特的性質(zhì)是,文本節(jié)點也觸發(fā)事件(在IE不會)。所以如果點擊示例中的
,實際的事件流應(yīng)該是:

要注意的問題:

1)focus、blur和scroll事件不會冒泡。文檔元素上的load事件會冒泡,但它會在document對象上停止冒泡而不會傳播到window對象。只有當整個文檔都加載完畢時才會觸發(fā)window對象的load事件。

2)阻止冒泡并不會阻止默認行為,比如submit按鈕被點擊后會提交表單數(shù)據(jù)。

什么情況下我們需要阻止冒泡事件呢?

比如現(xiàn)在有三個div盒子層層嵌套,我們需要點擊不同的div盒子時執(zhí)行各自的點擊事件。demo代碼如下:

HTML:

JS:

var lg = document.getElementById("lg");

var md = document.getElementById("md");

var sm = document.getElementById("sm");

lg.onclick = function()?{

alert("我是最外層的盒子lg");

};

md.onclick = function()?{

alert("我是中間的盒子md");

};

sm.onclick = function()?{

alert("我是最里面的盒子sm");

};

demo鏈接

當我們點擊最里面的盒子sm的時候,瀏覽器會依次彈出"我是最里面的盒子sm","我是中間的盒子md","我是最外層的盒子lg"。并不是我們所期望的那樣點擊當前的盒子只執(zhí)行當前盒子的點擊事件。這正是因為事件冒泡的原因而導致的結(jié)果,這個時候我們就需要阻止事件冒泡。

如何阻止事件冒泡?

方法一:

使用stopPropagation()方法,使用event對象調(diào)用即可,但是該方法不支持IE9以下的瀏覽器,上述例子代碼修改后如下:

var lg = document.getElementById("lg");

var md = document.getElementById("md");

var sm = document.getElementById("sm");

lg.onclick = function()?{

alert("我是最外層的盒子lg");

};

md.onclick = function()?{

alert("我是中間的盒子md");

event.stopPropagation();

};

sm.onclick = function()?{

alert("我是最里面的盒子sm");

event.stopPropagation();

};

IE8以下的瀏覽器的IE事件對象有一個cancelBubble屬性,設(shè)置這個屬性為true,則可以阻止事件冒泡。

我們可以將阻止事件冒泡封裝成一個函數(shù),代碼如下:

//document.all 用于判斷是否IE瀏覽器

//IE:cancelBubble

//Firefox: stopPropagation

function stopEventBubbling(event)?{

var e = window.event || event;

if(document.all)?{

e.cancelBubble = true;

}

else {

e.stopPropagation();

}

}

方法二:

JQ提供兩種方法,第一種是stopPropagation(),使用時直接用event調(diào)用即可。

第二種是return false,代碼如下:

$("#sm").click(function()?{

alert("我是最里面的盒子sm");

return false;

});

這兩種方法是有區(qū)別的。return false不僅阻止了事件冒泡,還阻止了事件本身。stopPropagation()方法只會阻止事件冒泡,不會阻止事件本身。

默認事件:

瀏覽器的一些默認的行為。例如:點擊超鏈接跳轉(zhuǎn),點擊鼠標右鍵會彈出菜單,滑動滾輪控制滾動條……

如何阻止默認事件?

可以使用preventDefault()方法,直接使用event對象調(diào)用即可,但是該方法不支持IE9以下的瀏覽器,IE事件對象有一個屬性returnValue,默認是true,當將其設(shè)置為false時,則可以取消事件默認行為,同樣使用event對象調(diào)用。

我們可以將取消默認行為的方法封裝成一個函數(shù),代碼如下:

function cancelHandler(event)?{

var e = window.event || event;

if(document.all)?{

e.returnValue = false;

}

else {

e.preventDefault();

}

}

參考文獻:

《JavaScript權(quán)威指南》

如果你在本文中發(fā)現(xiàn)錯誤或者有異議的地方,可以在評論區(qū)留言,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

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