JQuery each function pause between non functional

2019-08-16 17:42发布

问题:

This JQuery function should timeout to ensure that each item is delayed 8 seconds after the last. Thus producing a gallery where images fade in and out 8 seconds apart from each other.

It doesn't work.

Any ideas.

function gallery() {
    var timeout = 0;
    $('.cornerimg').each(function() {
        setTimeout(function() {
            $(this).addClass('cornerimgfocus');
            setTimeout(function() {
                $(this).removeClass('cornerimgfocus');
                timeout += 8000;
            }, (timeout + 8000));
        },timeout); 
    });
}

Marvellous

回答1:

   var $images = $( '.cornerimg' );
    var current_image = 0;

    function gallery() {

        $images[ current_image ].addClass( 'cornerimgfocus' );

        setTimeout( function() {

            $images[ current_image ].removeClass( 'cornerimgfocus' );

            current_image += 1;

            if ( current_image > $images.length - 1 ) {
                current_image = 0;
            }

            // remove this if you don't need additional timeout
            setTimeout( gallery, 8000 );

        }, 8000);

}


回答2:

setTimeout(func, 0) does not immediately execute the function, only after the current script finished, so timeout only gets incremented after setTimeout has been called for all the corners (with identical delay). Try it like this:

function gallery() {
    var timeout = 0;
    $('.cornerimg').each(function() {
        setTimeout(function() {
            $(this).addClass('cornerimgfocus');
            setTimeout(function() {
                $(this).removeClass('cornerimgfocus');
            }, 8000);
        },timeout);
    timeout += 8000;
    });
}


回答3:

You probably want to use recursion and some kind of index.

Create a function that remove the focus from the previous image (or perhaps just all the images if that will work) and then puts the cornerimgClass on the one that matches an index supplied to the function. Then once this is done it uses setTimeout to call itself agin in 8 seconds with the index incremented by one.

You'll want to do a check for when you reach the end of the list and either stop, reset to 0 or whatever you fancy.

The key thing though is to use recursion with named functions rather than just anonymous functions.



回答4:

In your setTimeout calls, 'this' is not equal to the element you think it is, it's equal to the DOMWindow. Try this version instead as I found it to be simpler.

function gallery() {
    var imgs = $('.cornerimg.');
    var timer = 8000; // default starting time


    var fade = function(element) {
        setTimeout(function() {
            element.addClass('cornerimgfocus');
        }, timer);

        timer += 8000;

        setTimeout(function() {
            element.removeClass('cornerimgfocus');
        }, timer);
    };

    for (var i = 0; i < imgs.length; i += 1) {
        fade(imgs.eq(i));
    }
}