成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

瀏覽器事件模型中捕獲階段、目標(biāo)階段、冒泡階段實(shí)例詳解

mylxsw / 1550人閱讀

摘要:目標(biāo)階段真正點(diǎn)擊的元素的事件發(fā)生了兩次,因?yàn)樵谏厦娴拇a中,既在捕獲階段綁定了事件,又在冒泡階段綁定了事件,所以發(fā)生了兩次。所以很明顯用直接綁定的事件發(fā)生在了冒泡階段。

如果對(duì)事件大概了解,可能知道有事件冒泡這回事,但是冒泡、捕獲、傳播這些機(jī)制可能還沒有深入的研究實(shí)踐一下,我抽時(shí)間整理了一下相關(guān)的知識(shí)。

本文主要對(duì)事件機(jī)制一些細(xì)節(jié)進(jìn)行討論,過于基礎(chǔ)的事件綁定知識(shí)方法沒有介紹。

特別少的篇幅關(guān)注瀏覽器兼容問題,畢竟原理了解了,兼容性問題可以自己想辦法解決了。

在瀏覽器相對(duì)標(biāo)準(zhǔn)化之前,各個(gè)瀏覽器廠商都是自己實(shí)現(xiàn)的事件模型,有的用了冒泡,有的用了捕獲,W3C為了兼顧之前的標(biāo)準(zhǔn),將事件發(fā)生定義成如下三個(gè)階段:

1、捕獲階段
2、目標(biāo)階段
3、冒泡階段

只是硬生生的說事件機(jī)制到底是怎么回事不容易理解,用一個(gè)demo為主線說明事件的原理比較容易理解:

HTML


    
wrapDiv

innerP textSpan

CSS

JavaScript

demo頁面效果圖

這個(gè)時(shí)候,如果點(diǎn)擊一下textSpan這個(gè)元素,控制臺(tái)會(huì)打印出這樣的內(nèi)容:

當(dāng)按下鼠標(biāo)點(diǎn)擊后,到底發(fā)生了什么的,現(xiàn)在我基于上面的例子來說一下:

capture=>start: 捕獲階段開始
window=>operation: window
document=>operation: document
documentElement=>operation: documentElement
body=>operation: body
wrapDiv=>operation: wrapDiv
innerP=>operation: innerP
target=>start: 捕獲階段結(jié)束,目標(biāo)階段開始
textSpan=>operation: textSpan
textSpan2=>operation: textSpan
bubble=>start: 目標(biāo)階段結(jié)束,冒泡階段開始
innerP2=>operation: innerP
wrapDiv2=>operation: wrapDiv
body2=>operation: body
documentElement2=>operation: documentElement
document2=>operation: document
window2=>operation: window
bubbleend=>start: 冒泡階段結(jié)束
capture->window->document->documentElement->body->wrapDiv->innerP->target->textSpan->textSpan2->bubble->innerP2->wrapDiv2->body2->documentElement2->document2->window2->bubbleend

從上面所畫的事件傳播的過程能夠看出來,當(dāng)點(diǎn)擊鼠標(biāo)后,會(huì)先發(fā)生事件的捕獲

捕獲階段:首先window會(huì)獲捕獲到事件,之后documentdocumentElementbody會(huì)捕獲到,再之后就是在body中DOM元素一層一層的捕獲到事件,有wrapDiv、innerP。

目標(biāo)階段:真正點(diǎn)擊的元素textSpan的事件發(fā)生了兩次,因?yàn)樵谏厦娴腏avaScript代碼中,textSapn既在捕獲階段綁定了事件,又在冒泡階段綁定了事件,所以發(fā)生了兩次。但是這里有一點(diǎn)是需要注意,在目標(biāo)階段并不一定先發(fā)生在捕獲階段所綁定的事件,而是先綁定的事件發(fā)生,一會(huì)會(huì)解釋一下。

冒泡階段:會(huì)和捕獲階段相反的步驟將事件一步一步的冒泡到window

那可能有一個(gè)疑問,我們不用addEventListener綁定的事件會(huì)發(fā)生在哪個(gè)階段呢,我們來一個(gè)測(cè)試,順便再演示一下我在上面的目標(biāo)階段所說的目標(biāo)階段并不一定先發(fā)生捕獲階段所綁定的事件是怎么一回事。
我們重新改一下JavaScript代碼:

