国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript函數(shù)節(jié)流和函數(shù)去抖知識(shí)點(diǎn)學(xué)習(xí)

2019-11-19 13:23:00
字體:
供稿:網(wǎng)友

概念

節(jié)流 (throttle) 讓一個(gè)函數(shù)不要執(zhí)行的太頻繁,減少執(zhí)行過快的調(diào)用,叫節(jié)流

去抖 (debounce) 去抖就是對(duì)于一定時(shí)間段的連續(xù)的函數(shù)調(diào)用,只讓其執(zhí)行一次

throttle 應(yīng)用場(chǎng)景

  • DOM 元素的拖拽功能實(shí)現(xiàn)(mousemove)
  • 射擊游戲的 mousedown/keydown 事件(單位時(shí)間只能發(fā)射一顆子彈)
  • 計(jì)算鼠標(biāo)移動(dòng)的距離(mousemove)
  • Canvas 模擬畫板功能(mousemove
  • 搜索聯(lián)想(keyup
  • 監(jiān)聽滾動(dòng)事件判斷是否到頁面底部自動(dòng)加載更多:給 scroll 加了 debounce 后,只有用戶停止?jié)L動(dòng)后,才會(huì)判斷是否到了頁面底部;如果是 throttle 的話,只要頁面滾動(dòng)就會(huì)間隔一段時(shí)間判斷一次

debounce 應(yīng)用場(chǎng)景

每次 resize/scroll 觸發(fā)統(tǒng)計(jì)事件

文本輸入的驗(yàn)證(連續(xù)輸入文字后發(fā)送 AJAX 請(qǐng)求進(jìn)行驗(yàn)證,驗(yàn)證一次就好)

函數(shù)去抖的實(shí)現(xiàn)

我們以scroll事件為例,探究如何是實(shí)現(xiàn)滾動(dòng)一次窗口打印一個(gè)hello world 字符串。 如果不對(duì)其節(jié)流或者去抖:

window.onscroll = function () { console.log('hello world');}

這樣每滾動(dòng)一次,實(shí)際上會(huì)打印多個(gè) hello world。 函數(shù)去抖背后的思路是指,某些代碼不可能在沒有間斷的情況下連續(xù)執(zhí)行。創(chuàng)建一個(gè)定時(shí)器,在指定的時(shí)間間隔之后運(yùn)行代碼。當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會(huì)清除前一次的定時(shí)器并設(shè)置另一個(gè)。如果前一個(gè)定時(shí)器已經(jīng)執(zhí)行過了,這個(gè)操作就沒有任何意義。然而,如果前一個(gè)定時(shí)器尚未執(zhí)行,其實(shí)就是將其替換為一個(gè)新的定時(shí)器。目的是只有在執(zhí)行函數(shù)的請(qǐng)求停止了一段時(shí)間之后才執(zhí)行。

《高程三》給出了最簡潔最經(jīng)典的去抖代碼,如下:

function debounce(method, context) { clearTimeout(method.tId); method.tId = setTimeout(function() { method.call(context); }, 1000);}function print() { console.log('hello world');}window.onscroll = function() { debounce(print);};

再做一些改動(dòng)

function debounce(delay, action) { var tId; return function () {  var context = this;  var arg = arguments;  if (tId) clearTimeout(tId);  tId = setTimeout(function () {   action.apply(context, arg);  }, delay); }}window.onscroll = debounce(1000, print);

函數(shù)節(jié)流的實(shí)現(xiàn)

函數(shù)節(jié)流就是讓連續(xù)執(zhí)行的函數(shù),變?yōu)楣潭〞r(shí)間段間斷地執(zhí)行。 大概有兩種方式實(shí)現(xiàn)。

其一使用時(shí)間戳來判斷是否已經(jīng)到回調(diào)執(zhí)行時(shí)間,記錄上次執(zhí)行的時(shí)間戳,然后每次觸發(fā)事件時(shí)執(zhí)行回調(diào),回調(diào)中判斷當(dāng)前時(shí)間戳距離上次執(zhí)行時(shí)間戳的時(shí)間間隔是否有*s,如果是,則執(zhí)行,并更新上次執(zhí)行的時(shí)間戳,如此循環(huán)。

var throttle = function(delay, action) { var last = 0; return function() {  var curr = new Date();  if (curr - last > delay) {   action.apply(this, arguments);   last = curr;  } }}

第二種方法是使用定時(shí)器,比如,當(dāng)scroll事件剛觸發(fā)時(shí),打印一個(gè)hello world ,然后設(shè)置一個(gè)1000ms的定時(shí)器,此后每次觸發(fā)scroll事件,觸發(fā)回調(diào),如果已經(jīng)存在定時(shí)器,則回調(diào)不執(zhí)行方法,知道定時(shí)器出發(fā),handler被清除,然后重新設(shè)置定時(shí)器。

var throttle = function(delay, action) { var timeout; var later = function () {  timeout = setTimeout(function(){   clearTimeout(timeout);   // 解除引用   timeout = null;  }, delay); }; later(); if (!timeout) {  action.apply(this, arguments);  later(); }}

更新方法:

function throttlePro(delay, action) { var tId; return function () {  var context = this;  var arg = arguments;  if (tId) return;  tId = setTimeout(function () {   action.apply(context, arg);   clearTimeout(tId);   // setTimeout 返回一個(gè)整數(shù),clearTimeout 之后,tId還是那個(gè)整數(shù),setInterval同樣如此   tId = null;  }, delay); }}

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 古丈县| 英山县| 昭平县| 博野县| 荔浦县| 永春县| 孟村| 句容市| 肇庆市| 都兰县| 娄烦县| 高邮市| 马山县| 甘泉县| 西乡县| 息烽县| 永德县| 宁南县| 北海市| 邓州市| 灯塔市| 新巴尔虎右旗| 东乌| 古蔺县| 漳州市| 英超| 拜城县| 汉川市| 右玉县| 南华县| 德化县| 平利县| 鄂托克前旗| 宣化县| 桐柏县| 保康县| 信阳市| 封丘县| 夹江县| 西平县| 章丘市|