setTimeout 在我的循环 javascript 幻灯片函数中工作一段时间,然后停止延迟
我的幻灯片已经经历了多次迭代,但始终没有摆脱这个问题。它将按预期运行一段时间,然后突然开始切换幻灯片,没有任何延迟。如果没有动画,它可能会以光速运行...
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<meta name="Description" content="Calvary Chapel Chico is a non-denominational,Bible-believing church established to worship,glorify,and share the good news of our Lord and Savior,Jesus Christ." />
<title>Calvary Chapel Chico</title>
<!--<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Droid+Sans:regular,bold"/>-->
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<div id="Top450">
<div id="TitleBar">
<div id="Logo"></div>
<h1>Calvary Chapel Chico</h1>
<a id="Login" href="">Login</a>
</div>
<div id="SlideShow">
<div id="Banner">
<div id="SMedia">Insert Media Links Here</div>
<div id="SMinistries">Insert Ministry links Here</div>
<div id="SServiceTimes">Insert Service Times Here</br><div style="background:#fff;">TEST</div></div>
<div id="SWelcome">Welcome to</br><span id="WelcomeText">Calvary Chapel Chico Online</span></div>
<a id="S5" href="2.html">2</a>
<a id="S6" href="2.html">3</a>
<a id="S7" href="2.html">4</a>
</div>
</div>
<div id="MenuBar">
<div class="Pages">
<a id="Home" href="2.html" class="current">Home</a>
<a id="About" href="2.html">About</a>
<a id="Media" href="#" rel="1" class="SlidePage">Media</a>
<a id="Ministries" href="#" rel="2" class="SlidePage">Ministries</a>
<a id="ServiceTimes" href="#" rel="3" class="SlidePage">Service Times & Directions</a>
</div>
<div class="BannerButtons">
<a href="#" rel="4"></a>
<a href="#" rel="5"></a>
<a href="#" rel="6"></a>
<a href="#" rel="7"></a>
</div>
</div>
</div>
<div id="Body">
<div id="Left300">
<div id="LeftTopTabs" class="Tabs">
<div id="LeftTopTabBar" class="TabBar">
<a href="#LTT-1">News</a>
<a href="#LTT-2">Media</a>
<a href="#LTT-3">Calendar</a>
</div>
<div id="LeftTopPanes" class="Panes">
<div id="LTT-1">Lorem ipsum dolor sit amet</div>
<div id="LTT-2">Nunc in tempor sem.</div>
<div id="LTT-3">Sed diam nisl,</div>
</div>
</div>
</div>
<div id="Right700">
Lorem ipsum dolor sit amet
</div>
</div>
<div id="Bottom450">
</div>
</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="scripts.js"></script>
</html>
javascript:
$(
function() {
//===================================================================================================================================
//Setup
//===================================================================================================================================
//Initialize variables
var Pause
var NextSlide
var RepeatTimer
var SlideshowTimer
var $CurrentSlide
//Slideshow setup
$(".BannerButtons a:first").addClass("current");//Force the first slide's button to be the "CurrentSlide"
$(".BannerButtons").show();
var SlideWidth=$("#SlideShow").width();
$("#Banner").css({'width':[SlideWidth*[$("#Banner>*").size()]]});
//Tabs setup
var $CurrentTab=$(".TabBar a:first").next();
//===================================================================================================================================
//Slideshow Functions
//===================================================================================================================================
//Move to the Next Slide
NextSlide=function(){
var image_reelPosition=[$CurrentSlide.attr("rel")-1]*SlideWidth;//Computes distance to the left edge of the slide in pixels
$(".BannerButtons a,.SlidePage").removeClass("current");//Make the old "CurrentSlide" no longer the "CurrentSlide"
$("#Banner").animate({left:-image_reelPosition},900);//Next slide animation
$CurrentSlide.addClass("current");//Make the new "CurrentSlide" current
};
//Repeat slide changes
RepeatTimer=function(){
$CurrentSlide=$('.BannerButtons a.current').next();//Make the next "CurrentSlide" current
if($CurrentSlide.length===0){$CurrentSlide=$('.BannerButtons a:first');};//If end of buttons is reached, go back to the beginning
NextSlide();//Go to the next slide
SlideshowTimer();
};
//Repeat slide changes every 10 seconds
SlideshowTimer=function(){
clearTimeout(Pause);//Clear the timer
Pause=setTimeout(RepeatTimer,10000);//Reset the timer
};
//Hover
$("#Banner").hover(
function(){//Hover trigger
clearTimeout(Pause);//Clear the timer
},function(){//Cease to hover trigger
Pause=setTimeout(RepeatTimer,2000);//Reset the timer
});
//Click
$(".BannerButtons a,.SlidePage").click(
function(){
$CurrentSlide=$(this);//Make the clicked object the "CurrentSlide"
clearTimeout(Pause);//Clear the timer
NextSlide();//Go to the clicked slide
SlideshowTimer();//Reset the timer
return false;//Keep the # out of the URL
}
);
//===================================================================================================================================
//Tab Functions
//===================================================================================================================================
//Move to the clicked tab
ChangeTab=function(){
$(".TabBar>a").removeClass("current");
$CurrentTab.addClass("current");//Force the first slide's button to be the "CurrentTab"
$CurrentPane=$($CurrentTab.attr("href"));
$(".Panes>div").addClass("HiddenPane");
$CurrentPane.removeClass("HiddenPane");
};
//Click
$(".TabBar>a").click(
function(){
$CurrentTab=$(this);//Make the clicked object the "CurrentSlide"
ChangeTab();//Go to the clicked tab
return false;//Keep the # out of the URL
}
);
//===================================================================================================================================
//Start Slide Show
SlideshowTimer();
//Initialize Tabs
ChangeTab();
//END
}
);
My slideshow has gone through several iterations, but it has never shaken off this issue. It will run for a while as expected, then suddenly begin switching slides without any delay. If it weren't for the animation it'd probably run at light-speed...
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<meta name="Description" content="Calvary Chapel Chico is a non-denominational,Bible-believing church established to worship,glorify,and share the good news of our Lord and Savior,Jesus Christ." />
<title>Calvary Chapel Chico</title>
<!--<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Droid+Sans:regular,bold"/>-->
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<div id="Top450">
<div id="TitleBar">
<div id="Logo"></div>
<h1>Calvary Chapel Chico</h1>
<a id="Login" href="">Login</a>
</div>
<div id="SlideShow">
<div id="Banner">
<div id="SMedia">Insert Media Links Here</div>
<div id="SMinistries">Insert Ministry links Here</div>
<div id="SServiceTimes">Insert Service Times Here</br><div style="background:#fff;">TEST</div></div>
<div id="SWelcome">Welcome to</br><span id="WelcomeText">Calvary Chapel Chico Online</span></div>
<a id="S5" href="2.html">2</a>
<a id="S6" href="2.html">3</a>
<a id="S7" href="2.html">4</a>
</div>
</div>
<div id="MenuBar">
<div class="Pages">
<a id="Home" href="2.html" class="current">Home</a>
<a id="About" href="2.html">About</a>
<a id="Media" href="#" rel="1" class="SlidePage">Media</a>
<a id="Ministries" href="#" rel="2" class="SlidePage">Ministries</a>
<a id="ServiceTimes" href="#" rel="3" class="SlidePage">Service Times & Directions</a>
</div>
<div class="BannerButtons">
<a href="#" rel="4"></a>
<a href="#" rel="5"></a>
<a href="#" rel="6"></a>
<a href="#" rel="7"></a>
</div>
</div>
</div>
<div id="Body">
<div id="Left300">
<div id="LeftTopTabs" class="Tabs">
<div id="LeftTopTabBar" class="TabBar">
<a href="#LTT-1">News</a>
<a href="#LTT-2">Media</a>
<a href="#LTT-3">Calendar</a>
</div>
<div id="LeftTopPanes" class="Panes">
<div id="LTT-1">Lorem ipsum dolor sit amet</div>
<div id="LTT-2">Nunc in tempor sem.</div>
<div id="LTT-3">Sed diam nisl,</div>
</div>
</div>
</div>
<div id="Right700">
Lorem ipsum dolor sit amet
</div>
</div>
<div id="Bottom450">
</div>
</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="scripts.js"></script>
</html>
javascript:
$(
function() {
//===================================================================================================================================
//Setup
//===================================================================================================================================
//Initialize variables
var Pause
var NextSlide
var RepeatTimer
var SlideshowTimer
var $CurrentSlide
//Slideshow setup
$(".BannerButtons a:first").addClass("current");//Force the first slide's button to be the "CurrentSlide"
$(".BannerButtons").show();
var SlideWidth=$("#SlideShow").width();
$("#Banner").css({'width':[SlideWidth*[$("#Banner>*").size()]]});
//Tabs setup
var $CurrentTab=$(".TabBar a:first").next();
//===================================================================================================================================
//Slideshow Functions
//===================================================================================================================================
//Move to the Next Slide
NextSlide=function(){
var image_reelPosition=[$CurrentSlide.attr("rel")-1]*SlideWidth;//Computes distance to the left edge of the slide in pixels
$(".BannerButtons a,.SlidePage").removeClass("current");//Make the old "CurrentSlide" no longer the "CurrentSlide"
$("#Banner").animate({left:-image_reelPosition},900);//Next slide animation
$CurrentSlide.addClass("current");//Make the new "CurrentSlide" current
};
//Repeat slide changes
RepeatTimer=function(){
$CurrentSlide=$('.BannerButtons a.current').next();//Make the next "CurrentSlide" current
if($CurrentSlide.length===0){$CurrentSlide=$('.BannerButtons a:first');};//If end of buttons is reached, go back to the beginning
NextSlide();//Go to the next slide
SlideshowTimer();
};
//Repeat slide changes every 10 seconds
SlideshowTimer=function(){
clearTimeout(Pause);//Clear the timer
Pause=setTimeout(RepeatTimer,10000);//Reset the timer
};
//Hover
$("#Banner").hover(
function(){//Hover trigger
clearTimeout(Pause);//Clear the timer
},function(){//Cease to hover trigger
Pause=setTimeout(RepeatTimer,2000);//Reset the timer
});
//Click
$(".BannerButtons a,.SlidePage").click(
function(){
$CurrentSlide=$(this);//Make the clicked object the "CurrentSlide"
clearTimeout(Pause);//Clear the timer
NextSlide();//Go to the clicked slide
SlideshowTimer();//Reset the timer
return false;//Keep the # out of the URL
}
);
//===================================================================================================================================
//Tab Functions
//===================================================================================================================================
//Move to the clicked tab
ChangeTab=function(){
$(".TabBar>a").removeClass("current");
$CurrentTab.addClass("current");//Force the first slide's button to be the "CurrentTab"
$CurrentPane=$($CurrentTab.attr("href"));
$(".Panes>div").addClass("HiddenPane");
$CurrentPane.removeClass("HiddenPane");
};
//Click
$(".TabBar>a").click(
function(){
$CurrentTab=$(this);//Make the clicked object the "CurrentSlide"
ChangeTab();//Go to the clicked tab
return false;//Keep the # out of the URL
}
);
//===================================================================================================================================
//Start Slide Show
SlideshowTimer();
//Initialize Tabs
ChangeTab();
//END
}
);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
找到了!事实证明这是浏览器/Javascript 问题。我没有意识到 jQuery 默认情况下如何对所有动画进行排队。
所以,首先,页面加载,一切都很好。没有时间问题。然后我转到另一个选项卡并保持页面打开。这就是这个问题的根源。浏览器以某种方式锁定了 jQuery,使其无法在需要时使用 CSS 更改来设置动画效果(虽然不是立即)。但与此同时,Javascript 计时器确实继续运行。 jQuery 一直在构建一个未执行动画的队列。当您重新打开选项卡时,浏览器将让 jQuery 发挥其作用,并开始连续运行所有排队的动画。此时计时器脚本仍在运行,但它只能将更改添加到队列中。所以看来计时器已经失败了。
修复
我将: 更改
为:
就这样,jQuery 知道构建队列对于某些动画来说是不可取的,因此它包含了一个修复。
Found it! Turns out it was a Browser/Javascript issue. I didn't realize just how jQuery queues up all the animations by default.
So, first off, page loaded, everything was fine. No timing issues. Then I go to another tab and leave my page open. That's where this is stemming from. The browser somehow is locking jQuery out of animating the animations (not immediately though) with CSS changes when it wants to. But at the same time the Javascript timer does continue. All the while jQuery is building a queue of un-performed animations. When you reopen the tab the browser let's jQuery have its way and begins running all the queued animation back-to-back. At which point the timer script is still running, but it only gets to add changes to the queue. And so it appears that the timer has failed.
THE FIX
I changed:
to:
And that's it, jQuery knows that building a queue is not desirable for some animations, so it includes a fix.
我发现的一件事是,您多次调用
clearTimeout(Pause)
而不知道Pause
是否是有效且活动的计时器ID。在许多情况下,您使用早已完成的旧计时器 ID 来调用它(因此不再有效)。操作系统可能会容忍这种情况,但它可能会再次导致一些问题。通常,解决此问题的方法是每当计时器触发或清除计时器时将timerID变量设置为null,然后在调用clearTimeout之前检查是否为null。
另外,正如 nnnnnn 在他们的评论中所说,将鼠标放在幻灯片上会将计时器时间从 10 秒减少到 2 秒。如果你有一个 2 秒的动画,那几乎就是整个时间。
我建议创建一个用于设置幻灯片计时器的函数和一个用于清除幻灯片计时器的函数,然后您可以集中管理计时器 ID 和计时器设置的时间。
我的猜测是,核心问题是悬停时的 2 秒问题,但您也应该清理您的 timeID 管理。
One thing I see is that you're calling
clearTimeout(Pause)
a lot without knowing whetherPause
is a valid and active timerID. In many cases, you're calling it with an old timerID that has long since finished (and thus is no longer valid). The OS may tolerate that, but then again it could cause some issues.Usually, the solution to this is to set the timerID variable to null whenever your timer fires or you clear the timer and then check for null before calling clearTimeout.
Also, as nnnnnn said in their comment, putting the mouse over the slideshow will drop the timer time from 10 seconds to 2 seconds. If you had a 2 second animation, that would be nearly the entire time.
I'd recommend making a function for setting the slide timer and a function for clearing the slide timer and then you can centralize the management of both the timer ID and the time that the timer is set for.
My guess is that the core problem is the 2 second issue on hover, but you should clean up your timerID management too.