今天有個同事遇到一個奇怪的問題,我照着他的代碼做了一些簡化寫了這個demo
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <style type="text/css"> 5 div{position: absolute;top: 0;left: 0;height: 50px} 6 #back{background-color: blue;left: 20px;width: 200px;z-index: 0} 7 #front{background-color: green;top:10px;width: 100px;z-index: 1} 8 </style> 9 </head> 10 <body> 11 <div id="back"></div> 12 <div id="front"></div> 13 <script type="text/javascript"> 14 document.getElementById("back").addEventListener("click", function () { 15 console.log("back clicked"); 16 }) 17 document.getElementById("front").addEventListener("click", function () { 18 console.log("front clicked"); 19 this.setAttribute("style", "z-index:0"); 20 document.getElementById("back").setAttribute("style", "z-index:1"); 21 }) 22 document.getElementById("back").addEventListener("dblclick", function () { 23 console.log("back double clicked"); 24 }) 25 document.getElementById("front").addEventListener("dblclick", function () { 26 console.log("front double clicked"); 27 }) 28 </script> 29 </body> 30 </html>
代碼的邏輯大致是這樣的:
首先,頁面中綠色方塊為front,藍色方塊為back。系統的需求是,在綠色方塊上單擊時,切換兩個方塊覆蓋方式(也就是點擊front后back會跑到front前面)。同時,還需要在雙擊藍色方塊時實現另一個功能邏輯。
於是這哥們很自然了寫了類似上面的代碼就提交了。沒多久,測試MM提了一個bug:“雙擊綠色方塊時,不應觸發雙擊藍色方塊的邏輯”。
后來我自己測了一下,果然如測試MM所說,當雙擊綠色和藍色方塊重疊的區域時,控制台會打印出這樣的log:
瀏覽器會先觸發front click,然后是back click,再然后居然是back double click。按理說,在back上面只點擊了一次,應該不觸發double click才對,畢竟第一次click是在front上觸發的。
所以,我大膽猜想,瀏覽器本身並不會去判定鼠標是否觸發雙擊事件,雙擊事件是由操作系統直接分發給瀏覽器的。當瀏覽器收到操作系統發來的雙擊消息時,直接根據該雙擊事件中的坐標去頁面中找命中的元素,並在這個元素上觸發js中的雙擊事件。
操作系統在判斷是否發生雙擊時,並不知道第一次click和第二次click的目標不是同一個元素,所以只要兩次click的間隔足夠短就認為構成雙擊事件。而瀏覽器在收到操作系統發來的雙擊事件時,並沒有去檢測這次雙擊是由那兩次單擊所產生,而是直接根據雙擊事件的坐標信息將這個事件分發到相應的html元素上了。
為驗證這個猜想,我又寫了一個demo
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <style type="text/css"> 5 body{transition:padding-left 8s linear;padding-left: 0} 6 div{width: 10px;height: 200px;background-color: blue;display: inline-block;float: left;} 7 </style> 8 </head> 9 <body> 10 <div id="div_00"></div> 11 <div id="div_01"></div> 12 <div id="div_02"></div> 13 <div id="div_03"></div> 14 <div id="div_04"></div> 15 <div id="div_05"></div> 16 <div id="div_06"></div> 17 <div id="div_07"></div> 18 <div id="div_08"></div> 19 <div id="div_09"></div> 20 <div id="div_10"></div> 21 <div id="div_11"></div> 22 <div id="div_12"></div> 23 <div id="div_13"></div> 24 <div id="div_14"></div> 25 <div id="div_15"></div> 26 <div id="div_16"></div> 27 <div id="div_17"></div> 28 <div id="div_18"></div> 29 <div id="div_19"></div> 30 <div id="div_20"></div> 31 <div id="div_21"></div> 32 <div id="div_22"></div> 33 <div id="div_23"></div> 34 <div id="div_24"></div> 35 <div id="div_25"></div> 36 <div id="div_26"></div> 37 <div id="div_27"></div> 38 <div id="div_28"></div> 39 <div id="div_29"></div> 40 <script type="text/javascript"> 41 var divs = document.getElementsByTagName("div"); 42 for(var i = 0, length = divs.length; i < length; i++){ 43 divs[i].addEventListener("click", function () { 44 console.log("clicked", this.id); 45 }); 46 divs[i].addEventListener("dblclick", function () { 47 console.log("double clicked", this.id); 48 }); 49 } 50 51 setTimeout(function(){ 52 document.body.setAttribute("style", "padding-left:300px"); 53 }, 1000); 54 </script> 55 </body> 56 </html>
當頁面中的藍色方塊開始移動后,在藍色方塊上雙擊鼠標,可以多試幾次,得到下面的結果:
可以看到,div_26、div_22兩次雙擊事件分別是由div27、div26和div23、div22的兩次單擊觸發的。
從這兩個結果來看,確實是符合我的猜想的。
不過,這個demo也帶來了一些疑惑:
1、clicked div_19 這個log打印的時候,我非常確定我點擊了兩次鼠標,但是只打出了這一個log,為什么?
2、double clicked div_15和double clicked div_11這兩次雙擊事件觸發前,都只觸發了一次click事件,這又是為什么?
以上所有代碼測試結果都是基於 Chrome 33 和 IE 11 運行環境。
希望有高人指導,也歡迎大家各抒己見。
如需轉載,請注明轉自:http://www.cnblogs.com/silenttiger/p/3578397.html
歡迎關注我的微信公眾號:老虎的小窩