欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js防抖-節(jié)流函數的基本實現(xiàn)和補充詳解

 更新時間:2023年01月08日 11:10:31   作者:既白biu  
這篇文章主要介紹了防抖-節(jié)流函數的基本實現(xiàn)和補充,文章從基礎概念到手寫對防抖-節(jié)流函數的實現(xiàn)進行講解,內容詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

前言

防抖和節(jié)流函數是我們在平常開發(fā)的時候,比較常用的兩個工具函數,使用防抖和節(jié)流函數可以提高我們的效率,減小事件觸發(fā)的頻率,可以起到降低服務器壓力的作用。并且在面試時候,這兩個函數也是會經常會被問到,因此,了解防抖和節(jié)流函數的基本原理和應用場景,并且手寫實現(xiàn)這兩個函數至關重要

防抖函數

概念和應用場景

防抖函數:當事件觸發(fā)的時候,并不會立刻執(zhí)行,而是會等待一段事件,當事件密集觸發(fā)時候,函數的觸發(fā)會頻繁的被推遲,只有等待了一段時間也沒有事件觸發(fā),才會真正的執(zhí)行。如下圖所示:

防抖的應用場景很多:

  • 輸入框中頻繁的輸入內容,搜索或者提交信息;
  • 頻繁的點擊按鈕,觸發(fā)某個事件;
  • 監(jiān)聽瀏覽器滾動事件,完成某些特定操作;
  • 用戶縮放瀏覽器的resize事件

案例:

在某個搜索框中輸入自己想要搜索的內容:

比如想要搜索一個MacBook:
當我輸入m時,為了更好的用戶體驗,通常會出現(xiàn)對應的聯(lián)想內容,這些聯(lián)想內容通常是保存在服務器的,所以需要一次網絡請求;當繼續(xù)輸入ma時,再次發(fā)送網絡請求;
那么macbook一共需要發(fā)送7次網絡請求; 這大大損耗我們整個系統(tǒng)的性能,無論是前端的事件處理,還是對于服務器的壓力;

但是我們需要這么多次的網絡請求嗎?

不需要,正確的做法應該是在合適的情況下再發(fā)送網絡請求; 比如如果用戶快速的輸入一個macbook,那么只是發(fā)送一次網絡請求;
比如如果用戶是輸入一個m想了一會兒,這個時候m確實應該發(fā)送一次網絡請求;
也就是我們應該監(jiān)聽用戶在某個時間,比如500ms內,沒有再次觸發(fā)時間時,再發(fā)送網絡請求;
這就是防抖的操作:只有在某個時間內,沒有再次觸發(fā)某個函數時,才真正的調用這個函數;

手寫實現(xiàn)防抖函數

那么如何通過代碼實現(xiàn)防抖的功能呢?

首先,防抖函數應該傳入一個需要實現(xiàn)防抖的函數,還有一個時間,該時間表示在規(guī)定時間內,如果再次觸發(fā)此次事件,則取消上次事件。返回的結果應該是一個執(zhí)行了此功能的函數。

那么整體的框架如下,只需要在_debounce函數里面實現(xiàn)功能即可。

function debounce(fn,delay){
	const _debounce = function(){
	}
	return _debounce
}

函數的參數傳進來一個時間,該時間表示在規(guī)定時間內,如果再次觸發(fā)此次事件,則取消上次事件,所以需要有定時器來記錄時間。并且有取消事件的過程,所以我們需要在滿足條件時候,取消定時器,即clearTimeout,那么還有個問題,fn函數this指向。

如果在_debounce中單獨調用傳進來的函數fn,即以fn()形式直接調用,那么fn是屬于獨立的函數調用,this指向的是window,實際this指向的是調用函數的對象,所以會出現(xiàn)錯誤。

我們知道事件調用的時候,響應函數參數會傳進來一個event事件對象,所以我們要對這個參數(event事件對象)做處理。

那么:

