【问题标题】:clearTimeout does not work the way expectedclearTimeout 无法按预期方式工作
【发布时间】:2019-07-15 03:09:24
【问题描述】:

我正在尝试在原生 JavaScript 中实现去抖动功能。我不确定为什么 clearTimeout 不清除超时对象。在每个事件触发器中,回调函数 setTimeout 如果距离上次调用不超过 5 秒,则清除刚刚创建的超时。但我没有看到超时被清除。

HTML:

<html>

  <head>

  </head>

  <body>
    <div id='move'>

    </div>
    <div id='result'>

    </div>
  </body>

JS:

 var area;
 var result;

 function init() {
   area = document.querySelector('#move');
   area.addEventListener('mousemove', debouce1);
   result = document.querySelector('#result');
 }

 function updateResult(event) {
   let xCordinate = event.clientX;
   let yCordinate = event.clientY;
   result.textContent = `${xCordinate} , ${yCordinate}`;
 }



 function debounce1(fn, time) {
   let firstTime = true;
   let start;
   return function() {
       if (firstTime) {
         fn.apply(null, arguments);
         firstTime = false;
         start = new Date();
       } else {
         let now = new Date();
         let timer = setTimeout(() => {
           fn.apply(null, arguments);
           start = new Date();
         }, time)
         if (now - start < 4000) {
           console.log('too fast');
           clearTimeout(timer);
           console.log(now - start);
           console.log(timer);
           start = new Date();
         }

       }
   }
   init();

【问题讨论】:

  • I don't see the timeout being cleared 您希望如何看到这个?控制台是否显示too fast?然后是一个数字? clearTimeout(timer) 应该“清除”该超时,它不会改变 timer 的值
  • 同样debounce1直接传递给addEventListener,而不是调用它并传递结果。
  • 您是否期望变量timer 在调用clearTimeout(timer) 后会有所不同?
  • startnowinstanceof Date。你需要在那些上面.getTime(),意识到这会给你几毫秒。
  • @JaromandaX:如果我调用 clearTimeout(timer),我是不是没有清除超时?我以为它会清除计时器

标签: javascript


【解决方案1】:

发布的代码存在很多问题。

area.addEventListener('mousemove', debouce1);

这是debounce1 不是debouce1

应该是这样的

area.addEventListener('mousemove', debounce1(updateResult, 1000));

使用null 调用fn.apply 意味着代码失去了调用事件处理程序并将this 设置为侦听器绑定到的元素这一事实

代码在debounce1内调用init

另一个小评论,您可以调用Date.now()performance.now() 来获取表示时间的数字,这可能比创建Date 对象更合适。

也不知道打电话给clearTimeout 有什么意义。

这是debounce1 的另一个实现。它传递最后一组参数和最后一个this。将updateResult 显示为this.id,以便我们检查this 是否适合回调。

'use strict';

const result = document.querySelector('#result');

function init() {
  const area = document.querySelector('#move');
  area.addEventListener('mousemove', debounce1(updateResult, 1000));
}

function updateResult(event) {
  const xCordinate = event.clientX;
  const yCordinate = event.clientY;
  result.textContent = `${this.id}: ${xCordinate} , ${yCordinate}`;
}

function debounce1(fn, time) {
  let lastArgs;
  let lastThis;
  let timeoutQueued;
  let debounceTime = 0;

  return function(...args) {
    lastThis = this;
    lastArgs = [...args];
    if (!timeoutQueued) {
      timeoutQueued = true;
      setTimeout(function() {
        timeoutQueued = false;
        fn.apply(lastThis, lastArgs);
      }, debounceTime);
      debounceTime = time;
    }
  };
};

init();
#move {
  background: red;
  height: 50px;
}
<div id='move'></div>
<div id='result'>

【讨论】:

    猜你喜欢
    • 2018-01-22
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    相关资源
    最近更新 更多