繁体   English   中英

暂停递归函数调用

[英]Pausing Recursive Function Call

我有一个应该在mouseenter上暂停并在mouseleave上暂停的函数,但是问题是该函数是递归的。 您传递一个parent和index,它将递归遍历每个内部div的显示和隐藏。 该函数如下所示:

var delay = 1000;
function cycle(variable, j){
    var jmax = jQuery(variable + " div").length;
    jQuery(variable + " div:eq(" + j + ")")
        .css('display', 'block')
        .animate({opacity: 1}, 600)
        .animate({opacity: 1}, delay)
        .animate({opacity: 0}, 800, function(){
            if(j+1 === jmax){ 
                j=0;
            }else{ 
                j++;
            }
            jQuery(this).css('display', 'none').animate({opacity: 0}, 10);

            cycle(variable, j);
        });
}

我试过设置一个超时并清除它,但它似乎没有做任何事情(它似乎完全忽略了超时),我试过使用stop()并在mouseout上再次调用该函数,但这似乎重复了函数调用(我看到重复项),它停止了动画无效的动画。 我尝试在某一点添加默认变量( var pause = false || true; ),但我也无法使其按预期工作(尽管我认为解决方案依赖于该变量)。 我愿意接受所有建议,但有一些参与规则:

规则:由于很多东西都依赖它,因此该函数的工作方式没有任何重大变化,这是我无法控制的。 假设函数调用看起来像这样的jQuery('#divList', 0)并包含一堆div元素作为子元素。

超时功能是我尝试过的最后一个解决方案,如下所示:

jQuery('#divList').on('mouseenter', function(){
    setTimeout(cycle, 100000);
})
.on('mouseleave', function(){
    window.clearTimeout();
});

您将需要放置一个标志,每个cycle在确定是否要运行之前都要对其进行检查。 然后,您可以在触发鼠标事件时更改该标志。 如果需要在取消暂停时从上次中断的地方继续,请考虑保存j的最后一个值

function cycle(variable, j){
    if (window.paused) {
        window.last_j = j;
        return;
    }
    ...

然后,当您想暂停时,只需设置window.paused = true 要恢复,请将其改回false并再次调用cycle

cycle(variable, last_j);

也许像这样? 我简化了动画,只是为了简化示例,但您应该能够使其适应您的需求。

首先,我们有一个函数负责对一组元素进行动画处理。 每个函数调用都会返回一个新功能,该功能允许切换动画(暂停和恢复之间的转换)。

function startCycleAnimation(els) {

    var index = 0,
        $els = $(els),
        $animatedEl;

    animate($nextEl());

    return pauseCycleAnimation;

    function animate($el, startOpacity) {
        $el.css('opacity', startOpacity || 1)
           .animate({ opacity: 0 }, 800, function () {
                animate($nextEl());
            });
    }

    function $nextEl() {
        index = index % $els.length;
        return $animatedEl = $els.slice(index++, index);
    }

    function pauseCycleAnimation() {
        $animatedEl.stop(true);

        return resumeCycleAnimation;
    }

    function resumeCycleAnimation() {
         animate($animatedEl, $animatedEl.css('opacity'));

         return pauseCycleAnimation;
    }
}

然后,我们可以通过以下方式启动一切:

$(function () {
    var $animationContainer = $('#animation-container'),
        toggleAnimation = startCycleAnimation($animationContainer.children('div'));

    $animationContainer.mouseenter(pauseOrResume).mouseleave(pauseOrResume);

    function pauseOrResume() {
        toggleAnimation = toggleAnimation();
    }
});

HTML范例

<body>
    <div id="animation-container">
        <div>Div 1</div>
        <div>Div 2</div>
        <div>Div 3</div>
    </div>
</body>

如果您想要更通用的东西,似乎有一个插件可以替代animate并允许以通用方式暂停/恢复动画。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM