setTimeout 在我的循环 javascript 幻灯片函数中工作一段时间,然后停止延迟

发布于 2024-11-19 22:09:54 字数 8259 浏览 5 评论 0原文

我的幻灯片已经经历了多次迭代,但始终没有摆脱这个问题。它将按预期运行一段时间,然后突然开始切换幻灯片,没有任何延迟。如果没有动画,它可能会以光速运行...

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尴尬癌患者 2024-11-26 22:09:54

找到了!事实证明这是浏览器/Javascript 问题。我没有意识到 jQuery 默认情况下如何对所有动画进行排队。

所以,首先,页面加载,一切都很好。没有时间问题。然后我转到另一个选项卡并保持页面打开。这就是这个问题的根源。浏览器以某种方式锁定了 jQuery,使其无法在需要时使用 CSS 更改来设置动画效果(虽然不是立即)。但与此同时,Javascript 计时器确实继续运行。 jQuery 一直在构建一个未执行动画的队列。当您重新打开选项卡时,浏览器将让 jQuery 发挥其作用,并开始连续运行所有排队的动画。此时计时器脚本仍在运行,但它只能将更改添加到队列中。所以看来计时器已经失败了。

修复

我将: 更改

$("#Banner").animate({left:-image_reelPosition},900);//Next slide animation

为:

$("#Banner").stop().animate({left:-image_reelPosition},900);//Next slide animation

就这样,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:

$("#Banner").animate({left:-image_reelPosition},900);//Next slide animation

to:

$("#Banner").stop().animate({left:-image_reelPosition},900);//Next slide animation

And that's it, jQuery knows that building a queue is not desirable for some animations, so it includes a fix.

凉城已无爱 2024-11-26 22:09:54

我发现的一件事是,您多次调用 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 whether Pause 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文