手機瀏覽器在滾動當前頁面(也可能是縮放頁面)時,由於預設行為被阻止,導致頁面被迫靜止,導致用戶使用體驗差,感覺滾動頁面有停頓感。
具體一點的解釋:由於touchstart 事件物件的cancelable 屬性為true,也就是說它的預設行為可以被監聽器透過preventDefault() 方法阻止。但瀏覽器無法預先知道一個監聽器會不會呼叫preventDefault(),它能做的只有等監聽器執行完後再去執行預設行為,而監聽器執行是要耗時的,有些甚至耗時很明顯,這樣就會導致頁面卡頓。即便監聽器是個空函數,也會產生一定的卡頓,畢竟空函數的執行也會耗時。
addEventListener的useCapture參數基本概念:xxx.addEventListener('事件名稱', function(xxx){xxx}, useCapture).
第一個參數表示事件名稱(不含on,如click);第二個參數表示要接收事件處理的函數;第三個參數為useCapture.
下面就來看看這個東西是個啥意思,直接舉例子說明比較直觀。
<div id=level1> <div id=level2> <div id=level3>請在此點選</div> </div></div><div id=info></div>
var level1 = document.getElementById(level1);var level2 = document.getElementById(level2);var level3= document.getElementById(level3);var info = document.getElementById(info); info.innerHTML += level1 + <br>; }, false);middleDiv.addEventListener(click, function () { info.innerHTML += level2 + <br>; }, false);inDiv.addEventListener(click, function () { info.innerHTML +=========== level3 + <br>; }, false);
根據上述程式碼來看這個useCapture 為true 和false的作用效果:
全為false 時,觸發順序為:level3、level2、level1
全為true 時,觸發順序為:level1、level2、level3
level1為true,其他為false 時,觸發順序為:level1、level3、level2
level2為true,其他為false 時,觸發順序為:level2、level3、level1
level3為true,其他為false 時,觸發順序為:level3、level2、level1
level1為false,其他為true時,觸發順序為:level2、level3、level1
level2為false,其他為true時,觸發順序為:level1、level3、level2
level3為false,其他為true時,觸發順序為:level1、level2、level3
由上述結果得出以下結論:
passive屬性來控制事件行為true 的觸發順序總是在false 之前;
如果多個均為true,則外層的觸發先於內層;
如果多個均為false,則內層的觸發先於外層。
使用方式如下
addEventListener('事件名稱', function(xxx){xxx}, { capture: false, passive: false, once: false})
三個屬性都是布林類型的開關,預設值都為false。
capture:等價於先前的useCapture 參數;
once:就是表示該監聽器是一次性的,執行一次後就被自動removeEventListener 掉;
passive:用於webapp的touch事件
據了解,在手機瀏覽器使用事件的時候,有80% 的滾動事件監聽器是不會阻止預設行為的,也就是說大部分情況下,瀏覽器是白等了。所以,passive 監聽器誕生了,passive 的意思是順從的,表示它不會對事件的預設行為說no,瀏覽器知道了一個監聽器是passive 的,它就可以在兩個執行緒同時執行監聽器中的JavaScript 程式碼和瀏覽器的預設行為了。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。