再看控制臺(tái)的結(jié)果:

圖中第一個(gè)被圈出來的解釋:textSpan是被點(diǎn)擊的元素,也就是目標(biāo)元素,所有在textSpan上綁定的事件都會(huì)發(fā)生在目標(biāo)階段,在綁定捕獲代碼之前寫了綁定的冒泡階段的代碼,所以在目標(biāo)元素上就不會(huì)遵守先發(fā)生捕獲后發(fā)生冒泡這一規(guī)則,而是先綁定的事件先發(fā)生。

圖中第二個(gè)被圈出來的解釋:由于wrapDiv不是目標(biāo)元素,所以它上面綁定的事件會(huì)遵守先發(fā)生捕獲后發(fā)生冒泡的規(guī)則。所以很明顯用onclick直接綁定的事件發(fā)生在了冒泡階段。

target和currentTarget

上面的代碼中寫了e.targete.currentTarget,還沒有說是什么,targetcurrentTarget都是event上面的屬性,target是真正發(fā)生事件的DOM元素,而currentTarget是當(dāng)前事件發(fā)生在哪個(gè)DOM元素上。
可以結(jié)合控制臺(tái)打印出來的信息理解下,目標(biāo)階段也就是 target == currentTarget的時(shí)候。我沒有打印它們兩個(gè)因?yàn)樘L(zhǎng)了,所以打印了它們的nodeName,但是由于window沒有nodeName這個(gè)屬性,所以是undefined。

阻止事件傳播

說到事件,一定要說的是如何阻止事件傳播??偸怯泻芏嗵诱fe.stopPropagation()是阻止事件的冒泡的傳播,實(shí)際上這么說并不是很準(zhǔn)確,因?yàn)樗粌H可以阻止事件在冒泡階段的傳播,還能阻止事件在捕獲階段的傳播。
來看一下我們?cè)俑囊幌碌腏avaScript代碼:

我們?cè)谑录牟东@階段阻止了傳播,看一下控制臺(tái)的結(jié)果:

實(shí)際上我們點(diǎn)擊的是textSpan,但是由于在捕獲階段事件就被阻止了傳播,所以在textSpan上綁定的事件根本就沒有發(fā)生,冒泡階段綁定的事件自然也不會(huì)發(fā)生,因?yàn)樽柚故录诓东@階段傳播的特性,e.stopPropagation()很少用到在捕獲階段去阻止事件的傳播,大家就以為e.stopPropagation()只能阻止事件在冒泡階段傳播。

阻止事件的默認(rèn)行為

e.preventDefault()可以阻止事件的默認(rèn)行為發(fā)生,默認(rèn)行為是指:點(diǎn)擊a標(biāo)簽就轉(zhuǎn)跳到其他頁面、拖拽一個(gè)圖片到瀏覽器會(huì)自動(dòng)打開、點(diǎn)擊表單的提交按鈕會(huì)提交表單等等,因?yàn)橛械臅r(shí)候我們并不希望發(fā)生這些事情,所以需要阻止默認(rèn)行為,這塊的知識(shí)比較簡(jiǎn)單,可以自己去試一下。

與事件相關(guān)的兼容性問題

這里只是簡(jiǎn)單提一下兼容性問題,不做過多的展開。對(duì)于綁定事件,ie低版本的瀏覽器是用attachEvent,而高版本ie和標(biāo)準(zhǔn)瀏覽器用的是addEventListener,attachEvent不能指定綁定事件發(fā)生在捕獲階段還是冒泡階段,它只能將事件綁定到冒泡階段,但是并不意味這低版本的ie沒有事件捕獲,它也是先發(fā)生事件捕獲,再發(fā)生事件冒泡,只不過這個(gè)過程無法通過程序控制。

其實(shí)事件的兼容性問題特別的多,比如獲取事件對(duì)象的方式、綁定和解除綁定事件的方式、目標(biāo)元素的獲取方式等等,由于古老的瀏覽器終究會(huì)被淘汰,不過多展開了。

