摘要:是如何決定由哪個(gè)元素來處理事件的,以及又是如何優(yōu)化處理這個(gè)問題的,這些都涉及到了事件傳播。事件冒泡的弊端事件冒泡可能會(huì)導(dǎo)致意料之外的行為,例如在響應(yīng)事件時(shí),依舊是上例,當(dāng)為最外層的添加一個(gè)事件。使用方法可以避免事件傳播導(dǎo)致的問題。
Javascript 是如何決定由哪個(gè)元素來處理事件的,以及 jQuery 又是如何優(yōu)化處理這個(gè)問題的,這些都涉及到了事件傳播。
事件傳播策略當(dāng)頁(yè)面內(nèi)的發(fā)生一個(gè)事件時(shí),每個(gè)層次的 DOM 元素都有機(jī)會(huì)來處理這個(gè)事件,為了弄懂整個(gè)過程,舉例說明:
1.事件捕獲
有兩種策略來處理事件,第一種是事件捕獲。
當(dāng)采取“事件捕獲”策略時(shí),點(diǎn)擊 a 標(biāo)簽后,事件首先交給外層的元素,然后再往內(nèi)交給更具體的元素:
div -> span -> a2.事件冒泡
另一種策略是“事件冒泡”,事件冒泡與事件捕獲剛好相反,當(dāng)點(diǎn)擊 a 標(biāo)簽后,首先會(huì)發(fā)送到最具體的元素,在這個(gè)元素得到響應(yīng)后,事件會(huì)往上冒泡到更外層的元素:
a -> span -> div
一開始,不同的瀏覽器采用不同的策略來處理事件傳播,為了統(tǒng)一化,DOM 標(biāo)準(zhǔn)規(guī)定應(yīng)該同時(shí)使用著兩種策略,首先通過“事件捕獲”來捕獲到最具體的元素,接著通過“事件冒泡”返回到 DOM 樹的頂層。
3.統(tǒng)一策略同時(shí),我們很容易理解,對(duì)于事件的處理程序既可以發(fā)生在事件捕獲階段,也可以發(fā)生在事件冒泡階段,jQuery 為了統(tǒng)一策略決定始終在事件冒泡階段注冊(cè)事件處理程序。因此,我們可以假定最具體最內(nèi)層的元素會(huì)首先獲得響應(yīng)事件的機(jī)會(huì)。
事件冒泡的弊端事件冒泡可能會(huì)導(dǎo)致意料之外的行為,例如在響應(yīng) mouseout 事件時(shí),依舊是上例,當(dāng)為最外層的 div 添加一個(gè) mouseout 事件。此時(shí),如果鼠標(biāo)移出 div 區(qū)域時(shí),肯定會(huì)觸發(fā) mouseout 事件綁定的程序,這是我們期望的,但是如果鼠標(biāo)是從 a 元素上離開時(shí),a 元素也會(huì)取得一個(gè) mouseout 事件,再通過事件冒泡后,外層的 div 也會(huì)獲得,這顯然不是我們想要的。
給 div 添加樣式來便于區(qū)分:
div { width: 200px; height: 200px; background-color: lightblue; }
綁定 mouseout 事件到 div 上:
$("div").mouseout(function() { //觸發(fā) `alert` alert("mouse is out!"); });
當(dāng)鼠標(biāo)從淡藍(lán)色的區(qū)域移開時(shí),觸發(fā) alert,但是當(dāng)鼠標(biāo)放到 a 標(biāo)簽上后再移開,即使沒移開 div 區(qū)域,同樣也會(huì)觸發(fā) alert,這顯然不是我們希望的,這就是事件冒泡帶來的弊端。
這里介紹兩種直接簡(jiǎn)單的方法來解決這個(gè)問題。
第一是使用 jQuery 自帶的 .hover() 方法,.hover() 方法接受兩個(gè)函數(shù)參數(shù),第一個(gè)參數(shù)在鼠標(biāo)進(jìn)入綁定元素時(shí)執(zhí)行,第二個(gè)參數(shù)在鼠標(biāo)移除綁定元素時(shí)執(zhí)行。使用 .hover() 方法可以避免事件傳播導(dǎo)致的問題。
$("div").hover(function() {}, function() { alert("mouse is out!"); });
第二種方法是使用 mouseleave 來代替 mouseout 方法。
$("div").mouseleave(function() { //觸發(fā) `alert` alert("mouse is out!"); });
這兩種方法是針對(duì) mouseout 可能出現(xiàn)的問題來解決的,對(duì)于事件冒泡可能導(dǎo)致的其他弊端現(xiàn)象,我們需要用更加適用的方法來解決,因?yàn)檫@個(gè)知識(shí)點(diǎn)在書中的下一個(gè)章節(jié)介紹,所以我打算在下一篇博文中總結(jié)。
參考http://book.douban.com/subject/24669823/
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78141.html
摘要:事件對(duì)象是一種結(jié)構(gòu),它會(huì)在元素獲得處理事件的機(jī)會(huì)時(shí)傳遞給調(diào)用的事件處理程序。事件對(duì)象的屬性指的是事件目標(biāo),它將保存發(fā)生事件的目標(biāo)元素。所以,接下來我們就要想辦法改變事件過程來阻止這個(gè)行為。 在 《細(xì)說 jQuery 事件篇(三) - 事件傳播》 中提到了事件冒泡可能造成的弊端,當(dāng)時(shí)舉了 mouseout 的例子,對(duì)于 mouseout 這個(gè)特殊情況,我們可以用 hover 方法來解決,...
摘要:我們可以利用可以對(duì)用戶發(fā)起的事件進(jìn)行處理,這里以樣式轉(zhuǎn)換為例來說明。其他類似的操作事件都可以通過這個(gè)方法,將處理事件的程序綁定到同名事件上面。 我們可以利用 jQuery 可以對(duì)用戶發(fā)起的事件進(jìn)行處理,這里以樣式轉(zhuǎn)換為例來說明。 增添樣式 基于用戶的事件,對(duì)特定的 DOM 元素樣式進(jìn)行轉(zhuǎn)換是 jQuery 處理事件中比較常見的情形,舉例說明,當(dāng)用戶點(diǎn)擊輸入框后,會(huì)增添 highli...
摘要:一種做法是在事件處理程序中使用條件語(yǔ)句進(jìn)行判斷,另一種更徹底的做法就是直接移除該處理程序。事件重綁定我們添加一個(gè)按鈕,當(dāng)點(diǎn)擊按鈕后,所有的事件的處理程序又被重新綁定回來。 如果我們需要移除已經(jīng)注冊(cè)的事件處理程序,使某些處理程序失效。一種做法是在事件處理程序中使用條件語(yǔ)句進(jìn)行判斷,另一種更徹底的做法就是直接移除該處理程序。 移除處理程序 假設(shè)有個(gè) div 和 button,當(dāng)我們點(diǎn)擊...
摘要:查看上方法被觸發(fā)的原因是但是通過方法直接修改元素的值并不能觸發(fā)事件,只有當(dāng)用戶真實(shí)輸入并改變框的內(nèi)容時(shí)才有效。但是假設(shè)我們希望能模擬用戶的操作,則需要用到方法,修改代碼如下此時(shí),不需要用戶進(jìn)行點(diǎn)擊操作,通過已經(jīng)模擬了一次用戶的操作。 前陣子在調(diào)一個(gè) bug 的時(shí)候遇到一個(gè)很坑的問題,在判斷一個(gè)輸入框是否有用戶輸入時(shí)觸發(fā) updateModel 操作,并向后臺(tái)發(fā)送 PUT 請(qǐng)求,結(jié)果調(diào)試...
摘要:在元素一篇介紹過,可以使用來使得代碼在加載完畢后自動(dòng)執(zhí)行代碼,接下來具體介紹下這個(gè)機(jī)制。這樣看上去貌似沒什么問題,但是如果有兩個(gè)函數(shù)需要指定時(shí)就會(huì)遇到麻煩,因?yàn)閷傩灾荒鼙4鎸?duì)一個(gè)函數(shù)的引用,如果我們寫成以下形式最后代碼執(zhí)行后的效果是會(huì)覆蓋。 在元素一篇介紹過,jQuery 可以使用 $(document).ready() 來使得代碼在 DOM 加載完畢后自動(dòng)執(zhí)行代碼,接下來具體介紹下這...
閱讀 3679·2021-11-24 09:38
閱讀 3159·2021-11-15 11:37
閱讀 800·2021-11-12 10:36
閱讀 3557·2021-10-21 09:38
閱讀 3230·2021-09-28 09:36
閱讀 2430·2021-09-22 16:01
閱讀 5005·2021-09-22 15:09
閱讀 1230·2019-08-30 15:55