理解mouseover和mouseout“不穩定”的原因
原文地址:https://sneezry.com/#!/2015/08/16/理解mouseover和mouseout“不穩定”的原因
謝絕轉載。
事情的起因是博主負責的專案需要一個精美的滑塊供使用者調整圖片大小,當然HTML5有現成的range
控制元件博主是清楚的,但前端攻城獅如果做起來都那麼愜意怎麼會成為瀕危物種呢?沒錯,相容性,我們要相容性,作為一個有情懷公司的員工,我們不會像某付寶那樣放棄1%的使用者!不會!
那麼多了不說,直接上博主第一版的程式碼(僅做例項使用,與博主所負責專案的真實程式碼與外觀不同):
See the Pen aOrOj by Li Zhe (@Sneezry) on CodePen
是不是很難用!那個滑塊根本不跟著滑鼠走啊,十分地卡頓!這不是一個有情懷的公司應該做出來的東西!為了避免有些初入前端的同學看不太懂上面的程式碼,我來簡單帶著大家分析一下。HTML和CSS就不說了,我們直接來看看JS的邏輯。
首先滑塊控制把手scrollHandle
監聽了mousedown
事件,這樣當使用者滑鼠在滑塊上按下後就看著監視滑鼠的活動情況。mouseup
和mouseout
事件都繫結在了更大的scroll
元素是為了避免使用者滑鼠移動速度過快移出scrollHandle
元素導致事件捕捉失敗。
博主在寫完程式碼之後感覺邏輯完美得無懈可擊,甚至專門設計了一個區域更大的scroll
元素來提高事件捕捉的可靠性,可是事實呢!事實讓博主甚是崩潰啊!怎麼回事!
為了確定問題所在,博主將監聽事件的結果輸出到控制檯,結果發現,當使用者滑鼠移出scrollHanlde
時,scroll
的mouseout
事件被觸發了,但隨後立刻又觸發了scroll
的mouseover
事件!這讓博主一度認為是瀏覽器的Bug——沒事你在那mouseout
、mouseover
的幹啥!但最後證明其實是博主術業不精,對此博主深表愧疚,所以博主事後將W3C上Level 3 DOM Events從頭到尾看了一遍。
我相信,對DOM Events瞭解不夠深入的同學遇到這個問題第一感覺一定也認為是瀏覽器出了問題,因為mouseout
和mouseover
同時被觸發是不合邏輯的。那麼博主來和大家一同分析一下這件“詭異”事件是如何發生的。
DOM Events中有個屬性叫bubbles,翻譯過來叫冒泡。這個屬性名看起來很有趣,感覺也有些抽象,但實際上它恰恰生動形象地表達了這個屬性的意思。冒泡屬性來說明這個事件是否會向下傳遞,這個性質我相信在很多事件中同學們都或多或少知道,但可能單獨提出來同學們對不上號。比如click
事件,當點選一個元素時,此元素的父系元素也會接收到點選事件,這就是因為子元素的click
事件為冒泡事件,會傳遞給其父系元素。而bubbles這個詞形象地描述出這個過程好比水中的氣泡從水底慢慢上浮,只是DOM Events方向相反,傳遞是從頂向下的,直到傳遞到body
、html
、window
(這三者是傳遞鏈中的最後三個,不是並列關係)。
那麼上例的scroll
元素被瀏覽器折騰得反覆收到mouseout
和mouseout
事件就不奇怪了,首先滑鼠移出了scrollHandle
,scrollHandle
接收到了mouseout
事件,由於這個事件是冒泡的,隨後便傳給了scroll
,於是scroll
接收到了mouseout
事件;之後滑鼠移到了灰色或者藍色進度條上,或者直接移動到了scroll
上,無論三者中的哪一個,scroll
都會因為冒泡接收到mouseover
事件。這就是看起來在上例中mouseover
和mouseout
“不穩定”的原因。
那麼冒泡事件還有哪些呢?通過 W3C文件 可以知道,冒泡事件還有beforeinput
、click
、compositionstart
、compositionupdate
、compositionend
、dbclick
、focusin
、focusout
、input
、keydown
、keyup
、mousedown
、mousemove
、mouseup
、select
和wheel
。
問題的原理搞懂了,那麼應該如何解決呢?首先所有冒泡事件在傳遞的過程中,target
都是不變的,所以可以直接在scroll
的mouseout
事件中判斷e.target === this
來過濾其子元素傳遞過來mouseout
事件。等等,這不是正規的解決方法!W3C顯然考慮到了博主在開始說明的使用背景,所以有專門的事件來處理這個問題——mouseenter
和mouseleave
,這兩個事件不冒泡,是我們真正需要用到的方法。或許諸位同學又有疑問了,“你前面不是說有情懷的公司不放棄1%的使用者,要做到相容性嗎,這個新標準相容性可以接受嗎,IE全家你問過了嗎”,您還別說,這兩個事件正是IE發明的,IE全家都支援,甚至包括IE6!所以嘛,不用總吐槽人家小軟就會添亂,人家真的給W3C提交了很多有價值的建議標準呢!
下面是改後的Demo,用起來是不是舒爽多了!
相關文章
- 淺談mouseenter和mouseover,mouseout和mouseleave
- 伺服器不穩定的原因伺服器
- 防止滑鼠移出移入子元素觸發mouseout和mouseover事件事件
- 執行計劃不穩定的原因分析
- 路由器無線網路不穩定怎麼辦?路由器無線網路速度不穩定的原因和解決方法路由器
- go 代理穩定不卡頓Go
- 企業網路的不穩定因素
- 伺服器不穩定因素伺服器
- 怎麼測試伺服器穩不穩定伺服器
- 理解去中心化 穩定幣 DAI中心化AI
- 路由器不穩定總是間歇性斷網什麼原因怎麼辦路由器
- 目標檢測框不穩定不連續?
- jQuery mouseout和mouseleave事件的區別jQuery事件
- jQuery mouseleave和mouseout 區別jQuery
- 網路 adb 不穩定咋辦?
- 如何處理不穩定的自動化測試?
- [譯]為何前端開發如此不穩定前端
- [譯] 為何前端開發如此不穩定前端
- JavaScript mouseout 事件JavaScript事件
- jQuery mouseout 事件jQuery事件
- PostgreSQL 字符集烏龍導致資料查詢排序的問題,與 MySQL 穩定 "PG不穩定"排序MySql
- oracle優化器和不走索引的原因Oracle優化索引
- 為什麼前端開發這麼不穩定?前端
- JavaScript mouseover 事件JavaScript事件
- jQuery mouseover事件jQuery事件
- MySQL:關於排序order by limit值不穩定的說明(1)MySql排序MIT
- 【JavaScript】offset、client、scroll、mouseover和mouseenter區別JavaScriptclient
- 穩定的牛分配
- 伺服器不穩定直接影響網站SEO?伺服器網站
- 關於教程中 NPM 下載不穩定個人的解決方法NPM
- 【知識分享】伺服器不穩定對網站的影響伺服器網站
- 透過shell指令碼來得到不穩定的執行計劃指令碼
- 通過shell指令碼來得到不穩定的執行計劃指令碼
- 程式採集裝置資料,不穩定,突然不採集, 程式崩潰
- phpsimplexml_load_file函式執行不穩定PHPXML函式
- 網速不穩定怎麼辦?網路小白都在看
- 無線路由器ping不穩定怎麼辦路由器
- Macbook OS X EI Capitan 10.11.5 WiFi不穩定MacAPIWiFi