Js 冒泡事件阻止實(shí)現(xiàn)代碼
1. 事件目標(biāo)
現(xiàn)在,事件處理程序中的變量event保存著事件對象。而event.target屬性保存著發(fā)生事件的目標(biāo)元素。這個(gè)屬性是DOM API中規(guī)定的,但是沒有被所有瀏覽器實(shí)現(xiàn) 。jQuery對這個(gè)事件對象進(jìn)行了必要的擴(kuò)展,從而在任何瀏覽器中都能夠使用這個(gè)屬性。通過.target,可以確定DOM中首先接收到事件的元素(即實(shí)際被單擊的元素)。而且,我們知道this引用的是處理事件的DOM元素,所以可以編寫下列代碼:
$(document).ready(function(){
$('#switcher').click(function(event){
$('#switcher .button').toggleClass('hidden');
})
})
$(document).ready(function(){
$('#switcher').click(function(event){
if(event.target==this){
$('#switcher .button').toggleClass('hidden');
}
})
})
此時(shí)的代碼確保了被單擊的元素是<div id="switcher"> ,而不是其他后代元素?,F(xiàn)在,單擊按鈕不會再折疊樣式轉(zhuǎn)換器,而單擊邊框則會觸發(fā)折疊操作。但是,單擊標(biāo)簽同樣什么也不會發(fā)生,因?yàn)樗彩且粋€(gè)后代元素。實(shí)際上,我們可以不把檢查代碼放在這里,而是通過修改按鈕的行為來達(dá)到目標(biāo) 。
2. 停止事件傳播
事件對象還提供了一個(gè).stopPropagation()方法,該方法可以完全阻止事件冒泡。與.target類似,這個(gè)方法也是一種純JavaScript特性,但在跨瀏覽器的環(huán)境中則無法安全地使用 。不過,只要我們通過jQuery來注冊所有的事件處理程序,就可以放心地使用這個(gè)方法。
下面,我們會刪除剛才添加的檢查語句event.target == this,并在按鈕的單擊處理程序中添加一些代碼:
$(document).ready(function(){
$('#switcher .button').click(funtion(event){
//……
event.stopPropagation();
})
})
同以前一樣,需要為用作單擊處理程序的函數(shù)添加一個(gè)參數(shù),以便訪問事件對象。然后,通過簡單地調(diào)用event.stopPropagation()就可以避免其他所有DOM元素響應(yīng)這個(gè)事件。這樣一來,單擊按鈕的事件會被按鈕處理,而且只會被按鈕處理。單擊樣式轉(zhuǎn)換器的其他地方則可以折疊和擴(kuò)展整個(gè)區(qū)域。
3. 默認(rèn)操作
如果我們把單擊事件處理程序注冊到一個(gè)錨元素,而不是一個(gè)外層的<div>上,那么就要面對另外一個(gè)問題:當(dāng)用戶單擊鏈接時(shí),瀏覽器會加載一個(gè)新頁面。這種行為與我們討論的事件處理程序不是同一個(gè)概念,它是單擊錨元素的默認(rèn)操作。類似地,當(dāng)用戶在編輯完表單后按下回車鍵時(shí),會觸發(fā)表單的submit事件,在此事件發(fā)生后,表單提交才會真正發(fā)生。
如果我們不希望執(zhí)行這種默認(rèn)操作,那么在事件對象上調(diào)用.stopPropagation()方法也無濟(jì)于事,因?yàn)槟J(rèn)操作不是在正常的事件傳播流中發(fā)生的。在這種情況下,.preventDefault()方法則可以在觸發(fā)默認(rèn)操作之前終止事件 。
提示 當(dāng)在事件的環(huán)境中完成了某些驗(yàn)證之后,通常會用到.preventDefault()。例如,在表單提交期間,我們會對用戶是否填寫了必填字段進(jìn)行檢查,如果用戶沒有填寫相應(yīng)字段,那么就需要阻止默認(rèn)操作。我們將在第8章詳細(xì)討論表單驗(yàn)證。
事件傳播和默認(rèn)操作是相互獨(dú)立的兩套機(jī)制,在二者任何一方發(fā)生時(shí),都可以終止另一方。如果想要同時(shí)停止事件傳播和默認(rèn)操作,可以在事件處理程序中返回false,這是對在事件對象上同時(shí)調(diào)用.stopPropagation()和.preventDefault()的一種簡寫方式。
補(bǔ)充:
//單擊按鈕事件(改變文字樣式)
$(document).ready(function() {
$('#switcher .button').click(function() {
$('body').removeClass();
if (this.id == 'switcher-narrow') {
$('body').addClass('narrow');
}
else if (this.id == 'switcher-large') {
$('body').addClass('large');
}
$('#switcher .button').removeClass('selected');
$(this).addClass('selected');
});
});
//單擊按鈕外層div出發(fā)事件(隱藏按鈕)
$(document).ready(function() {
$('#switcher').click(function() {
$('#switcher .button').toggleClass('hidden');
});
});
現(xiàn)在的問題是,當(dāng)點(diǎn)擊了按鈕時(shí),同時(shí)觸發(fā)了隱藏按鈕事件。這是事件冒泡導(dǎo)致。
為了阻止事件冒泡,需要為隱藏按鈕函數(shù)添加一個(gè)參數(shù):
$(document).ready(function() {
$('#switcher').click(function(even) {
if(even.target==this){
$('#switcher .button').toggleClass('hidden');
}
});
});
even保存事件對象,even.target屬性保存發(fā)生事件的目標(biāo)元素??梢源_定DOM中首先接收到事件的元素。此時(shí)代碼確保了被單擊的是<div id="switcher">,而不是其后代元素。
也可以這樣處理,通過修改按鈕的行為來達(dá)到目的。
$(document).ready(function() {
$('#switcher .button').click(function(even) {
$('body').removeClass();
if (this.id == 'switcher-narrow') {
$('body').addClass('narrow');
}
else if (this.id == 'switcher-large') {
$('body').addClass('large');
}
$('#switcher .button').removeClass('selected');
$(this).addClass('selected');
even.stopPropagation();
});
});
用JS阻止事件冒泡
事件冒泡: 當(dāng)一個(gè)元素上的事件被觸發(fā)的時(shí)候,比如說鼠標(biāo)點(diǎn)擊了一個(gè)按鈕,同樣的事件將會在那個(gè)元素的所有祖先元素中被觸發(fā)。這一過程被稱為事件冒泡;這個(gè)事件從原始元素開始一直冒泡到DOM樹的最上層。
可以用JS來阻止js事件冒泡。因?yàn)闉g覽器的差異IE和FF的JS寫法有點(diǎn)不一樣。
IE用cancelBubble=true來阻止而FF下需要用stopPropagation方法。
下一下完整的代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>無標(biāo)題文檔</title>
<script type="text/javascript">
function aaaclick(){
alert("td click");
}
function bbbclick(evt){
alert("td click");
if (window.event) {
event.cancelBubble = true;
}else if (evt){
evt.stopPropagation();
}
}
function trclick(){
alert("tr click");
}
function tableclick(){
alert("table click");
}
</script>
<style type="text/css">
<!--
.tab {
border: 1px solid #0066FF;
cellpadding:0px;
cellspacing:0px;
}
.tab td{
border: 1px solid #0066FF;
}
-->
</style>
</head>
<body>
<p>點(diǎn)擊aaaa會觸發(fā)上層的onclick事件,點(diǎn)擊bbbb不會觸發(fā)上層onclick事件</p>
<table width="204" onclick="tableclick()" class="tab">
<tr >
<td width="96"> </td>
<td width="96"> </td>
</tr>
<tr onclick="trclick()">
<td onclick="aaaclick()">aaaa</td>
<td onclick="bbbclick(event)">bbbbb</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
</table>
</body>
</html>
- 阻止JavaScript事件冒泡傳遞(cancelBubble 、stopPropagation)
- js阻止默認(rèn)事件與js阻止事件冒泡示例分享 js阻止冒泡事件
- javascript事件冒泡詳解和捕獲、阻止方法
- js冒泡、捕獲事件及阻止冒泡方法詳細(xì)總結(jié)
- js阻止冒泡及jquery阻止事件冒泡示例介紹
- zepto.js中tap事件阻止冒泡的實(shí)現(xiàn)方法
- javascript阻止scroll事件多次執(zhí)行的思路及實(shí)現(xiàn)
- JS阻止冒泡事件以及默認(rèn)事件發(fā)生的簡單方法
- javascript阻止瀏覽器后退事件防止誤操作清空表單
- JavaScript實(shí)現(xiàn)事件的中斷傳播和行為阻止方法示例
相關(guān)文章
JavaScript實(shí)現(xiàn)父子dom同時(shí)綁定兩個(gè)點(diǎn)擊事件,一個(gè)用捕獲,一個(gè)用冒泡時(shí)執(zhí)行順序的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)父子dom同時(shí)綁定兩個(gè)點(diǎn)擊事件,一個(gè)用捕獲,一個(gè)用冒泡時(shí)執(zhí)行順序的方法,涉及javascript事件的觸發(fā)與執(zhí)行原理及相關(guān)操作技巧,需要的朋友可以參考下2017-03-03淺析javascript中函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別
這篇文章主要介紹了淺析javascript中函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別,需要的朋友可以參考下2015-02-02強(qiáng)悍無比的WEB開發(fā)好助手FireBug(Firefox Plugin)
強(qiáng)悍無比的WEB開發(fā)好助手FireBug(Firefox Plugin)...2007-01-01JavaScript懶加載與預(yù)加載原理與實(shí)現(xiàn)詳解
這篇文章主要介紹了JavaScript懶加載與預(yù)加載,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09JavaScript Event學(xué)習(xí)第五章 高級事件注冊模型
在這一章我會講解兩種高級時(shí)間注冊模型:W3C和微軟的。因?yàn)檫@兩個(gè)方法都不能跨瀏覽器,所以在現(xiàn)在看來他們的使用場合并不多。2010-02-02Bootstrap 下拉多選框插件Bootstrap Multiselect
這篇文章主要介紹了Bootstrap 下拉多選框插件Bootstrap Multiselect,引入文件及使用方法講解,需要的朋友參考下吧2017-01-01javascript運(yùn)算符——邏輯運(yùn)算符全面解析
下面小編就為大家?guī)硪黄猨avascript運(yùn)算符——邏輯運(yùn)算符詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-06-06nodejs創(chuàng)建web服務(wù)器之hello world程序
本文給大家分享nodejs創(chuàng)建web服務(wù)器之hello world程序,node真的很好用,不僅用v8引擎來解析了javascript外,還提供了高度優(yōu)化的應(yīng)用庫,真的很好,有需要的朋友一起來學(xué)習(xí)吧2015-08-08JavaScript實(shí)現(xiàn)一個(gè)輸入框組件
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)一個(gè)輸入框組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09