日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网页性能优化03-函数防抖

發(fā)布時間:2024/9/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网页性能优化03-函数防抖 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.1-函數(shù)防抖

1.函數(shù)防抖介紹

  • 1.什么是函數(shù)防抖? (debounce)

    • 網(wǎng)上主流解釋:函數(shù)防抖,就是指觸發(fā)事件后在 n 秒內(nèi)函數(shù)只能執(zhí)行一次,如果在 n 秒內(nèi)又觸發(fā)了事件,則會重新計算函數(shù)執(zhí)行時間。
      • 參考博客:https://www.jianshu.com/p/f9f6b637fd6c
      • 參考博客:https://segmentfault.com/a/1190000018445196
    • 筆者解釋:
      • 先理解什么是抖動?:例如用戶鼠標(biāo)輕微晃動,快速劃過某一個元素(用戶本身不想觸發(fā),只是鼠標(biāo)誤觸發(fā),常見于鼠標(biāo)事件 移入/移出/移動 )。 例如輸入框手機和郵箱驗證,用戶在不停的輸入,還沒有輸完的時候其實是不需要驗證的,應(yīng)該等用戶輸入完畢后再驗證。
      • 防抖 :如果用戶鼠標(biāo)輕微晃動,在某一個元素上停留時間很短,則認為是用戶誤觸發(fā),則不執(zhí)行本次事件處理函數(shù)
        • 一句話總結(jié):用戶連續(xù)多次觸發(fā)某個事件,則只執(zhí)行最后一次
      • 由于函數(shù)防抖 屬于 前端中的 網(wǎng)頁性能優(yōu)化技術(shù),因此初學(xué)者剛開始學(xué)習(xí)會有一些吃力,并且很多網(wǎng)站都沒有做防抖處理(性能優(yōu)化)
        • 沒有函數(shù)防抖的真實案例:http://www.elong.com/?semid=ppzqbaidu
          • 這是一個旅游類網(wǎng)站,上面酒店類型選擇沒有做防抖處理,用戶體驗很差
        • 有函數(shù)防抖的真實案例:https://xyq.163.com/
          • 這是網(wǎng)易夢幻西游官網(wǎng),在網(wǎng)頁底部選擇職業(yè)的手風(fēng)琴位置有做防抖處理,用戶體驗較好
  • 沒有做函數(shù)防抖處理的用戶體驗如下

    • 假設(shè)當(dāng)前鼠標(biāo)在第一張,此時用戶想看第五張。正常情況下,鼠標(biāo)會依次觸發(fā) 第二、第三、第四張的移入事件,但這不是用戶真正想要觸發(fā)的(誤觸發(fā))

  • 有做函數(shù)防抖處理的用戶體驗如下
    • 用戶從第一張 滑動到第五張,由于鼠標(biāo)在 第二、第三、第四張停留時間很短(假設(shè)小于0.5秒),所以判定為用戶誤觸發(fā),則不觸發(fā)對應(yīng)的事件處理函數(shù)

2.函數(shù)防抖解決思路

  • 使用定時器:保證用戶多次觸發(fā)事件時,以最后一次觸發(fā)為準(zhǔn)

  • 1.每一次移入元素時 : 不立即觸發(fā)該事件處理函數(shù),而是開啟定時器,間隔0.5s(防抖間隔)之后再執(zhí)行事件處理函數(shù)。

    • 此時并沒有徹底解決函數(shù)防抖,因為用戶多次觸發(fā)事件時,每一個定時器都會在0.5s之后,依次執(zhí)行
  • 2.每一次移入元素時 : 先清除上一次的定時器

    • 保證用戶多次觸發(fā)事件時,以最后一次觸發(fā)為準(zhǔn)
  • 注意點:定時器中的this默認為window,需要使用上下文模式bind()動態(tài)修改為當(dāng)前事件源

