<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # 簡介 當事件被觸發時,設定一個周期延遲執行動作,若期間又被觸發,則重新設定周期,直到周期結束,執行動作。 ![](https://box.kancloud.cn/5aa82c5e25e95846b27e3ebe0dfac9b5_1442x734.png) <br> 為此,我們舉個示例代碼來了解事件如何頻繁的觸發: 我們寫個`index.html`文件: ~~~html <!DOCTYPE html> <html lang="zh-cmn-Hans"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1"> <title>debounce</title> <style> #container{ width: 100%; height: 200px; line-height: 200px; text-align: center; color: #fff; background-color: #444; font-size: 30px; } </style> </head> <body> <div id="container"></div> <script src="debounce.js"></script> </body> </html> ~~~ `debounce.js`文件的代碼如下: ~~~js var count = 1; var container = document.getElementById('container'); function getUserAction() { container.innerHTML = count++; }; container.onmousemove = getUserAction; ~~~ # 基本功能 ~~~ function debounce1(func, wait) { var timmer return function () { clearTimeout(timmer) timmer = setTimeout(func, wait) } } ~~~ <br> <br> # this 丟失修復 如果我們在`getUserAction`函數中`console.log(this)`,在不使用`debounce`函數的時候,`this`的值為: ~~~html <div id="container"></div> ~~~ 但是如果使用我們的 debounce 函數,this 就會指向 Window 對象! 所以我們需要將 this 指向正確的對象。 ~~~ /** * 修復 debounce1 中 func 中的 this 會指向 window */ function debounce2(func, wait) { var timmer return function () { var that = this // 獲取this clearTimeout(timmer) timmer = setTimeout(function () { func.apply(that) //修復 this }, wait) } } ~~~ # event 對象 JavaScript 在事件處理函數中會提供事件對象 event,我們修改下 getUserAction 函數: ~~~js function getUserAction(e) { console.log(e); container.innerHTML = count++; }; ~~~ 如果我們不使用 debouce 函數,這里會打印 MouseEvent 對象 ![](https://box.kancloud.cn/74bbcf3786b957e98455e032dc25b451_1214x66.png) <br> 但是在我們實現的 debounce 函數中,卻只會打印 undefined。修復代碼如下 ~~~ /** * 修復 event 對象指向問題 */ function debounce3(func, wait) { var timmer return function () { var that = this var args = arguments clearTimeout(timmer) timmer = setTimeout(function () { func.apply(that, args) }, wait) } } ~~~ ## 傳參 當要執行的函數需要額外傳參時,要注意函數的this已丟失,需要重新綁定 ~~~ // function getUserAction(event) { // console.log(this) // DOM // console.log(event) // container.innerHTML = count++ // return false // } function getUserAction(...args) { console.log(this) // window console.log(args) // [mouseEvent, 1, 2] container.innerHTML = count++ return false } var setUseAction = debounce(function (event) { console.log(this) // DOM // 重新綁定this // getUserAction.call(this, event, 1, 2) getUserAction(event, 1, 2) }, 500, false) container.onmousemove = setUseAction ~~~ <br> <br> # 立刻執行 有時候我們不希望非要等到事件停止觸發后才執行,而是立刻執行函數,然后等到停止觸發 n 秒后,才可以重新觸發執行。 ![](https://box.kancloud.cn/ea6e24a777ba1487f5ad63aa170cc237_2020x992.png) <br> 可以加個 immediate 參數判斷是否是立刻執行。 ~~~ function debounce4(func, wait, immediate) { var timeout return function () { var context = this var args = arguments if (timeout) clearTimeout(timeout) if (immediate) { // 如果已經執行過,不再執行 var callNow = !timeout timeout = setTimeout(function () { timeout = null }, wait) if (callNow) func.apply(context, args) } else { timeout = setTimeout(function () { func.apply(context, args) }, wait) } } } ~~~ <br> <br> # 返回值 此時注意一點,就是 getUserAction 函數可能是有返回值的,所以我們也要返回函數的執行結果,但是當 immediate 為 false 的時候,因為使用了 setTimeout ,我們將 func.apply(context, args) 的返回值賦給變量,最后再 return 的時候,值將會一直是 undefined,所以我們只在 immediate 為 true 的時候返回函數的執行結果。 ~~~ /** * 返回 func 的返回值 */ function debounce5(func, wait, immediate) { var timeout, result return function () { var context = this var args = arguments if (timeout) clearTimeout(timeout); if (immediate) { var callNow = !timeout timeout = setTimeout(function () { timeout = null }, wait) // 在 immediate 為 true 的時候返回函數的執行結果 if (callNow) result = func.apply(context, args) } else { timeout = setTimeout(function () { func.apply(context, args) }, wait) } return result } } ~~~ <br> <br> # 取消 我們希望能取消 debounce 函數。比如說 debounce 的時間間隔是 10 秒鐘,immediate 為 true,這樣的話,只有等 10 秒后才能重新觸發事件。而我們添加一個按鈕,點擊后能夠取消防抖,立刻就能出發事件。 ~~~ function debounce(func, wait, immediate) { var timeout, result var debounced = function () { var context = this var args = arguments if (timeout) clearTimeout(timeout) if (immediate) { var callNow = !timeout timeout = setTimeout(function () { timeout = null }, wait) if (callNow) result = func.apply(context, args) } else { timeout = setTimeout(function () { func.apply(context, args) }, wait); } return result } // 取消 debounced.cancel = function () { clearTimeout(timeout) timeout = null } return debounced } ~~~ 同時修改demo代碼 ~~~ var count = 1; var container = document.getElementById('container'); function getUserAction(e) { container.innerHTML = count++; }; var setUseAction = debounce(getUserAction, 10000, true); container.onmousemove = setUseAction; document.getElementById("button").addEventListener('click', function(){ setUseAction.cancel(); }) ~~~ <br> <br> # 參考資料 [JavaScript專題之跟著underscore學防抖](https://github.com/mqyqingfeng/Blog/issues/22)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看