JS 事件(2)

1哈误、事件傳播機(jī)制暖眼、阻止傳播惕耕、取消默認(rèn)事件、事件代理這些到底是什么呢诫肠?

①事件傳播機(jī)制:
JS事件傳播包括三個(gè)階段:

  • 捕獲階段:簡(jiǎn)單來(lái)說(shuō)就是從最頂層元素司澎,逐漸進(jìn)入dom內(nèi)部欺缘,查找目標(biāo)元素的過(guò)程。過(guò)程中依次執(zhí)行各個(gè)元素綁定在捕獲階段的事件(不包括目標(biāo)元素上的事件)

  • 處于目標(biāo)階段:到達(dá)目標(biāo)元素挤安,按事件注冊(cè)順序執(zhí)行綁定在目標(biāo)元素上的事件

  • 冒泡階段:從目標(biāo)元素谚殊,依次像外層元素冒泡,最后到達(dá)頂層元素的過(guò)程蛤铜。依次執(zhí)行各個(gè)元素綁定在冒泡階段的事件(不包括目標(biāo)元素上的事件)

②阻止傳播:即阻止事件進(jìn)一步的捕獲或者冒泡嫩絮,使事件不在向后傳播∥Х剩可以使用事件對(duì)象e(e的介紹在我的博客JS DOM(2)的第6點(diǎn)中已經(jīng)介紹)的stopPropagation()設(shè)置在事件的相應(yīng)階段剿干。
舉個(gè)列子:列子代碼地址
列子中嵌套了3個(gè)div(div#outer =》 div#middle =》div#inner)。給每個(gè)div都綁定了捕獲階段和冒泡階段的事件穆刻。
(1)首先測(cè)試捕獲階段設(shè)置阻止事件傳播怨愤。把div#middle的捕獲階段的代碼改成如下:

middle.addEventListener("click", function(e){
  e.stopPropagation();
  console.log("middle捕獲");
}, true);

點(diǎn)擊div#inner,出現(xiàn)如下結(jié)果蛹批,可見(jiàn)div#middle的捕獲階段后面的事件都不執(zhí)行了,事件被阻止傳播了

"outer捕獲"
"middle捕獲"

(2)接著測(cè)試在處于目標(biāo)階段設(shè)置阻止事件傳播篮愉。在div#inner的冒泡階段事件中設(shè)置阻止事件傳播(目標(biāo)元素的事件執(zhí)行是按照注冊(cè)順序執(zhí)行腐芍,和冒泡捕獲無(wú)關(guān),我的div#inner的冒泡事件是設(shè)置在捕獲事件的前面的试躏,正常不阻止事件傳播的話猪勇,會(huì)先輸出"inner冒泡",在輸出"inner捕獲"

inner.addEventListener("click", function(e){
  e.stopPropagation();
  console.log("inner冒泡");
}, false);

點(diǎn)擊div#inner颠蕴,結(jié)果如下:☆此時(shí)尤其需要注意☆泣刹,處于目標(biāo)階段的所有事件都會(huì)被執(zhí)行完

"outer捕獲"
"middle捕獲"
"inner冒泡"
"inner捕獲"

(3)最后測(cè)試冒泡階段設(shè)置阻止事件傳播。在div#middle的冒泡階段設(shè)置阻止事件傳播

middle.addEventListener("click", function(e){
  e.stopPropagation();
  console.log("middle冒泡");
}, false);

點(diǎn)擊div#inner犀被,結(jié)果如下:可見(jiàn)div#middle的冒泡階段后面的事件都不執(zhí)行了椅您,事件被阻止傳播了

"outer捕獲"
"middle捕獲"
"inner冒泡"
"inner捕獲"
"middle冒泡"

③取消默認(rèn)事件:
對(duì)于一些元素是有默認(rèn)事件的,比如點(diǎn)擊a鏈接可以實(shí)現(xiàn)跳轉(zhuǎn)寡键。又比如表單中掀泳,點(diǎn)擊input類型為submit的按鈕會(huì)默認(rèn)提交表單。
那么如何取消這些默認(rèn)事件呢西轩?
事件對(duì)象e中有個(gè)preventDefault()方法员舵,給這些具有默認(rèn)事件的元素重新綁定事件,并且在里面設(shè)置e.preventDefault()就可以取消默認(rèn)事件了
還是以代碼為例:

<a >baidu</a>
<script>
document.querySelector('a').onclick = function(e){
  e.preventDefault()
  console.log(this.href)
  if(/baidu.com/.test(this.href)){
    location.href = this.href
  }
}
</script>
<form action="/login">
  <input type="text" name="username" placeholder="login">
  <input type="submit" value="login">
</form>
<script>
document.querySelector('form').addEventListener('submit', function(e){
  e.preventDefault()
  if(document.querySelector('input[name=username]').value === 'login'){
    this.submit()
  }
})
</script>

④事件代理:
事件代理是利用事件的冒泡原理來(lái)實(shí)現(xiàn)的藕畔。當(dāng)我們需要對(duì)很多元素添加事件的時(shí)候马僻,可以為每個(gè)元素都綁定事件。也可以給他們的父節(jié)點(diǎn)綁定事件注服。因?yàn)槭录芭菥碌耍?dāng)點(diǎn)擊子節(jié)點(diǎn)的時(shí)候措近,事件會(huì)冒泡傳播到父節(jié)點(diǎn),觸發(fā)設(shè)置在父節(jié)點(diǎn)上的事件仍秤。這就是事件代理熄诡,委托它們父級(jí)代為執(zhí)行事件。
為什么要用事件代理?
假設(shè)有100個(gè)li诗力,每個(gè)li都有相同的click點(diǎn)擊事件凰浮,如果用for循環(huán)的方法,來(lái)遍歷所有的li苇本,然后給它們添加事件袜茧,需要添加100事件。每個(gè)函數(shù)都是一個(gè)對(duì)象瓣窄,是對(duì)象就會(huì)占用內(nèi)存笛厦,對(duì)象越多,內(nèi)存占用率就越大俺夕,自然性能就越差了裳凸。而且每次增加或刪除具有相同事件的li都需要重新綁定或者解除事件。
如果用事件委托劝贸,那么我們就可以只對(duì)它的父級(jí)(如果只有一個(gè)父級(jí))這一個(gè)對(duì)象進(jìn)行操作姨谷,這樣我們就需要一個(gè)內(nèi)存空間就夠了,是不是省了很多映九,自然性能就會(huì)更好梦湘。而且每次增加或刪除需要有相同事件的li不需要做額外操作。
那么如何在父節(jié)點(diǎn)的事件中獲取到具體點(diǎn)擊的是哪個(gè)子節(jié)點(diǎn)呢件甥?
Event對(duì)象提供了一個(gè)屬性叫target捌议,e.target可以返回事件的目標(biāo)節(jié)點(diǎn)。e.target.nodeName可以獲取具體是什么標(biāo)簽名引有,這個(gè)返回的是大寫(xiě)的(比如"LI")
以下代碼事例加深理解
事例實(shí)現(xiàn)了:

  • 當(dāng)點(diǎn)擊按鈕開(kāi)頭添加時(shí)在<li>這里是</li>元素前添加一個(gè)新元素瓣颅,內(nèi)容為用戶輸入的非空字符串;當(dāng)點(diǎn)擊結(jié)尾添加時(shí)在最后一個(gè) li 元素后添加用戶輸入的非空字符串.
  • 當(dāng)點(diǎn)擊每一個(gè)元素li時(shí)控制臺(tái)展示該元素的文本內(nèi)容譬正。

