在 if 循环中使用 setTimeout 时捕获 setTimeout timerID
capture setTimeout timerID when setTimeout is used in an if loop
我正在使用 setTimeout 在循环中创建一个暂停(在 mouseenter 上)并且需要捕获计时器 ID 以便它可以在 mouseleave 上停止。
我认为这将是一项简单的任务……在我尝试编写代码之前。
我有一个缩略图画廊,将鼠标悬停在缩略图上时,我想循环浏览一系列图像(无限循环);有点像迷你旋转木马。我通过交换缩略图的源文件路径的常用方法来实现这一点;我捕获并存储缩略图的文件路径,循环遍历一组图像,然后在 mouseleave 上替换原始缩略图。没什么复杂的。
我对此进行了编码,一切正常,除了 mouseenter 函数循环遍历整个图像数组,无论鼠标悬停的时间有多短。我最终发现你实际上不能暂停或停止一个函数,但是通过将它包装在一个 setTimeout 中并使用一个布尔标志,你可以创建那个效果。这是我从 user1693593 找到的答案,它非常简单而且效果很好。
var doLoop = false;
function loopy() {
if (doLoop === true) {
setTimeout(function () {
// code to loop through array of images
loopy();
}, 11);
}
};
我正在使用 jQuery 的悬停方法来设置标志。
$(".thumbnails").hover(function() {
doLoop = true;
}, function() {
doLoop = false;
});
所以我把它编码了,当你将鼠标悬停在第一个缩略图上时,它工作得很好,但当你移动到一个新的缩略图时,一切都变得一团糟。我发现这是因为第一个超时没有被取消,随后的超时干扰了它(以及彼此)。我从各种 Stack Overflow 问题中可以看出这是一个常见问题。我发现 setTimeout returns 一个 ID,如果你想用 clearTimeout 取消它,你需要捕获它。
所以我在 MDN setInterval 上找到了一个示例,您可以将超时 ID 存储在一个变量中。它看起来很简单,所以我将其编码并完美运行。当鼠标在缩略图上移动时,我可以在控制台中看到所有超时设置(具有唯一 ID)和取消……但现在我无法让循环工作。
我不明白为什么在 JavaScript 中这么复杂,这肯定是常见的需求。
有人可以可怜一下相关的新手,并解释我如何编写 user1693593 的示例代码,以便在将鼠标悬停在多个元素上时它能正常工作。我不介意它使用setTimeout还是setInterval。
请不要将其标记为重复——如果有人这样做我会理解的——但我已经遍历 Stack Overflow(加上 MDN 和 W3Schools)但我找不到具体回答这个问题的例子问题,肯定不是我能理解的问题。
将引用存储在某处并取消它。
var timer = null
function addOne (elem) {
elem.textContent = (+elem.textContent + .1).toFixed(1)
}
$(".foo")
.on("mouseenter", function () {
var elem = this
timer = window.setInterval(function () { addOne(elem) }, 100)
}).on("mouseleave", function () {
if (timer) window.clearInterval(timer)
})
div.foo {
width:100px;
line-height: 100px;
border: 1px solid black;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="foo">1</div>
<div class="foo">1</div>
<div class="foo">1</div>
<div class="foo">1</div>
<div class="foo">1</div>
只需跟踪当前正在执行循环的元素而不是布尔值 true/false。
var loopEl;
function loopy() {
if (loopEl) {
setTimeout(function () {
// code to loop through array of images
// do something with loopEl
loopy();
}, 11);
}
};
$(".thumbnails").hover(function() {
loopEl = this;
}, function() {
loopEl = false;
});
我正在使用 setTimeout 在循环中创建一个暂停(在 mouseenter 上)并且需要捕获计时器 ID 以便它可以在 mouseleave 上停止。
我认为这将是一项简单的任务……在我尝试编写代码之前。
我有一个缩略图画廊,将鼠标悬停在缩略图上时,我想循环浏览一系列图像(无限循环);有点像迷你旋转木马。我通过交换缩略图的源文件路径的常用方法来实现这一点;我捕获并存储缩略图的文件路径,循环遍历一组图像,然后在 mouseleave 上替换原始缩略图。没什么复杂的。
我对此进行了编码,一切正常,除了 mouseenter 函数循环遍历整个图像数组,无论鼠标悬停的时间有多短。我最终发现你实际上不能暂停或停止一个函数,但是通过将它包装在一个 setTimeout 中并使用一个布尔标志,你可以创建那个效果。这是我从 user1693593 找到的答案,它非常简单而且效果很好。
var doLoop = false;
function loopy() {
if (doLoop === true) {
setTimeout(function () {
// code to loop through array of images
loopy();
}, 11);
}
};
我正在使用 jQuery 的悬停方法来设置标志。
$(".thumbnails").hover(function() {
doLoop = true;
}, function() {
doLoop = false;
});
所以我把它编码了,当你将鼠标悬停在第一个缩略图上时,它工作得很好,但当你移动到一个新的缩略图时,一切都变得一团糟。我发现这是因为第一个超时没有被取消,随后的超时干扰了它(以及彼此)。我从各种 Stack Overflow 问题中可以看出这是一个常见问题。我发现 setTimeout returns 一个 ID,如果你想用 clearTimeout 取消它,你需要捕获它。
所以我在 MDN setInterval 上找到了一个示例,您可以将超时 ID 存储在一个变量中。它看起来很简单,所以我将其编码并完美运行。当鼠标在缩略图上移动时,我可以在控制台中看到所有超时设置(具有唯一 ID)和取消……但现在我无法让循环工作。
我不明白为什么在 JavaScript 中这么复杂,这肯定是常见的需求。
有人可以可怜一下相关的新手,并解释我如何编写 user1693593 的示例代码,以便在将鼠标悬停在多个元素上时它能正常工作。我不介意它使用setTimeout还是setInterval。
请不要将其标记为重复——如果有人这样做我会理解的——但我已经遍历 Stack Overflow(加上 MDN 和 W3Schools)但我找不到具体回答这个问题的例子问题,肯定不是我能理解的问题。
将引用存储在某处并取消它。
var timer = null
function addOne (elem) {
elem.textContent = (+elem.textContent + .1).toFixed(1)
}
$(".foo")
.on("mouseenter", function () {
var elem = this
timer = window.setInterval(function () { addOne(elem) }, 100)
}).on("mouseleave", function () {
if (timer) window.clearInterval(timer)
})
div.foo {
width:100px;
line-height: 100px;
border: 1px solid black;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="foo">1</div>
<div class="foo">1</div>
<div class="foo">1</div>
<div class="foo">1</div>
<div class="foo">1</div>
只需跟踪当前正在执行循环的元素而不是布尔值 true/false。
var loopEl;
function loopy() {
if (loopEl) {
setTimeout(function () {
// code to loop through array of images
// do something with loopEl
loopy();
}, 11);
}
};
$(".thumbnails").hover(function() {
loopEl = this;
}, function() {
loopEl = false;
});