【发布时间】:2021-09-28 22:00:26
【问题描述】:
我编写了一个选项卡功能,可以在一段时间后在选项卡之间切换,这似乎工作得很好,但是我注意到它有时会中断。
在查看setInterval 并查看错误本身后,它在 20-30 分钟后看起来像 setInterval,会自行跳闸并启动第二个计时器。这会导致同时显示 2 个选项卡。
我在网上读到了一点,基本上它与 Javascript 是单线程的有关,这只是 setInterval 的一个基本缺陷,如果它跳闸,它不会重置计时器,它只会创建第二个。是否有为此行程添加错误捕获或运行重复超时功能的更好方法?
jQuery(document).ready(function() {
function autoPlayTabs(tabTitle1, tabTitle2, tabTitle3, tabTitle4, tabContent1, tabContent2, tabContent3, tabContent4, tabLength, tabTitleMobile1, tabTitleMobile2, tabTitleMobile3, tabTitleMobile4) {
var actualTabLength = tabLength * 4;
var tabContainer = jQuery('.elementor-tabs');
var allTabs = jQuery('.elementor-tabs .elementor-tabs-wrapper .elementor-tab-title');
var allContent = jQuery('.elementor-tabs .elementor-tabs-content-wrapper .elementor-tab-content');
var initialTabTimer = null;
var tabTimer = null;
tabTitle1.addClass('active'); tabContent1.addClass('active');
console.log('Setting initialTabTimer');
initialTabTimer = setTimeout(function(){
tabTitle1.removeClass('active'); tabContent1.removeClass('active');
tabTitle2.addClass('active'); tabContent2.addClass('active');
console.log("Setting Timeout2");
setTimeout(function(){
tabTitle2.removeClass('active'); tabContent2.removeClass('active');
tabTitle3.addClass('active'); tabContent3.addClass('active');
console.log("Setting Timeout3");
setTimeout(function(){
tabTitle3.removeClass('active'); tabContent3.removeClass('active');
tabTitle4.addClass('active'); tabContent4.addClass('active');
console.log("Executing Timeout3 Function");
}, tabLength);
}, tabLength);
}, tabLength);
console.log("Setting tabTimer");
tabTimer = setInterval(function(){
tabTitle4.removeClass('active'); tabContent4.removeClass('active');
tabTitle1.addClass('active'); tabContent1.addClass('active');
console.log("Setting TimeoutB");
setTimeout(function(){
tabTitle1.removeClass('active'); tabContent1.removeClass('active');
tabTitle2.addClass('active'); tabContent2.addClass('active');
console.log("Setting TimeoutC");
setTimeout(function(){
tabTitle2.removeClass('active'); tabContent2.removeClass('active');
tabTitle3.addClass('active'); tabContent3.addClass('active');
console.log("Setting TimeoutD");
setTimeout(function(){
tabTitle3.removeClass('active'); tabContent3.removeClass('active');
tabTitle4.addClass('active'); tabContent4.addClass('active');
console.log("Executing TimeoutD Function");
}, tabLength);
}, tabLength);
}, tabLength);
}, actualTabLength);
allTabs.click(function() {
if (initialTabTimer !== null) {
clearTimeout(initialTabTimer);
initialTabTimer = null;
console.log("Cleared initialTabTimer");
}
if (tabTimer !== null) {
clearInterval(tabTimer);
tabTimer = null;
console.log("Cleared tabTimer");
} else {
console.log("Did not need to clear tabTimer");
}
allTabs.removeClass('active');
allContent.removeClass('active');
tabContainer.addClass('tabsManual');
});
}
if(homeTabTitle1.length > 0){
console.log("Calling AutoPlayTabs Homepage");
autoPlayTabs(homeTabTitle1,homeTabTitle2,homeTabTitle3,homeTabTitle4,homeTabContent1,homeTabContent2,homeTabContent3,homeTabContent4,homeTabLength);
}
});
下面是一个 console.log,其中包含从它工作到中断到修复自身调用的每个 setTimeout:
Calling AutoPlayTabs Homepage
Setting initialTabTimer
Setting tabTimer
Setting Timeout2
Setting Timeout3
Executing Timeout3 Function
//This console.log block ran 30 times without error//
Setting TimeoutB
Setting TimeoutC
Setting TimeoutD
Executing TimeoutD Function
//This console.log block ran 30 times without error//
//It Breaks here after a total of 24 minutes//
Setting TimeoutB
Setting TimeoutC
Setting TimeoutD
Setting TimeoutB //For some reason TimeoutB has been fired again
Executing TimeoutD Function
Setting TimeoutC
Setting TimeoutD
Setting TimeoutB
Executing TimeoutD Function
Setting TimeoutC
Setting TimeoutD
Executing TimeoutD Function
//It fixed itself here after 2.4 minutes//
Setting TimeoutB
Setting TimeoutC
Setting TimeoutD
Executing TimeoutD Function
【问题讨论】:
-
您能否提供该问题的工作示例,包括所有相关的 HTML 和 CSS。我问,因为 JS 计时器是出了名的不准确,尤其是在长时间运行时。您的问题很可能可以使用 CSS 动画以更简单、更高效的方式避免和解决,或者至少不需要 7 个嵌套计时器。
-
setInterval()不会“绊倒”。 -
autoPlayTabs()是否有任何更改不止一次触发?如果您可以重现错误,请在该函数中放置一个 console.log,以便您可以观察该函数是否被再次调用... -
定时器是不准确的,因为当你要求它们(必要的)时它们不会精确地触发。然而,一个自发启动另一个自身副本的
setInterval()设置将是一个严重的浏览器错误。 -
看起来它是由
setInterval和setTimeout混合引起的 - 如果您考虑实际超时的 1% 差异,那么您可以看到它不会那么长,直到 @987654331 @ 将更频繁地运行 4xsetTimeout(t)- 将您的外部 setInterval 更改为 setTimeout 并在第 4 次之后重新启动它。或者,重构,因此您只需要一次超时,问题就会消失(同时使您的代码更易于维护)
标签: javascript jquery setinterval