clearTimeout无法按预期方式工作

时间:2019-07-15 03:09:24

标签: javascript

我正在尝试在原始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();

1 个答案:

答案 0 :(得分:-1)

发布的代码有很多问题。

area.addEventListener('mousemove', debouce1);

debounce1而不是debouce1

应该是类似

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

使用fn.apply调用null意味着代码失去了以下事实:使用设置为侦听器绑定的元素的this来调用事件处理程序

代码正在init内部调用debounce1

另一个小注释,您可以调用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'>