timer定義一個定時器,保存上一次的定時器,在_debounce函數里面,如果timer不為空,那么先清除上一次的定時器,之后再給timer賦值,讓他延遲執(zhí)行fn函數,fn函數用apply改變了this指向,在setTimeout內部使用的是箭頭函數,由于箭頭函數內部沒有this,所以會去上層找this,那么這個this實際上就是調用debounce的對象。

比如輸入框的輸入事件做防抖處理:

const inputEl = document.querySelector(“input”)
inputChange是輸入事件觸發(fā)后所要執(zhí)行的函數,可以給他做防抖處理:const debounceChange = debounce(inputChange,3000),然后執(zhí)行: inputEl.oninput = debounceChange,如果不加防抖處理,毫無疑問,每次在輸入框輸入時候,都會觸發(fā)事件,加了防抖處理后,3秒內多次調用,下一次事件會把上一次事件清除掉。

這里的this通過apply調用后,指向的就是inputEl這個元素,

function debounce(fn, delay) {
  // 1.定義一個定時器, 保存上一次的定時器
  let timer = null

  // 2.真正執(zhí)行的函數
  const _debounce = function(...args) {
    // 取消上一次的定時器
    if (timer) clearTimeout(timer)
    // 延遲執(zhí)行
    timer = setTimeout(() => {
      // 外部傳入的真正要執(zhí)行的函數
      fn.apply(this, args)
    }, delay)
  }

  return _debounce
}

節(jié)流函數

概念和應用場景

節(jié)流函數:當事件執(zhí)行時候,會執(zhí)行這個事件的響應函數;如果這個事件會被頻繁觸發(fā),那么節(jié)流函數會按照一定的頻率來執(zhí)行函數;不管在這個中間有多少次觸發(fā)這個事件,執(zhí)行函數的頻繁總是固定的;如圖所示:

節(jié)流的應用場景:

  • 監(jiān)聽頁面的滾動事件;
  • 鼠標移動事件;
  • 用戶頻繁點擊按鈕操作;
  • 游戲中的一些設計

節(jié)流的具體應用場景:
很多人都玩過類似于飛機大戰(zhàn)的游戲

在飛機大戰(zhàn)的游戲中,我們按下空格會發(fā)射一個子彈:

很多飛機大戰(zhàn)的游戲中會有這樣的設定,即使按下的頻率非???,子彈也會保持一定的頻率來發(fā)射;

比如1秒鐘只能發(fā)射一次,即使用戶在這1秒鐘按下了10次,子彈會保持發(fā)射一顆的頻率來發(fā)射;

但是事件是觸發(fā)了10次的,響應的函數只觸發(fā)了一次

手寫實現(xiàn)節(jié)流函數

那么如何通過代碼實現(xiàn)防抖的功能呢?

首先,我們需要兩個變量記錄當前事件觸發(fā)的時間和上一次的開始時間,函數的參數會傳進來間隔的時間,由此我們可以計算出下次觸發(fā)的最低間隔時間,即為間隔時間-(當前事件觸發(fā)的時間-上次的開始時間),如果間隔時間<=0,那么執(zhí)行fn函數,并且修改上一次的開始時間為當前事件觸發(fā)時間。

function throttle(fn, interval) {
  // 1.記錄上一次的開始時間
  let lastTime = 0

  // 2.事件觸發(fā)時, 真正執(zhí)行的函數
  const _throttle = function(...args) {

    // 2.1.獲取當前事件觸發(fā)時的時間
    const nowTime = new Date().getTime()

    // 2.2.使用當前觸發(fā)的時間和之前的時間間隔以及上一次開始的時間, 計算出還剩余多長事件需要去觸發(fā)函數
    const remainTime = interval - (nowTime - lastTime)
    if (remainTime <= 0) {
      // 2.3.真正觸發(fā)函數
      fn.apply(this,args)
      // 2.4.保留上次觸發(fā)的時間
      lastTime = nowTime
    }
  }

  return _throttle
}

