Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/409.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 暂停递归函数调用_Javascript_Jquery_Animation_Recursion_Settimeout - Fatal编程技术网

Javascript 暂停递归函数调用

Javascript 暂停递归函数调用,javascript,jquery,animation,recursion,settimeout,Javascript,Jquery,Animation,Recursion,Settimeout,我有一个函数,应该在mouseenter上暂停,在mouseleave上暂停,但问题是这个函数是递归的。您传入一个父级和索引,它将递归地循环显示和隐藏每个内部div。函数如下所示: var delay = 1000; function cycle(variable, j){ var jmax = jQuery(variable + " div").length; jQuery(variable + " div:eq(" + j + ")") .css('displ

我有一个函数,应该在mouseenter上暂停,在mouseleave上暂停,但问题是这个函数是递归的。您传入一个父级和索引,它将递归地循环显示和隐藏每个内部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);
        });
}
我尝试过设置一个超时并清除它,但它似乎没有做任何事情,它似乎完全忽略了超时,我尝试过在mouseout上使用stop并再次调用函数,但这似乎重复了函数调用,我看到了重复的函数,它在动画中停止了,但不起作用。我尝试在一个点上添加一个默认变量var pause=false | | true;但是我也不能让它像预期的那样工作,尽管我觉得解决方案依赖于这个变量。我愿意接受所有建议,但有一些接触规则:

规则:这个函数的工作方式不能有任何重大的改变,因为很多事情都依赖它,这是我无法控制的。假设函数调用类似于jQuery'divList',0,并将一组div元素作为子元素保存

timeout函数是我尝试的最后一个解决方案,如下所示:

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

您需要在每个循环确定是否要运行之前设置一个标志,以供其检查。然后,您可以在触发鼠标事件时更改该标志。如果您需要在停顿时拾取掉的地方,请考虑保存J

的最后一个值。 然后,当您想暂停时,只需将window.paused设置为true。要继续,请将其更改回false并再次调用循环:


也许是这样的?我简化了动画只是为了使示例更简单,但是您应该能够根据自己的需要对其进行调整

首先,我们有一个函数,负责设置一组元素的动画。每个函数调用都返回一个新函数,该函数允许在暂停和恢复之间切换动画转换

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>

如果您想要更通用的东西,它似乎会覆盖动画,并允许以通用方式暂停/恢复动画。

使用“停止”时,您需要将true作为参数传递,以防止调用回调。window.clearTimeout需要从setTimeout函数返回的超时ID。带有pause变量的解决方案也应该有效。您可以发布该try的全部代码吗?这里的技术问题:这不是递归调用,因为一次只存在一个cycle函数实例。这使用事件来重新调用自身-从技术角度来看,这是非常不同的。如果这实际上是递归的,您将无法暂停它。@JeremyJStarcher不是任何调用自身递归的函数吗?这不是一个全局窗口属性吗?没有理由将其设为全局窗口属性,特别是因为可以使用不同的参数多次调用cycle。我尝试了这个方法,但它从未停止。我收到了所有预期的控制台消息,但随后多个div开始出现并循环,就像该函数有多个实例一样:
$(function () {
    var $animationContainer = $('#animation-container'),
        toggleAnimation = startCycleAnimation($animationContainer.children('div'));

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

    function pauseOrResume() {
        toggleAnimation = toggleAnimation();
    }
});
<body>
    <div id="animation-container">
        <div>Div 1</div>
        <div>Div 2</div>
        <div>Div 3</div>
    </div>
</body>