代碼地址
事例中點(diǎn)擊每一個(gè)元素li時(shí)控制臺(tái)展示該元素的文本內(nèi)容就是通過(guò)事件代理實(shí)現(xiàn)的弄捕,無(wú)論增加或刪除li都不需要再做額外的事件綁定或解除

實(shí)現(xiàn)如下頁(yè)面

音樂(lè)網(wǎng)站登錄頁(yè)面
自己的實(shí)現(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市导帝,隨后出現(xiàn)的幾起案子守谓,更是在濱河造成了極大的恐慌,老刑警劉巖您单,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斋荞,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡虐秦,警方通過(guò)查閱死者的電腦和手機(jī)平酿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門凤优,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蜈彼,你說(shuō)我怎么就攤上這事筑辨。” “怎么了幸逆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵棍辕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我还绘,道長(zhǎng)楚昭,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任拍顷,我火速辦了婚禮抚太,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘昔案。我一直安慰自己尿贫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布踏揣。 她就那樣靜靜地躺著庆亡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪呼伸。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,245評(píng)論 1 299
  • 那天钝尸,我揣著相機(jī)與錄音括享,去河邊找鬼。 笑死珍促,一個(gè)胖子當(dāng)著我的面吹牛铃辖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猪叙,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼娇斩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了穴翩?” 一聲冷哼從身側(cè)響起犬第,我...
    開(kāi)封第一講書(shū)人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芒帕,沒(méi)想到半個(gè)月后歉嗓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡背蟆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年鉴分,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哮幢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡志珍,死狀恐怖橙垢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情伦糯,我是刑警寧澤柜某,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站舔株,受9級(jí)特大地震影響莺琳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜载慈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一惭等、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧办铡,春花似錦辞做、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至童叠,卻和暖如春框喳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背厦坛。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工五垮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人杜秸。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓放仗,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親撬碟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诞挨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

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

  • 1、寫(xiě)一個(gè)函數(shù)呢蛤,批量操作 css 2惶傻、如何獲取 DOM 計(jì)算后的樣式 設(shè)置div的background為pink ...
    海山城閱讀 273評(píng)論 0 0
  • (續(xù)jQuery基礎(chǔ)(1)) 第5章 DOM節(jié)點(diǎn)的復(fù)制與替換 (1)DOM拷貝clone() 克隆節(jié)點(diǎn)是DOM的常...
    凜0_0閱讀 1,338評(píng)論 0 8
  • DOM操作 children 子節(jié)點(diǎn) 兒子節(jié)點(diǎn) parentNode 父節(jié)點(diǎn) 谷歌和火狐的方式 firs...
    Kris_Shin閱讀 164評(píng)論 0 3
  • 事件處理程序的本質(zhì):事件與相關(guān)DOM元素的交互。 事件代理:將多個(gè)子元素的DOM操作優(yōu)為化對(duì)父元素的一次DOM操作...
    余生筑閱讀 290評(píng)論 0 0
  • 1. 事件冒泡與事件捕獲 事件冒泡和事件捕獲分別由微軟和網(wǎng)景公司提出其障,這兩個(gè)概念都是為了解決頁(yè)面中事件流(事件發(fā)生...
    cbw100閱讀 2,696評(píng)論 0 8