setTimeout 在几分钟后变得疯狂,FF6.0,Chrome 15

发布于 2024-12-01 03:20:56 字数 3024 浏览 0 评论 0原文

看看我的新闻滚轮:现场演示

一切正常完美,直到您将 scipt 留在选项卡中几分钟。

发生的事情看起来浏览器每 5 秒就会丢失一次计数,并且不断执行操作。

我猜它与和设置超时

有什么建议如何修复它吗?

脚本:

(function($) {

$.fn.NoticeBoard = function() {


    // Set a timeout
    var timeOut = setTimeout(nextNotice, 5000);

    // pause on hover
    $('.noticeboard').hover(

    function() {
        clearTimeout(timeOut);
    }, function() {
        timeOut = setTimeout(nextNotice, 5000);
    });

    // Next notice function called on timeout or click

    function nextNotice(event) {
        clearTimeout(timeOut);
        timeOut = setTimeout(nextNotice, 5000);

        if ($('.noticeboard span:visible').is('.noticeboard span:last-child')) {
            $('.noticeboard span:visible').fadeOut(300);
            $('.noticeboard span:first-child').fadeIn();
        }
        else {
            $('.noticeboard span:visible').fadeOut(300).next().fadeIn();
        }
        return false;
    }

    $('#notice-next').click(nextNotice);
    $('#notice-prev').click(function(event) {


        if ($('.noticeboard span:visible').is('.noticeboard span:first-child')) {
            $('.noticeboard span:visible').fadeOut(300);
            $('.noticeboard span:last-child').fadeIn();
        }
        else {
            $('.noticeboard span:visible').fadeOut(300).prev().fadeIn();
        }
        return false;

    });

};


 })(jQuery);

$(document).ready(function() {

$('.noticeboard span').hide();
$('.noticeboard span:first').show();
$('.noticeboard').NoticeBoard();

});

HTML

<div class="action-box"> 
<!-- NOTICEBOARD NAV --> 
<a href="#" id="notice-prev">«</a> <a href="#" id="notice-next">»</a> 
<!-- /NOTICEBOARD NAV --> 

<span class="ge"></span>
<div class="noticeboard" style="height: 145px;"> 
    <span style="display: block; opacity: 0.515705;">
        <strong>Boy, 14, found stabbed to death</strong>
        <a href="http://www.bbc.co.uk/news/uk-england-14570107">A 14-year-old boy has been found stabbed to death in a park in north London.</a>
    </span>

    <span style="display: block;">
        <strong>A-level passes rise for 29th year</strong>
        <a href="http://www.bbc.co.uk/news/education-14558490">Hundreds of thousands of teenagers are getting their A-level results amid an intense battle for university places ahead of tuition fee rises.</a>
    </span>
    <span style="display: none;">
        <strong>UK: Matter of time for Gaddafi</strong>
        <a href="http://www.bbc.co.uk/news/uk-politics-14625484">Deputy Prime Minister Nick Clegg has said it is "only a matter of time" before Col Muammar Gaddafi is defeated.</a>
    </span> 
</div>

Take a look on my news roller: LIVE DEMO

Everything works perfectly till you leave scipt in the tab for couple of minutes.

What is happening looks like browser lost count of every 5s and is performing action constantly.

I'm guessing it has something to to with setTimeout.

Any suggestion how to fix it?

Script:

(function($) {

$.fn.NoticeBoard = function() {


    // Set a timeout
    var timeOut = setTimeout(nextNotice, 5000);

    // pause on hover
    $('.noticeboard').hover(

    function() {
        clearTimeout(timeOut);
    }, function() {
        timeOut = setTimeout(nextNotice, 5000);
    });

    // Next notice function called on timeout or click

    function nextNotice(event) {
        clearTimeout(timeOut);
        timeOut = setTimeout(nextNotice, 5000);

        if ($('.noticeboard span:visible').is('.noticeboard span:last-child')) {
            $('.noticeboard span:visible').fadeOut(300);
            $('.noticeboard span:first-child').fadeIn();
        }
        else {
            $('.noticeboard span:visible').fadeOut(300).next().fadeIn();
        }
        return false;
    }

    $('#notice-next').click(nextNotice);
    $('#notice-prev').click(function(event) {


        if ($('.noticeboard span:visible').is('.noticeboard span:first-child')) {
            $('.noticeboard span:visible').fadeOut(300);
            $('.noticeboard span:last-child').fadeIn();
        }
        else {
            $('.noticeboard span:visible').fadeOut(300).prev().fadeIn();
        }
        return false;

    });

};


 })(jQuery);

$(document).ready(function() {

$('.noticeboard span').hide();
$('.noticeboard span:first').show();
$('.noticeboard').NoticeBoard();

});

HTML:

<div class="action-box"> 
<!-- NOTICEBOARD NAV --> 
<a href="#" id="notice-prev">«</a> <a href="#" id="notice-next">»</a> 
<!-- /NOTICEBOARD NAV --> 

