为什么在此设置中超时未被清除?我如何弥补()阻止延迟动作的运行?
var active = false;
var delay;
window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);
function down(e) {
active = true;
console.log("down")
window.scrollTo(0,document.body.scrollHeight);
}
function up(e) {
active = false;
clearTimeout(delay); //expecting this to clear delay
console.log("up")
window.scrollTo(0,document.body.scrollHeight);
}
function move(e) {
if (active) {
delay = setTimeout(function() {
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
}, 50);
}
}期望在mouseup上清除延迟,但它仍然执行。
发布于 2019-10-20 00:49:53
因此,我从答复中了解到,每次执行setTimeout时,move()都会生成一个新的独立计时器。我的理解是,每一个新计时器都会覆盖前一个定时器,但由于情况并非如此,我不得不考虑其他的事情。
我并没有真正解释我到底需要做些什么来拖延时间,所以让我澄清一下。如果某个动作有x段时间没有执行,我想为该操作创建一个超时。通过对操作使用setTimeout,它自己创建了一个问题,即即使在mouseup事件之后,该操作仍然可能有多个排队的执行等待发生。
因此,我在一个新变量上使用了setTimeout,该变量充当操作的锁。结果是以下代码:
var active = false;
var actionTimeout = false;
var actionTimeStamp;
var actionLock = false;
window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);
function down(e) {
active = true;
console.log("down")
window.scrollTo(0,document.body.scrollHeight);
}
function up(e) {
active = false;
console.log("up")
window.scrollTo(0,document.body.scrollHeight);
}
function move(e) {
if (active) {
if ((Date.now() - actionTimeStamp > 500) && (!actionTimeout)) { // get time elapsed and compare to threshold (500ms)
actionTimeout = true; //this is for the if statement above to prevent multiple timeouts
actionLock = false; // set the lock
setTimeout(function() { // remove lock after 50ms
actionTimeout = false;
actionLock = true;
actionTimeStamp = Date.now(); // timestamp here to make sure we don't lock again to soon. (helps if setTimeout is => than threshold.
}, 50);
}
if (actionLock) { //do our action
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
actionTimeStamp = Date.now(); // timestamp last execution
}
}
}感谢每一个人在评论和回答中插嘴。真的很感激。
发布于 2019-10-14 21:02:27
你每次动作都要暂停。它不能取代最后一个..。
您的代码基本上如下
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- cancels this one
window.clearTimeout(delay)所以你需要在创建一个新的
if (active) {
if (delay) window.clearTimeout(delay)
delay = setTimeout(function() {
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
}, 50);
}如果您需要移动到触发不止一次,您想查看节流脚本。
发布于 2019-10-14 21:12:27
答案:
在您的代码中有一些事情需要调整:
与使用新的Interval.
delay不同的是,中的多个定时器。
关于JavaScript中的计时器,有几件事需要调整和理解:
undefined --它保持不变的整数/ ID。这是因为您没有清除变量,作用域是停止与变量所在的ID匹配的计时器。由于上述原因,undefined (或其他一些falsy值),然后清除该变量才能正常工作。
var active = false;
var delay;
window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);
function down(e) {
active = true;
console.log("down")
window.scrollTo(0,document.body.scrollHeight);
}
function up(e) {
active = false;
clearTimeout(delay); //expecting this to clear delay
delay = undefined;
console.log("up")
window.scrollTo(0,document.body.scrollHeight);
}
function move(e) {
if (active) {
if(!delay) {
delay = setInterval(function() {
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
}, 50);
}
}
else { //fallback in case of Browser Queuing issues
if(delay) {
clearTimeout(delay);
delay = undefined;
}
}
}
编辑的
由于对问题的评论,我在mousemove中添加了一个回退,如果状态是非活动的,它将移除计时器,但是仍然定义了delay。我不认为您在技术上应该需要这样做,但实际上,浏览器事件队列和计时器有时并不像预期的那样进行。
https://stackoverflow.com/questions/58383928
复制相似问题