歡迎關(guān)注【本期節(jié)目】,微信公眾號(hào)ID:benqijiemu。
這里有:互聯(lián)網(wǎng)思考、軟件&工具推薦、前端技術(shù)等。
可以在公眾號(hào)回復(fù)我,希望和大家一起交流所有與互聯(lián)網(wǎng)相關(guān)的事情~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85903.html

相關(guān)文章

  • 詳解JS事件 - 事件模型/事件流/事件代理/事件對(duì)象/自定義事件

    摘要:取消事件的默認(rèn)行為。阻止事件的派發(fā)包括了捕獲和冒泡阻止同一個(gè)事件的其他監(jiān)聽函數(shù)被調(diào)用。 事件模型 DOM0 級(jí)事件模型 -沒有事件流,這種方式兼容所有瀏覽器 // 方式一 將事件直接通過屬性綁定在元素上 / 方式二 獲取到頁面元素后,通過 onclick 等事件,將觸發(fā)的方法指定為元素的事件 var btn = document.getElementById(btn) btn....

    URLOS 評(píng)論0 收藏0
  • JavaScript系列之事件詳解

    摘要:響應(yīng)某個(gè)事件的函數(shù)就叫事件處理程序或事件偵聽器。為事件指定事件處理程序的方法主要有種。事件處理程序事件直接加在元素上。事件委托利用冒泡的原理,把事件加到父元素或祖先元素上,觸發(fā)執(zhí)行效果,解決事件處理程序過多問題。事件委托優(yōu)點(diǎn)提高性能。 JavaScript簡(jiǎn)單入門可以看看我丑丑的Github博客JavaScript簡(jiǎn)單入門 事件 JavaScript與HTML之間的交互是通過事件實(shí)現(xiàn)的...

    pakolagij 評(píng)論0 收藏0
  • JavaScript學(xué)習(xí)總結(jié)(九)事件詳解

    摘要:布爾值表示捕獲階段調(diào)用事件處理程序,表示冒泡階段通過對(duì)象的方法,也可以定義事件的回調(diào)函數(shù)。對(duì)象會(huì)被作為第一個(gè)參數(shù)傳遞給事件監(jiān)聽的回調(diào)函數(shù)。布爾默認(rèn)值是,當(dāng)設(shè)置成時(shí)用以取消事件的默認(rèn)行為與中的相同。 其實(shí)這篇文章挺早之前就寫了,但是由于sf保存方面的bug,所以當(dāng)時(shí)寫了一大堆,結(jié)果沒保存,覺得這個(gè)沒寫完是個(gè)不小的遺憾,今天正好有空,就給補(bǔ)充下了,也正好給我的javascript學(xué)習(xí)總結(jié)做...

    LiveVideoStack 評(píng)論0 收藏0
  • DOM 事件詳解

    摘要:與此同時(shí),我們獲得了回調(diào)函數(shù)的句柄,從而可以隨時(shí)從元素上移除相應(yīng)的事件監(jiān)聽。對(duì)象會(huì)被作為第一個(gè)參數(shù)傳遞給事件監(jiān)聽的回調(diào)函數(shù)。 Click、touch、load、drag、change、input、error、risize — 這些都是冗長(zhǎng)的DOM(文檔對(duì)象模型)事件列表的一部分。事件可以在文檔(Document)結(jié)構(gòu)的任何部分被觸發(fā),觸發(fā)者可以是用戶操作,也可以是瀏覽器本身。事件并不是...

    tianhang 評(píng)論0 收藏0
  • DOM事件機(jī)制

    摘要:而事件分為個(gè)級(jí)別級(jí)事件處理,級(jí)事件處理和級(jí)事件處理。一個(gè)事件發(fā)生后,會(huì)在子元素和父元素之間傳播。也就是說,始終是監(jiān)聽事件者,而是事件的真正發(fā)出者。五參考文章級(jí)別與事件事件機(jī)制解惑事件模型事件委托詳解事件的學(xué)與記和和的區(qū)別 前言 本文主要介紹DOM事件級(jí)別、DOM事件模型、事件流、事件代理和Event對(duì)象常見的應(yīng)用,希望對(duì)你們有些幫助和啟發(fā)! 本文首發(fā)地址為GitHub博客,寫文章不易,...

    laznrbfe 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<