<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識(shí)百科 - 正文

        javascript事件冒泡詳解和捕獲、阻止方法_javascript技巧

        來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 21:21:53
        文檔

        javascript事件冒泡詳解和捕獲、阻止方法_javascript技巧

        javascript事件冒泡詳解和捕獲、阻止方法_javascript技巧:一、事件的發(fā)生順序 這個(gè)問題的起源非常簡單,假設(shè)你在一個(gè)元素中又嵌套了另一個(gè)元素 代碼如下:-----------------------------------| element1 ------------------------- |element2 | -------------------
        推薦度:
        導(dǎo)讀javascript事件冒泡詳解和捕獲、阻止方法_javascript技巧:一、事件的發(fā)生順序 這個(gè)問題的起源非常簡單,假設(shè)你在一個(gè)元素中又嵌套了另一個(gè)元素 代碼如下:-----------------------------------| element1 ------------------------- |element2 | -------------------

        一、事件的發(fā)生順序

        這個(gè)問題的起源非常簡單,假設(shè)你在一個(gè)元素中又嵌套了另一個(gè)元素
        代碼如下:
        -----------------------------------
        | element1 |
        | ------------------------- |
        | |element2 | |
        | ------------------------- |

        -----------------------------------
        :并且兩者都有一個(gè)onClick事件處理函數(shù)(event handler)。如果用戶單擊元素2,則元素1和元素2的單擊事件都會(huì)被觸發(fā)。但是哪一個(gè)事件先被觸發(fā)?哪一個(gè)事件處理函數(shù)會(huì)被首先執(zhí)行?換句話說,事件的發(fā)生順序到底如何?

        二、兩種模型

        不出所料,在那些“不堪回首”(瀏覽器大戰(zhàn))的日子里,Netscape和微軟有兩種截然不同的處理方法:

        Netscape主張?jiān)?的事件首先發(fā)生,這種事件發(fā)生順序被稱為捕獲型
        微軟則保持元素2具有優(yōu)先權(quán),這種事件順序被稱為冒泡型
        這兩種事件順序是截然相反的。Explorer瀏覽器只支持冒泡事件,Mozilla,Opera7和Konqueror兩者都支持。而更古老的opera和iCab兩者都不支持

        三、捕獲型事件

        當(dāng)你使用捕獲型事件時(shí)
        代碼如下:

        ---------------| |-----------------
        | element1 | | |
        | -----------| |----------- |
        | |element2 \ / | |
        | ------------------------- |
        | Event CAPTURING |
        -----------------------------------
        :元素1的事件處理函數(shù)首先被觸發(fā),元素2的事件處理函數(shù)最后被觸發(fā)

        四、冒泡型事件

        當(dāng)你使用冒泡型事件時(shí)
        代碼如下:
        / \
        ---------------| |-----------------
        | element1 | | |
        | -----------| |----------- |
        | |element2 | | | |
        | ------------------------- |
        | Event BUBBLING |
        -----------------------------------
        :元素2 的處理函數(shù)首先被觸發(fā),元素1其次

        五、W3C 模型

        W3c明智的在這場爭斗中選擇了一個(gè)擇中的方案。任何發(fā)生在w3c事件模型中的事件,首是進(jìn)入捕獲階段,直到達(dá)到目標(biāo)元素,再進(jìn)入冒泡階段
        代碼如下:
        | | / \
        -----------------| |--| |-----------------
        | element1 | | | | |
        | -------------| |--| |----------- |
        | |element2 \ / | | | |
        | -------------------------------- |
        | W3C event model |
        ------------------------------------------
        為一個(gè)web開發(fā)者,你可以選擇是在捕獲階段還是冒泡階段綁定事件處理函數(shù),這是通過addEventListener()方法實(shí)現(xiàn)的,如果這個(gè)函數(shù)的最后一個(gè)參數(shù)是true,則在捕獲階段綁定函數(shù),反之false,在冒泡階段綁定函數(shù)。

        假設(shè)你要做
        代碼如下:
        element1.addEventListener('click',doSomething2,true)

        element2.addEventListener('click',doSomething,false)

        如果用戶單擊元素2,則接下來會(huì)發(fā)生:

        (事件在這里就像一個(gè)觀光客,由外至內(nèi)游覽,逐漸接近被觸發(fā)的主要元素,然后又反向離開)

        1.單擊事件首先進(jìn)入捕獲階段開始(逐漸接近元素2的方向)。查看元素2的祖先元素中是否有在捕獲階段有onclick處理函數(shù)的
        2.發(fā)現(xiàn)元素1有一個(gè),于是doSomething2被執(zhí)行
        3.事件檢查到目標(biāo)自己(元素2),捕獲階段沒有發(fā)現(xiàn)更多的處理函數(shù)了。事件開始進(jìn)入冒泡階段,想當(dāng)然執(zhí)行doSomething(),這個(gè)綁定于元素2冒泡階段的函數(shù)。
        4.事件向遠(yuǎn)離元素2的方向,查看是否有任何祖先元素在冒泡階段綁定了一個(gè)處理函數(shù)。沒有這樣的情況,所以什么也沒有發(fā)生
        相反的情況是:
        代碼如下:
        element1.addEventListener('click',doSomething2,false)

        element2.addEventListener('click',doSomething,false)
        現(xiàn)在如果用戶點(diǎn)擊元素2會(huì)發(fā)生:

        1.單擊事件進(jìn)入捕獲階段。查看元素2的祖先元素中是否有在捕獲階段有onclick處理函數(shù)的,結(jié)果一無所獲
        2.事件檢查到目標(biāo)自己。事件開始進(jìn)入冒泡階段,并且執(zhí)行綁定于元素2冒泡階段的函數(shù)。doSomething()
        3.事件開始遠(yuǎn)離目標(biāo),檢查元素2的祖先元素中是否有在冒泡階段綁定了處理函數(shù)的
        4.發(fā)現(xiàn)了一個(gè),于是元素1的doSomething2()被執(zhí)行

        六、兼容性和傳統(tǒng)模式

        在支持w3c dom(文檔對象模型) 的瀏覽器中,傳統(tǒng)的事件綁定方法是
        代碼如下:element1.onclick = doSomething2;
        默認(rèn)被視為在綁定于冒泡階段

        七、使用冒泡型事件

        很少的開發(fā)人員會(huì)有意識(shí)的去使用冒泡型事件或者捕獲型事件。在他們今天制作的網(wǎng)頁中,沒有必要讓一個(gè)事件因?yàn)槊芭荻缓脦讉€(gè)函數(shù)處理。但是有時(shí)用戶通常會(huì)很疑惑,因?yàn)樵谒麄冎稽c(diǎn)擊了一次鼠標(biāo)之后出現(xiàn)了許多種情況(多個(gè)函數(shù)被執(zhí)行,因?yàn)槊芭荩6蠖鄶?shù)情況下你還是希望你的處理函數(shù)相互獨(dú)立的。當(dāng)用戶點(diǎn)擊了某一個(gè)元素,發(fā)生什么,點(diǎn)擊另一個(gè)元素,又對應(yīng)發(fā)生些什么,相互獨(dú)立,而不因?yàn)槊芭葸B鎖。

        八、一直在發(fā)生

        首先你要明白的是事件捕獲或者冒泡一直在發(fā)生。如果你給整個(gè)頁面文檔的定義一個(gè)通用onclick處理函數(shù)
        代碼如下:
        document.onclick = doSomething;
        if (document.captureEvents) document.captureEvents(Event.CLICK);

        在頁面上單擊任何元素的單擊事件,最終會(huì)冒泡至頁面最高文檔層,因此觸發(fā)那個(gè)通用的處理函數(shù),除非之前一個(gè)處理函數(shù)明確的指出終止冒泡,這樣才冒泡才不會(huì)傳播到整個(gè)文檔層面


        對上面代碼第二句的補(bǔ)充:

        >>>先說IE
        object.setCapture() 當(dāng)一個(gè)object的被 setCapture 后,他的方法將會(huì)被繼承到整個(gè)文檔進(jìn)行捕獲。
        當(dāng)不需要把方法繼承到整個(gè)文檔捕獲時(shí),要用 object.releaseCapture()
        >>>others
        Mozilla 也有類似的功能,方法稍微不同
        window.captureEvents(Event.eventType)
        window.releaseEvents(Event.eventType)
        >>>example
        代碼如下://如果只有下面這句話,那只有點(diǎn)擊obj是才會(huì)觸發(fā)click obj.onclick = function(){alert("something")}
        //若加上下面這句話,則方法會(huì)被繼承到document(或者window,不同瀏覽器不同)來捕獲
        obj.captureEvents(Event.click); //FF
        obj.setCapture() //IE

        九、用法

        因?yàn)槿魏问录鞑ソK止于頁面文檔(這個(gè)最高層),這使默認(rèn)的事件處理函數(shù)變得可能,假設(shè)你有這樣一個(gè)頁面
        代碼如下:
        ------------------------------------
        | document |
        | --------------- ------------ |
        | | element1 | | element2 | |
        | --------------- ------------ |

        ------------------------------------
        element1.onclick = doSomething;
        element2.onclick = doSomething;
        document.onclick = defaultFunction;

        現(xiàn)在如果用戶單擊元素1或者元素2,doSomething()將被執(zhí)行。如果你愿意的話,如果你不想讓事件冒泡至執(zhí)行defaultFunction(),你可以在這里阻止事件冒泡向上傳播,。但是如果用戶點(diǎn)擊頁面上的其他部位,defaultFunction()還是會(huì)被執(zhí)行。這樣的效果或許有時(shí)能用的上。

        設(shè)置頁面­——使處理函數(shù)有范圍較大的觸發(fā)面積,在“拖拽效果”腳本中是必須的。一般來說在某一個(gè)元素層上發(fā)生 mousedown事件意味著選擇了這個(gè)元素,并且使它能夠響應(yīng)mousemove事件。雖然mousedown通常綁定于這個(gè)元素層上以避免瀏覽器bug,但是其他兩者的事件函數(shù)的范圍必須是整個(gè)頁面(?)

        記住瀏覽器學(xué)的第一法則(First Law of Browserology)是:一切皆有可能(anything can happen),并且是在你起碼有點(diǎn)準(zhǔn)備的時(shí)候。所以有可能發(fā)生的是,用戶拖拽時(shí),大幅度在頁面上移動(dòng)他的鼠標(biāo),腳本卻不能在大幅度中做出反應(yīng),以至于鼠標(biāo)也就不再停留在元素層上了

        1.如果onmouseover處理函數(shù)綁定在元素層上,這個(gè)元素層不會(huì)再對鼠標(biāo)的移動(dòng)有任何反應(yīng),這會(huì)讓用戶覺得奇怪
        2.如果onmouseup處理函數(shù)綁定在元素層上,事件也不能被觸發(fā),后果是,用戶想放下這個(gè)元素層后,元素層持續(xù)對鼠標(biāo)移動(dòng)做出反應(yīng)。這會(huì)引起(用戶)更多的迷惑(?)

        所以在這個(gè)例子中,事件冒泡非常的有用,因?yàn)閷⒛愕奶幚砗瘮?shù)放在頁面層能保證他們一直能被執(zhí)行

        十、把它給關(guān)了(阻止事件冒泡)

        但是一般情況下,你會(huì)想關(guān)了所有的冒泡和捕獲以保證函數(shù)之間不會(huì)打擾到對方。除此之外,如果你的文檔結(jié)構(gòu)相當(dāng)?shù)膹?fù)雜(許多table之間相互嵌套或者諸如此類),你也會(huì)為了節(jié)省系統(tǒng)資源,而關(guān)閉冒泡。此時(shí)瀏覽器不得不檢查目標(biāo)元素的每一個(gè)祖先,看是否它有一個(gè)處理函數(shù)。即使一個(gè)都沒有找到,剛剛的搜索同樣花費(fèi)不少時(shí)間

        在微軟的模型中,你必須設(shè)置事件的cancelBubble的屬性為true
        代碼如下:window.event.cancelBubble = true
        在w3c模型中你必須調(diào)用事件的stopPropagation()方法
        代碼如下:e.stopPropagation()
        這會(huì)阻止所有冒泡向外傳播。而作為跨瀏覽器解決方案應(yīng)該這么作:
        代碼如下:
        function doSomething(e)

        {
             if (!e) var e = window.event;

        e.cancelBubble = true;

        if (e.stopPropagation) e.stopPropagation();

        }

        在支持cancelBubble屬性的瀏覽器中設(shè)置cancelBubble無傷大雅。瀏覽器會(huì)聳一聳肩然后創(chuàng)造一個(gè)這個(gè)屬性。當(dāng)然這也并不能真正的取消冒泡,但至少能保證這條命令是安全正確的

        十一、currentTarget

        像我們之前看到的一樣,一個(gè)事件用target或者是srcElement屬性用來表示事件究竟發(fā)生在哪個(gè)目標(biāo)元素上(即用戶最初點(diǎn)擊的元素)。在我們的例子中是元素2,因?yàn)槲覀儐螕袅怂?/P>

        非常重要的是,要明白在捕獲或者冒泡階段的目標(biāo)元素是不變的,它始終與元素2相關(guān)聯(lián)。

        但是假設(shè)我們綁定了以下函數(shù)
        代碼如下:element1.onclick = doSomething;

        element2.onclick = doSomething;
        如果用戶單擊元素2, doSomething()會(huì)被執(zhí)行兩次。但是你怎么知道哪個(gè)html元素正在響應(yīng)這個(gè)事件?target/srcElement也沒有給出線索,但人們總是更傾向于元素2,因?yàn)樗且鹗录脑颍ㄒ驗(yàn)橛脩酎c(diǎn)擊的是它)。
        為了解決這個(gè)問題,w3c 增加了currentTarget這個(gè)屬性,它就指向正在處理事件的元素:這恰是我們需要的。很不幸的是微軟模型中并沒有相似的屬性
        你也可以使用”this”關(guān)鍵字。在上面的例子中,它相當(dāng)于正在處理事件的html元素,就像currentTarget。

        十二、微軟模型的問題

        但是當(dāng)你使用微軟事件綁定模型時(shí),this關(guān)鍵字并不相當(dāng)于HTML元素。聯(lián)想缺少類似currentTarget屬性的微軟模型(?)——按上面的代碼操作的話,你這么做便意味著:
        代碼如下:element1.attachEvent('onclick',doSomething)

        element2.attachEvent('onclick',doSomething)
        你無法確切知道哪一個(gè)HTML元素正在負(fù)責(zé)處理事件,這是微軟事件綁定模型最嚴(yán)重的問題,對我來說,這也是我從不使用它的原因,哪怕是在開發(fā)僅供Windows下的IE的應(yīng)用程序

        我希望能夠盡快增加currentTarget類似的屬性——或者遵循標(biāo)準(zhǔn)?web開發(fā)者們需要這些信息

        后記:

        因?yàn)闆]有實(shí)戰(zhàn)過javascript,所以這篇文章有些地方我并不是很理解,只能硬生的翻譯出來,比如談拖拽效果的那一段,如果大家有什么補(bǔ)充和疑問可以留言給我,謝謝支持啦!

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        javascript事件冒泡詳解和捕獲、阻止方法_javascript技巧

        javascript事件冒泡詳解和捕獲、阻止方法_javascript技巧:一、事件的發(fā)生順序 這個(gè)問題的起源非常簡單,假設(shè)你在一個(gè)元素中又嵌套了另一個(gè)元素 代碼如下:-----------------------------------| element1 ------------------------- |element2 | -------------------
        推薦度:
        標(biāo)簽: 事件 冒泡 詳解
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 免费在线观看亚洲| **aaaaa毛片免费| 国产男女猛烈无遮档免费视频网站| 午夜一区二区免费视频| 成人免费视频网址| 亚洲精品无码久久久久sm| 亚洲国产午夜精品理论片 | 亚洲国产精品SSS在线观看AV| 一个人看的www在线免费视频| 亚洲精品线路一在线观看| 亚洲色图综合网站| 特级做a爰片毛片免费看| 最近中文字幕高清免费中文字幕mv | 亚洲精品无码久久久久YW| 青青青青青青久久久免费观看| 亚洲AV无码资源在线观看| 毛片在线全部免费观看| 亚洲国产一区二区a毛片| 最新黄色免费网站| 亚洲最大天堂无码精品区| 又黄又爽无遮挡免费视频| 国产无遮挡无码视频免费软件| 久久久久亚洲av无码专区 | 亚洲av色福利天堂| 午夜不卡AV免费| 亚洲色偷偷偷鲁综合| 精品一区二区三区免费毛片爱| 亚洲一区精彩视频| 亚洲精品国精品久久99热| 国产精品免费大片| 国产亚洲精品免费视频播放| 久久青草免费91观看| 亚洲香蕉在线观看| 亚洲乱码无限2021芒果| 国产资源免费观看| 暖暖免费日本在线中文| 最新亚洲卡一卡二卡三新区| av免费不卡国产观看| 亚洲网站免费观看| 国产亚洲福利一区二区免费看| www成人免费观看网站|