如何从另一个函数中停止 javascript 函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18137656/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 10:50:35  来源:igfitidea点击:

How to stop a javascript function from within another function?

javascriptreturnslideshowexitexecute

提问by

I'm developing a simple slideshow system. I've got the slideshow wrapped in a hidden div, which is shown when a thumbnail from the gallery is clicked.

我正在开发一个简单的幻灯片系统。我将幻灯片包装在隐藏的 div 中,单击图库中的缩略图时会显示该幻灯片。

The slideshow works through a function called commence(), which is executed when the play button is clicked.

幻灯片通过名为 的函数工作,该函数commence()在单击播放按钮时执行。

At the moment I've got it set to hide to whole divagain when stop is clicked, but I would like to keep the divshown, simply stop the slideshow, in other words, stop the commence()function.

目前我已经将它设置为div在单击停止时再次隐藏为整体,但我想保持div显示,只需停止幻灯片放映,换句话说,停止该commence()功能。

Can anyone tell me how to do this?

谁能告诉我如何做到这一点?

Here is my JS:

这是我的JS:

function commence() {
    hidden = document.getElementById("hidden");
    hidden.style.display = 'block';
    pause = document.getElementById("pause");
    pause.style.display = 'block';
    play = document.getElementById("play");
    play.style.display = 'none';
    pic = document.getElementById("picbox"); // Assign var pic to the html element.
    imgs = []; // Assign images as values and indexes to imgs array.

/* --------------------------- IMAGE URLS FOR IMGS ARRAY -------------------------*/

    imgs[0] = "/snakelane/assets/images/thumb/_1.jpg";  imgs[10] = "/snakelane/assets/images/thumb/_19.jpg"; 
    imgs[1] = "/snakelane/assets/images/thumb/_2.jpg";  imgs[11] = "/snakelane/assets/images/thumb/_20.jpg"; 
    imgs[2] = "/snakelane/assets/images/thumb/_3.jpg";  imgs[12] = "/snakelane/assets/images/thumb/_21.jpg";
    imgs[3] = "/snakelane/assets/images/thumb/_4.jpg";  imgs[13] = "/snakelane/assets/images/thumb/_22.jpg";
    imgs[4] = "/snakelane/assets/images/thumb/_5.jpg";  imgs[14] = "/snakelane/assets/images/thumb/_23.jpg";    
    imgs[5] = "/snakelane/assets/images/thumb/_6.jpg";  imgs[15] = "/snakelane/assets/images/thumb/_24.jpg";
    imgs[6] = "/snakelane/assets/images/thumb/_7.jpg";  imgs[16] = "/snakelane/assets/images/thumb/_25.jpg";
    imgs[7] = "/snakelane/assets/images/thumb/_8.jpg";  imgs[17] = "/snakelane/assets/images/thumb/_26.jpg"; 
    imgs[8] = "/snakelane/assets/images/thumb/_9.jpg";  imgs[18] = "/snakelane/assets/images/thumb/_27.jpg";
    imgs[9] = "/snakelane/assets/images/thumb/_10.jpg"; imgs[19] = "/snakelane/assets/images/thumb/_28.jpg"; 


/* -----------------------------------------------------------------------------------------------------*/


    var preload = []; // New array to hold the 'new' images.
    for(i = 0 ; i < imgs.length; i++) // Loop through imgs array
    {
        preload[i] = new Image(); // Loop preload array and declare current index as a new image object.
        preload[i].src = imgs[i]; // Fill preload array with the images being looped from ims array.
    }
    i = 0; // Reset counter to 0.
    rotate(); // Execute rotate function to create slideshow effect.
}

// Function to perform change between pictures.
function rotate() {
    pic.src = imgs[i]; // Change html element source to looping images
    (i === (imgs.length -1))?(i=0) : (i++); // counter equals imgs array length -1.
    setTimeout( rotate, 4000); // Sets the time between picture changes. (5000 milliseconds).
}


function init() {

    [].forEach.call(document.querySelectorAll('.pic'), function(el) { 
        el.addEventListener('click', changeSource); 
    });


    function changeSource() {  
        hidden = document.getElementById("hidden");
        hidden.style.display = 'block';
        newpic = this.src; 
        var pic = document.getElementById("picbox");
        pic.src = newpic;
    }
}

document.addEventListener("DOMContentLoaded", init, false);

function stopSlide() {
    var hidden = document.getElementById("hidden");
    hidden.style.visibility = 'hidden';
    pause.style.display = 'none';
    var play = document.getElementById("play");
    play.style.display = 'block';
}

The pauseand playstatements are not relevant to my question, they simply hide the play button and show the pause button if the slideshow is running, and vice versa.

pauseplay语句不相关的我的问题,他们只是隐藏播放按钮,并显示是否幻灯片正在运行的暂停按钮,反之亦然。

回答by

It looks to me like you actually want to stop the rotate() function, rather then commence, since rotate is what is actually changing the images (ie running the slideshow).

在我看来,您实际上想要停止旋转()函数,而不是开始,因为旋转实际上是在改变图像(即运行幻灯片)。

There are two ways. The first, like thriqon posted, is to use the clearTimeout function. However I'd recommend doing it like this:

有两种方法。第一个,就像 thriqon 发布的一样,是使用 clearTimeout 函数。但是我建议这样做:

// somewhere in global space
var rotateTimeout;

// in commence
rotateTimeout = window.setInterval(rotate,4000); // this will tell the browser to call rotate every 4 seconds, saving the ID of the interval into rotateTimeout

// in stopSlide
window.clearInterval(rotateTimeout); // this will tell the browser to clear, or stop running, the interval.

The second, which is a bit messier, is to use a sentinel.

第二种,有点麻烦,是使用哨兵。

// somewhere in global space
var running;

// in commence
running = true;
rotate();

// in stopSlide
running = false;

// in rotate
if (running) {
    setTimeout(rotate,4000);
}

回答by thriqon

You want to use window.clearTimeoutusing the id you get by call window.setTimeout.

您想使用window.clearTimeout通过 call 获得的 id window.setTimeout

But you should also consider switching to window.setInterval, which gives you an function call every 4 seconds (and not 4 seconds after the last call), the not-needing of repeated calls to re-set the timeout and a better handling of missed events.

但是您还应该考虑切换到window.setInterval,它每 4 秒(而不是最后一次调用后的 4 秒)为您提供一次函数调用,不需要重复调​​用来重新设置超时并更好地处理错过的事件。

See this jsFiddle: http://jsfiddle.net/D3kMG/for an example on how to use these functions for a simple counter.

请参阅此 jsFiddle:http: //jsfiddle.net/D3kMG/以获取有关如何将这些函数用于简单计数器的示例。

回答by SimonR

As mentioned by @thriqon you will want to use window.clearTimeout. To do this you need to save a "global" reference to the id returned by window.setTimeout, as follows:

正如@thriqon 提到的,你会想要使用window.clearTimeout. 为此,您需要保存对 返回的 id 的“全局”引用window.setTimeout,如下所示:

var timeoutID;

//... function declarations

function rotate() {
    //...
    timeoutID = setTimeout( rotate, 4000);
}

Then in your stopSlidefunction you'll simply call clearTimout( timeoutID )to stop the rotation.

然后在您的stopSlide函数中,您只需调用clearTimout( timeoutID )即可停止旋转。