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