admin管理员组

文章数量:1429841

This has probably been answered before and I already know how this should work, but for some reason it is not. I think it may be how I am looping through the elements.

$(document).ready(function() {
     var element = '#gallery ul#gallery-container';
 var idx=0;
 var timeout = 3000;
 var number =  $(element + ' li').length;

function changeSlide() {

    $(element + ' li:eq(' + idx + ')').fadeOut();

    idx = idx + 1;

    if (idx == number) {
        idx=0;
    }

    $(element + ' li:eq(' + idx + ')').fadeIn().delay(timeout).delay(0,   function() {
        changeSlide();
    });;

}

 $(element + ' li').hide();

 $(element + ' li:first').fadeIn().delay(timeout).delay(0, function() {
    changeSlide();
 });
});

Then the list is like this:

<div id="gallery">
    <ul id="gallery-container">
        <li><img src="media/images/screen-shot-02.jpg" width="173" height="258" alt=" "></li>
        <li><img src="media/images/screen-shot-01.jpg" width="173" height="258" alt=" "></li>
    </ul>   
</div>

I was trying to get it to loop through the elements one by one, after a delay so the list item calls the function and hides itself, then the counter is incremented and then the current index is shown. I suspect the culprit to be this as if I put an alert in the function it is called:

 $(element + ' li:eq(' + idx + ')').fadeOut();

This has probably been answered before and I already know how this should work, but for some reason it is not. I think it may be how I am looping through the elements.

$(document).ready(function() {
     var element = '#gallery ul#gallery-container';
 var idx=0;
 var timeout = 3000;
 var number =  $(element + ' li').length;

function changeSlide() {

    $(element + ' li:eq(' + idx + ')').fadeOut();

    idx = idx + 1;

    if (idx == number) {
        idx=0;
    }

    $(element + ' li:eq(' + idx + ')').fadeIn().delay(timeout).delay(0,   function() {
        changeSlide();
    });;

}

 $(element + ' li').hide();

 $(element + ' li:first').fadeIn().delay(timeout).delay(0, function() {
    changeSlide();
 });
});

Then the list is like this:

<div id="gallery">
    <ul id="gallery-container">
        <li><img src="media/images/screen-shot-02.jpg" width="173" height="258" alt=" "></li>
        <li><img src="media/images/screen-shot-01.jpg" width="173" height="258" alt=" "></li>
    </ul>   
</div>

I was trying to get it to loop through the elements one by one, after a delay so the list item calls the function and hides itself, then the counter is incremented and then the current index is shown. I suspect the culprit to be this as if I put an alert in the function it is called:

 $(element + ' li:eq(' + idx + ')').fadeOut();
Share Improve this question edited Jun 2, 2012 at 13:13 Chad Ferguson 3,0875 gold badges37 silver badges42 bronze badges asked Feb 14, 2011 at 9:16 Designer023Designer023 2,0222 gold badges27 silver badges45 bronze badges 4
  • 1 According to this api.jquery./delay the delay() function does not have a callback function, so changeSlide() never gets executed I'm thinking. – Anriëtte Myburgh Commented Feb 14, 2011 at 10:12
  • For some reason, changeSlide() is called the first time, but when it gets to the function the $(element + ' li:eq(' + idx + ')').fadeOut(); isn't called. I may have to resort to setTimeout and work with that! – Designer023 Commented Feb 14, 2011 at 10:31
  • Yeah, and note the double ;; in changeSlide()'s last line, that's stopping your script. – Anriëtte Myburgh Commented Feb 14, 2011 at 10:40
  • Completely missed that! and Also didn't realise that was the case. I just assumed that things like that would be skipped over as it was just an empty line. I assumed wrong! – Designer023 Commented Feb 14, 2011 at 10:46
Add a ment  | 

2 Answers 2

Reset to default 5

The main problem is, as the ment states, delay does not do what you think it does - you should be looking at the native setTimeout function instead. In addition to that, there are multiple places where this could be made more efficient. Have a look at this:

var element = $('#gallery-container li'),
    length = element.length,
    current = 0,
    timeout = 3000;

function changeSlide() {
    element.eq(current++).fadeOut(300, function(){
        if(current === length){
            current = 0;
        }

        element.eq(current).fadeIn(300);
    });

    setTimeout(changeSlide, timeout);
}

element.slice(1).hide();
setTimeout(changeSlide, timeout);

We try not to evoke the jQuery function with a dynamically generated selector, but instead manipulate a single instance of a jQuery object containing all the slides cached at the start. We also use the callback function provided by the fade functions to fade in the next slide after the current one has faded out.

See http://www.jsfiddle/b3Lf5/1/ for a simple demo

I would do it something like this:

$(document).ready(function() {
    var element = '#gallery ul#gallery-container';
    var idx = 0;
    var timeout = 3000;
    var number = $(element + ' li').length;

    setInterval(function () {
        idx = (idx + 1) % number;
        $(element + ' li:visible').fadeOut();
        $(element + ' li:eq(' + idx + ')').fadeIn();
    },timeout);
    $(element + ' li:not(:first)').hide();
});

Or better still, wrap it in a plugin:

(function ($) {
    $.fn.customGallery = function (options) {
        defaults = {
            timeout : 3000
        };
        options = $.extend(defaults, options);
        return this.each(function () {
            var idx = 0, number = $(this).children('li').size(), element = this;
            setInterval(function () {
                idx = (idx + 1) % number;
                $(element).children('li:visible').fadeOut();
                $(element).children('li:eq(' + idx + ')').fadeIn();
            },options.timeout);
            $(element).children('li:not(:first)').hide();
        });
    };
}(jQuery));

jQuery(document).ready(function($) {
    $('#gallery-container').customGallery()
});

edit: Edited the plugin code to bring it into line with good practice.

本文标签: javascriptjQuery rotating through list items in a galleryStack Overflow