<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><title>動畫-案例《手風(fēng)琴》</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>/*需求(1):給每一個li設(shè)置鼠標(biāo)移入事件:當(dāng)前l(fā)i的寬度變成800,其他兄弟li寬度變成100(2):鼠標(biāo)移出大盒子,所有的li的寬度都變成默認的240 *///1.獲取元素var liList = document.querySelectorAll('#box li');//li元素列表var box = document.querySelector('#box');//li元素列表/* 一:聲明全局變量存儲定時器ID */var timeID = null;//2.注冊事件//2.1 鼠標(biāo)移入事件:當(dāng)前l(fā)i的寬度變成800,其他兄弟li寬度變成100for (var i = 0; i < liList.length; i++) {liList[i].onmouseover = function () {//二:先清除以前的定時器,以本次為準(zhǔn)clearTimeout(timeID);//事件處理函數(shù) : this 指向事件源/* 三:當(dāng)事件被觸發(fā)時,用戶可能是誤操作,所以開啟定時器等一會兒再執(zhí)行注意點: 定時器中的this默認一定是window,需要動態(tài)修改為事件源*/timeID = setTimeout(function () {console.log(1111);// 定時器中的this : 默認指向window//3.排他思想修改樣式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);};};//2.2 鼠標(biāo)移出大盒子,所有的li的寬度都變成默認的240 box.onmouseout = function (e) {/* 由于受到事件冒泡影響,當(dāng)鼠標(biāo)滑出某一個li元素也會觸發(fā)父元素的移出事件解決方案:判斷事件觸發(fā)源是不是box,是的話才修改li元素寬度為240*/if (e.target == box) {for (var i = 0; i < liList.length; i++) {animationSlow(liList[i], { width: 240 });};};};</script></body></html>

3.萬能防抖函數(shù)的封裝

  • 為什么要封裝萬能的防抖函數(shù)
    • 在上一個小節(jié)中,我們的重點是介紹函數(shù)防抖的思路。但是在實際開發(fā)中,每一個防抖函數(shù)的事件處理都是不一樣的,他們可能是鼠標(biāo)移入、鼠標(biāo)移出、鼠標(biāo)移動。 每一個案例需要的防抖間隔也不同
/** * @description: 萬能防抖函數(shù) * @param {type} fn : 事件處理函數(shù) * @param {type} timeout : 防抖時間間隔 * @return: */ function debounce(fn, timeout) {/*核心技術(shù)介紹 1. 函數(shù)防抖需要使用定時器,但是定時器id不能是局部的 (局部變量函數(shù)執(zhí)行完畢會被回收)2. 定時器id如果使用全局變量存儲,則會造成全局變量污染3. 解決方案 :(1)使用閉包延長局部變量聲明周期,但是語法過于繁瑣(2)利用函數(shù)本身也是對象,使用函數(shù)本身的靜態(tài)成員來存儲定時器id*///1.先清除上一次觸發(fā)事件的定時器clearTimeout(debounce.timeID);//2.以最后一次觸發(fā)為準(zhǔn)debounce.timeID = setTimeout(fn, 500); }; <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><title>動畫-案例《手風(fēng)琴》</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>/*需求(1):給每一個li設(shè)置鼠標(biāo)移入事件:當(dāng)前l(fā)i的寬度變成800,其他兄弟li寬度變成100(2):鼠標(biāo)移出大盒子,所有的li的寬度都變成默認的240 *///1.獲取元素var liList = document.querySelectorAll('#box li');//li元素列表var box = document.querySelector('#box');//li元素列表//2.注冊事件//2.1 鼠標(biāo)移入事件:當(dāng)前l(fā)i的寬度變成800,其他兄弟li寬度變成100for (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);};};/*** @description: 萬能防抖函數(shù)* @param {type} fn : 事件處理函數(shù)* @param {type} timeout : 防抖時間間隔* @return: */function debounce(fn, timeout) {/*核心技術(shù)介紹 1. 函數(shù)防抖需要使用定時器,但是定時器id不能是局部的 (局部變量函數(shù)執(zhí)行完畢會被回收)2. 定時器id如果使用全局變量存儲,則會造成全局變量污染3. 解決方案 :(1)使用閉包延長局部變量聲明周期,但是語法過于繁瑣(2)利用函數(shù)本身也是對象,使用函數(shù)本身的靜態(tài)成員來存儲定時器id*///1.先清除上一次觸發(fā)事件的定時器clearTimeout(debounce.timeID);//2.以最后一次觸發(fā)為準(zhǔn)debounce.timeID = setTimeout(fn, 500);};//2.2 鼠標(biāo)移出大盒子,所有的li的寬度都變成默認的240 box.onmouseout = function (e) {/* 由于受到事件冒泡影響,當(dāng)鼠標(biāo)滑出某一個li元素也會觸發(fā)父元素的移出事件解決方案:判斷事件觸發(fā)源是不是box,是的話才修改li元素寬度為240*/if (e.target == box) {for (var i = 0; i < liList.length; i++) {animationSlow(liList[i], { width: 240 });};};};</script></body></html>

總結(jié)

以上是生活随笔為你收集整理的网页性能优化03-函数防抖的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。