几分钟后,setTimeout发疯了,FF6.0,Chrome 15

时间:2011-08-23 13:23:29

标签: javascript jquery jquery-animate

看看我的新闻报道: LIVE DEMO

一切都很完美,直到您将标签留在标签中几分钟。

正在发生的事情看起来浏览器每5秒丢失一次并且不断执行操作。

我猜它与setTimeout有关。

有任何建议如何修复它?

脚本:

(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>

2 个答案:

答案 0 :(得分:3)

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

我认为您面临的问题是:当您在选项卡中将其打开然后通过选择另一个选项卡隐藏页面,然后在+ 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 :添加了解决方案源代码

答案 1 :(得分:1)

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

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

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

看看你是怎么过的。 悬停中的clearTimeout虽然有效。

更新

我稍微移动了这个功能,它现在看起来工作正常,并且在动画之后设置新的超时使它感觉更平滑,他是我的小提琴版本:

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