到此這篇關于js防抖-節(jié)流函數的基本實現(xiàn)和補充詳解的文章就介紹到這了,更多相關js防抖節(jié)流函數的實現(xiàn)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 微信小程序常用簡易小函數總結

    微信小程序常用簡易小函數總結

    這篇文章主要介紹了微信小程序常用簡易小函數,結合實例形式總結分析了微信小程序提示、登陸、驗證、session操作等相關操作函數與使用技巧,需要的朋友可以參考下
    2019-02-02
  • JS中去掉if...else的多種方法

    JS中去掉if...else的多種方法

    在JavaScript編程中,過多的if...elseif...else語句可能導致代碼難以維護,可以通過switch語句、對象字面量、函數映射、數組或映射對象分發(fā)、提前返回以及使用數組的find方法來優(yōu)化這種復雜的條件判斷,提高代碼的可讀性和維護性,下面就來介紹一下
    2024-09-09
  • 多個上傳文件用js驗證文件的格式和大小的方法(推薦)

    多個上傳文件用js驗證文件的格式和大小的方法(推薦)

    下面小編就為大家?guī)硪黄鄠€上傳文件用js驗證文件的格式和大小的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • JavaScript中字符串GBK與GB2312的編解碼示例講解

    JavaScript中字符串GBK與GB2312的編解碼示例講解

    在瀏覽器JavaScript環(huán)境中,可以使用TextEncoder和TextDecoder?API?來進行?GBK?編碼和解碼,也可以使用?encodeURIComponent?函數對字符串進行編碼,最好使用第三方庫,比如iconv-lite來實現(xiàn)
    2023-12-12
  • 詳解JVM系列之內存模型

    詳解JVM系列之內存模型

    JVM是一種用于計算設備的規(guī)范,它是一個虛構出來的機器,是通過在實際的計算機上仿真模擬各種功能實現(xiàn)的。JVM的內存區(qū)域可以被分為:線程、棧、堆、靜態(tài)方法區(qū)。本文將介紹JVM的內存模型,感興趣的小伙伴,可以參考下
    2021-06-06
  • JavaScript中this的四個綁定規(guī)則總結

    JavaScript中this的四個綁定規(guī)則總結

    相信大家都知道,ES5及之前時代的JavaScript中this的綁定機制是讓很多開發(fā)者頭疼不已的事情。this 的綁定變化多端,讓筆者也吃了不少虧。所以本文總結了this的四條綁定規(guī)則,在此記錄,以防自己遺忘,也方便他人參考借鑒。下面來一起看看吧。
    2016-09-09
  • Javascript 詳解封裝from表單數據為json串進行ajax提交

    Javascript 詳解封裝from表單數據為json串進行ajax提交

    這篇文章主要介紹了Javascript 詳解封裝from表單數據為json串進行ajax提交的相關資料,需要的朋友可以參考下
    2017-03-03
  • JS實現(xiàn)添加,替換,刪除節(jié)點元素的方法

    JS實現(xiàn)添加,替換,刪除節(jié)點元素的方法

    這篇文章主要介紹了JS實現(xiàn)添加,替換,刪除節(jié)點元素的方法,實例分析了javascript針對節(jié)點元素的替換、刪除及常用的幾種添加技巧,需要的朋友可以參考下
    2016-06-06
  • js二維數組定義和初始化的三種方法總結

    js二維數組定義和初始化的三種方法總結

    本篇文章主要是對js二維數組定義和初始化的三種方法進行了總結介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-03-03
  • 最新熱門腳本Autojs源碼分享

    最新熱門腳本Autojs源碼分享

    AutoJS 是基于一個標準字典庫的文本輸入自動完成 JavaScript 庫。Auto.js 是使用純 JS 實現(xiàn)的,沒有任務外部依賴,大小僅僅 6kb,本文給大家分享最新熱門腳本Autojs源碼,感興趣的朋友一起看看吧
    2021-05-05

最新評論