<span class="ge"></span>
<div class="noticeboard" style="height: 145px;"> 
    <span style="display: block; opacity: 0.515705;">
        <strong>Boy, 14, found stabbed to death</strong>
        <a href="http://www.bbc.co.uk/news/uk-england-14570107">A 14-year-old boy has been found stabbed to death in a park in north London.</a>
    </span>

    <span style="display: block;">
        <strong>A-level passes rise for 29th year</strong>
        <a href="http://www.bbc.co.uk/news/education-14558490">Hundreds of thousands of teenagers are getting their A-level results amid an intense battle for university places ahead of tuition fee rises.</a>
    </span>
    <span style="display: none;">
        <strong>UK: Matter of time for Gaddafi</strong>
        <a href="http://www.bbc.co.uk/news/uk-politics-14625484">Deputy Prime Minister Nick Clegg has said it is "only a matter of time" before Col Muammar Gaddafi is defeated.</a>
    </span> 
</div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

苏璃陌 2024-12-08 03:20:56

我想我已经找到了你的问题,但还不知道如何解决。

我认为您面临的问题是这样的:当您在选项卡中将其打开,然后通过选择另一个选项卡隐藏页面,然后在布告栏保留的 + 10 秒(或分钟,如果您愿意)后返回到您的页面闪烁。

这可能是因为当前未选择选项卡时 jquery 无法执行视觉效果。所以在我看来,它将所有效果保留在队列中,并在您返回选项卡时一一执行它们。不知道为什么会这样做。

我已经在您的 nextNotice 函数中添加了一个简单的调试行,以证明问题不是 setTimeout

只需添加

var d = new Date();
$("#debug").append(d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + " call to nextNotice<br />");

并在某处添加一个 div 块即可

<div id="debug"></div>

这将向您显示调用始终有 5 秒的延迟。

现在要弄清楚为什么 jquery 对视觉效果进行排队...

还可以从第一条评论中的链接复制粘贴:

为了避免这个潜在的问题,请使用循环中最后一个动画的回调,或者将一个函数附加到元素.queue()来设置启动下一个动画的超时

所以您的代码应该更改为:

function nextNotice(event) {
    if ($('.noticeboard span:visible').is('.noticeboard span:last-child')) {
        $('.noticeboard span:visible').fadeOut(300);
        $('.noticeboard span:first-child').fadeIn(300, function() {timeOut = setTimeout(nextNotice, 5000);});
    } else {
        $('.noticeboard span:visible').fadeOut(300).next().fadeIn(300, function() {timeOut = setTimeout(nextNotice, 5000);});
    }
}

这将确保新的超时仅在动画结束时开始。因此,如果您离开选项卡,则最后一个未播放的动画将不会开始新的超时,直到您返回选项卡。

编辑:正确格式化代码块

编辑2:第一条评论解释了我描述的问题的原因。

编辑3:添加解决方案源代码

I think I've found your problem, don't really know how to solve it yet.

I think the issue you are facing is this: when you leave it open in a tab and then you hide the page by selecting another tab and then go back to your page after + 10 seconds(or minutes if you will) that the noticeboard keeps on flashing.

This is probably because jquery can't perform the visual effect when the tab is not currently selected. So it seems to me that it keeps all the effects in a queue and executes them one by one when you return to the tab. Don't know why it does that.

I've added a simple debug line to your nextNotice function to prove that the problem is not setTimeout

Simply add

var d = new Date();
$("#debug").append(d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + " call to nextNotice<br />");

and add a div block somewhere with

<div id="debug"></div>

That will show you that the call is always made with a 5second delay.

Now to figure out why jquery is queuing the visual effects...

Also copy-pasting from the link in the first comment:

To avoid this potential problem, use the callback of your last animation in the loop, or append a function to the elements .queue() to set the timeout to start the next animation

So your code should change to this:

function nextNotice(event) {
    if ($('.noticeboard span:visible').is('.noticeboard span:last-child')) {
        $('.noticeboard span:visible').fadeOut(300);
        $('.noticeboard span:first-child').fadeIn(300, function() {timeOut = setTimeout(nextNotice, 5000);});
    } else {
        $('.noticeboard span:visible').fadeOut(300).next().fadeIn(300, function() {timeOut = setTimeout(nextNotice, 5000);});
    }
}

This will make sure that the new timeouts are only started when the animation finishes. So if you leave the tab, the last animation that hasn't played will not start a new timeout until you return to the tab.

Edit: Formatted code block properly

Edit 2: The first comment explains the reason for the problem I describe.

Edit 3: Added solution source code

放肆 2024-12-08 03:20:56

setTimeout 设置一个只运行一次的计时器。

一旦超时功能命中,您可能不需要清除它,因此请尝试进行此更改

function nextNotice(event) {
    // clearTimeout(timeOut);

并看看您的进展如何。
悬停中的clearTimeout是有效的。

更新:

我稍微移动了该函数,现在看起来工作正常,并且在动画后设置新的超时使其感觉更流畅,他是我的小提琴版本:

http://jsfiddle.net/t4NXD/20/

setTimeout sets a timer that runs only once.

You might not need to clear it, once the timeout function hits, so try making this change

function nextNotice(event) {
    // clearTimeout(timeOut);

And see how you get on.
the clearTimeout in the hover is valid though.

Update:

I've moved the function around slightly, it appears to be working fine now, and setting the new timeout after the animation makes it feel a little smoother, he're my fiddle version:

http://jsfiddle.net/t4NXD/20/

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