Search code examples
javascriptreturnslideshowexitexecute

How to stop a javascript function from within another function?


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.

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

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

Can anyone tell me how to do this?

Here is my 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 pause and play statements 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.


Solution

  • 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:

    // 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);
    }