溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

jQuery基本事件代碼優(yōu)化的示例分析

發(fā)布時(shí)間:2021-09-16 17:43:17 來(lái)源:億速云 閱讀:105 作者:小新 欄目:web開(kāi)發(fā)

這篇文章主要介紹了jQuery基本事件代碼優(yōu)化的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

事件模型

說(shuō)到事件,就要追溯到網(wǎng)景與微軟的“瀏覽器大戰(zhàn)”了。當(dāng)時(shí),事件模型還沒(méi)有標(biāo)準(zhǔn),兩家公司的實(shí)現(xiàn)就是事實(shí)標(biāo)準(zhǔn)。網(wǎng)景在Navigator中實(shí)現(xiàn)了“事件捕獲”的事件系統(tǒng),而微軟則在IE中實(shí)現(xiàn)了一個(gè)基本上相反的事件系統(tǒng),叫做“事件冒泡”。這兩種系統(tǒng)的區(qū)別在于當(dāng)事件發(fā)生時(shí),相關(guān)元素處理(響應(yīng))事件的優(yōu)先權(quán)不同。

下面舉例說(shuō)明這兩種事件機(jī)制的區(qū)別  。假設(shè)文檔中有如下結(jié)構(gòu):

<div>       <span>           <a>...a>       span>   div>

因?yàn)檫@三個(gè)元素是嵌套的,所以單擊了a,實(shí)際上也就單擊了span和div  。換句話說(shuō),這三個(gè)元素都應(yīng)該有處理單擊事件的機(jī)會(huì)  。在事件捕獲機(jī)制下,處理這個(gè)單擊事件的優(yōu)先次序是:div > span > a;而在事件冒泡機(jī)制下,處理這個(gè)單擊事件的優(yōu)先次序則是:a > span > div  。

后來(lái),W3C的規(guī)范要求瀏覽器同時(shí)支持捕獲和冒泡機(jī)制,并允許開(kāi)發(fā)人員選擇把事件注冊(cè)到哪個(gè)階段  。于是就有了下面這個(gè)注冊(cè)事件的標(biāo)準(zhǔn)方法

target.addEventListener(type, listener, useCapture Optional );

其中:

type:字符串,表示監(jiān)聽(tīng)的事件類(lèi)型

listener:監(jiān)聽(tīng)器對(duì)象(JavaScript函數(shù)),在指定事件發(fā)生時(shí)可以收到通知

useCapture:布爾值,是否注冊(cè)到捕獲階段

在實(shí)際應(yīng)用開(kāi)發(fā)中,為了確保與IE(因?yàn)樗恢С植东@)兼容,useCapture一般都指定為false(默認(rèn)值也是false)  。換句話說(shuō),只把事件注冊(cè)到冒泡階段;對(duì)于上面那個(gè)簡(jiǎn)單的例子來(lái)說(shuō),響應(yīng)順序就是:a > span > div  。

冒泡的副作用

如前所述,IE的冒泡事件模型基本上成為了事實(shí)標(biāo)準(zhǔn)。但冒泡有一個(gè)副作用。

仍以前面的文檔結(jié)構(gòu)為例,假設(shè)它是界面中的一個(gè)菜單項(xiàng),我們希望用戶鼠標(biāo)離開(kāi)div時(shí)隱藏菜單。于是,我們給div注冊(cè)了一個(gè)mouseout事件  。如果用戶鼠標(biāo)是從div離開(kāi)的,那么一切正確  。而如果用戶鼠標(biāo)是從a或span離開(kāi)的,問(wèn)題就來(lái)了。因?yàn)橛捎谑录芭?,從這兩個(gè)元素開(kāi)始分派的mouseout事件都會(huì)傳播到div,從而導(dǎo)致鼠標(biāo)并沒(méi)有離開(kāi)div,菜單就提前隱藏了。

當(dāng)然,冒泡的副作用不難避免  。比如,給div內(nèi)部的每個(gè)元素都注冊(cè)mouseout事件,并使用.stopPropagation()方法阻止事件進(jìn)一步傳播  。對(duì)于IE,就得將事件對(duì)象的cancelBubble屬性設(shè)置為false,取消事件冒泡  。不過(guò),這仍然回到自己處理瀏覽器不兼容性問(wèn)題的老路上了  。

優(yōu)化方案

為了避免冒泡的副作用,jQuery提供了mouseenter和mouseleave事件,就使用它們來(lái)代替mouseover和mouseout吧  。

下面這個(gè)摘自jQuery的內(nèi)部函數(shù)withinElement,就是為mouseenter和mouseleave提供支持的  。翻譯了一下注釋,僅供大家參考  。

// 下面這個(gè)函數(shù)用于檢測(cè)事件是否發(fā)生在另一個(gè)元素的內(nèi)部    // 在 jQuery.event.special.mouseenter 和 mouseleave 處理程序中使用    var withinElement = function( event ) {        // 檢測(cè) mouse(over|out) 是否還在相同的父元素內(nèi)        var parent = event.relatedTarget;           // 設(shè)置正確的事件類(lèi)型        eventevent.type = event.data;           // Firefox 有時(shí)候會(huì)把 relatedTarget 指定一個(gè) XUL 元素        // 對(duì)于這種元素,無(wú)法訪問(wèn)其 parentNode 屬性        try {               // Chrome 也類(lèi)似,雖然可以訪問(wèn) parentNode 屬性            // 但結(jié)果卻是 null            if ( parent && parent !== document && !parent.parentNode ) {                return;            }               // 沿 DOM 樹(shù)向上            while ( parent && parent !== this ) {                parentparent = parent.parentNode;            }               if ( parent !== this ) {                // 如果實(shí)際正好位于一個(gè)非子元素上面,那好,就處理事件                jQuery.event.handle.apply( this, arguments );            }           // 假定已經(jīng)離開(kāi)了元素,因?yàn)楹芸赡苁髽?biāo)放在了一個(gè)XUL元素上        } catch(e) { }    },

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“jQuery基本事件代碼優(yōu)化的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI