【问题标题】:How to stop a javascript function from within another function?如何从另一个函数中停止一个javascript函数?
【发布时间】:2013-08-10 20:27:33
【问题描述】:

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

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

目前我已将其设置为在单击停止时再次隐藏到整个 div,但我想保持 div 显示,只需停止幻灯片,换句话说,停止 @987654324 @函数。

谁能告诉我怎么做?

这是我的 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';
}

pauseplay 语句与我的问题无关,它们只是隐藏播放按钮并在幻灯片播放时显示暂停按钮,反之亦然。

【问题讨论】:

  • 使用return 声明
  • 看起来你需要停止的是rotate中的setTimeout
  • 谢谢!我怎么做?我可以使用 stopSlide() 函数中的语句来停止超时吗?
  • 实际上,每次rotate 运行时,都会安排一个新的调用(通过setTimeout)。所以你只需要一个if 来决定是否安排一个新的电话。不过,我不知道条件应该是什么。

标签: javascript return slideshow exit execute


【解决方案1】:

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

有两种方法。第一个,就像发布的 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.

第二个,比较麻烦的是使用哨兵。

// somewhere in global space
var running;

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

// in stopSlide
running = false;

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

【讨论】:

    【解决方案2】:

    您想通过调用window.setTimeout 获得的ID 来使用window.clearTimeout

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

    请参阅这个 jsFiddle:http://jsfiddle.net/D3kMG/,了解如何将这些函数用于简单计数器的示例。

    【讨论】:

    • 一个小注解:这种代码不是多线程安全的!如果多个线程同时处于活动状态,则实际上可能会丢失停止信号。但是通常浏览器中的JS是一次一个线程。
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-11
      • 2014-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多