生活随笔
收集整理的這篇文章主要介紹了
网页性能优化03-函数防抖
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.1-函數防抖
1.函數防抖介紹
-
1.什么是函數防抖? (debounce)
- 網上主流解釋:函數防抖,就是指觸發事件后在 n 秒內函數只能執行一次,如果在 n 秒內又觸發了事件,則會重新計算函數執行時間。
- 參考博客:https://www.jianshu.com/p/f9f6b637fd6c
- 參考博客:https://segmentfault.com/a/1190000018445196
- 筆者解釋:
- 先理解什么是抖動?:例如用戶鼠標輕微晃動,快速劃過某一個元素(用戶本身不想觸發,只是鼠標誤觸發,常見于鼠標事件 移入/移出/移動 )。 例如輸入框手機和郵箱驗證,用戶在不停的輸入,還沒有輸完的時候其實是不需要驗證的,應該等用戶輸入完畢后再驗證。
- 防抖 :如果用戶鼠標輕微晃動,在某一個元素上停留時間很短,則認為是用戶誤觸發,則不執行本次事件處理函數
- 一句話總結:用戶連續多次觸發某個事件,則只執行最后一次
- 由于函數防抖 屬于 前端中的 網頁性能優化技術,因此初學者剛開始學習會有一些吃力,并且很多網站都沒有做防抖處理(性能優化)
- 沒有函數防抖的真實案例:http://www.elong.com/?semid=ppzqbaidu
- 這是一個旅游類網站,上面酒店類型選擇沒有做防抖處理,用戶體驗很差
- 有函數防抖的真實案例:https://xyq.163.com/
- 這是網易夢幻西游官網,在網頁底部選擇職業的手風琴位置有做防抖處理,用戶體驗較好
-
沒有做函數防抖處理的用戶體驗如下
- 假設當前鼠標在第一張,此時用戶想看第五張。正常情況下,鼠標會依次觸發 第二、第三、第四張的移入事件,但這不是用戶真正想要觸發的(誤觸發)
- 有做函數防抖處理的用戶體驗如下
- 用戶從第一張 滑動到第五張,由于鼠標在 第二、第三、第四張停留時間很短(假設小于0.5秒),所以判定為用戶誤觸發,則不觸發對應的事件處理函數
2.函數防抖解決思路
-
使用定時器:保證用戶多次觸發事件時,以最后一次觸發為準
-
1.每一次移入元素時 : 不立即觸發該事件處理函數,而是開啟定時器,間隔0.5s(防抖間隔)之后再執行事件處理函數。
- 此時并沒有徹底解決函數防抖,因為用戶多次觸發事件時,每一個定時器都會在0.5s之后,依次執行
-
2.每一次移入元素時 : 先清除上一次的定時器
-
注意點:定時器中的this默認為window,需要使用上下文模式bind()動態修改為當前事件源
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>動畫-案例《手風琴》
</title><style>* {margin: 0;padding: 0;}ul {list-style: none;width: 2400px;}#box {width: 1200px;height: 400px;border: 2px solid red;margin: 100px auto;overflow: hidden;}#box li {width: 240px;height: 400px;float: left;}</style>
</head><body><div id="box"><ul><li><img src="./images/collapse/1.jpg" alt=""></li><li><img src="./images/collapse/2.jpg" alt=""></li><li><img src="./images/collapse/3.jpg" alt=""></li><li><img src="./images/collapse/4.jpg" alt=""></li><li><img src="./images/collapse/5.jpg" alt=""></li></ul></div><script src="./animation.js"></script><script>var liList = document.querySelectorAll('#box li');var box = document.querySelector('#box');var timeID = null;for (var i = 0; i < liList.length; i++) {liList[i].onmouseover = function () {clearTimeout(timeID);timeID = setTimeout(function () {console.log(1111);for (var j = 0; j < liList.length; j++) {if (liList[j] == this) {animationSlow(liList[j], { width: 800 });} else {animationSlow(liList[j], { width: 100 });}};}.bind(this), 500);};};box.onmouseout = function (e) {if (e.target == box) {for (var i = 0; i < liList.length; i++) {animationSlow(liList[i], { width: 240 });};};};</script></body></html>
3.萬能防抖函數的封裝
- 為什么要封裝萬能的防抖函數
- 在上一個小節中,我們的重點是介紹函數防抖的思路。但是在實際開發中,每一個防抖函數的事件處理都是不一樣的,他們可能是鼠標移入、鼠標移出、鼠標移動。 每一個案例需要的防抖間隔也不同
function debounce(fn
, timeout
) {clearTimeout(debounce
.timeID
);debounce
.timeID
= setTimeout(fn
, 500);
};
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>動畫-案例《手風琴》
</title><style>* {margin: 0;padding: 0;}ul {list-style: none;width: 2400px;}#box {width: 1200px;height: 400px;border: 2px solid red;margin: 100px auto;overflow: hidden;}#box li {width: 240px;height: 400px;float: left;}</style>
</head><body><div id="box"><ul><li><img src="./images/collapse/1.jpg" alt=""></li><li><img src="./images/collapse/2.jpg" alt=""></li><li><img src="./images/collapse/3.jpg" alt=""></li><li><img src="./images/collapse/4.jpg" alt=""></li><li><img src="./images/collapse/5.jpg" alt=""></li></ul></div><script src="./animation.js"></script><script>var liList = document.querySelectorAll('#box li');var box = document.querySelector('#box');for (var i = 0; i < liList.length; i++) {liList[i].onmouseover = function () {debounce(function () {for (var j = 0; j < liList.length; j++) {if (liList[j] == this) {animationSlow(liList[j], { width: 800 });} else {animationSlow(liList[j], { width: 100 });}};}.bind(this), 500);};};function debounce(fn, timeout) {clearTimeout(debounce.timeID);debounce.timeID = setTimeout(fn, 500);};box.onmouseout = function (e) {if (e.target == box) {for (var i = 0; i < liList.length; i++) {animationSlow(liList[i], { width: 240 });};};};</script></body></html>
總結
以上是生活随笔為你收集整理的网页性能优化03-函数防抖的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。