开发者

javascript execution order

I am starting to learn Javascript and jQuery. I wanted to make a simple slide show with jQuery which displays list unordered list items one by one.

My code is here: on jsfiddle

I thought that I'd make the slideshow by iterating over list items in a for loop and display them with fadeIn and fadeOut effects like below:

for(var i = 0; i < 3; i++)
{
    $('#slider li:nth-child('+ i +')')
        .fadeIn()
        .delay(1000)
        .fadeOut();
}

But it only shows the last item in the list.

I read that I need to close the value of i variable in a separate function because of the Javascript scope that it sees the value of i is being increased to 2 in the loop. So, I made a separate function which closes the value of i and called the function. But it was still same, displaying the last item of the list.

So, I just wanted to try without the loop by making two separate effects on list items like below:

$('#slider li:first-child')
    .fadeIn()
    .delay(1000)
    .fadeOut();
$('#slider li:nth-child(2)')
    .fadeIn()
    .delay(1000)开发者_开发百科
    .fadeOut();

But it doesn't display the list items sequentially like written above. When you run the code, it seems like the first item is shown really fast and the last item is displayed as intended.

I have written it like a C or Java code, thinking that it would execute from top to bottom. But it seems like Javascript is different and I didn't understand a key concept of Javascript.

So, my question is why it is not displaying the list items in order and only displaying the last item, and what should I need to know to make it work as intented.

Thank you.


Since the reasons why yours didn't work have already been covered, instead I've set up a new fiddle for you with the following working slideshow code and commented explanation:

$('#slider li').hide();

// Method 3
var slideIt = function ( which ) {
    $('#slider li:nth-child('+ which +')')
        .fadeIn(300)
        .delay(1000)
        .fadeOut(300, function() { // after animation complete
            which++; // increment which child
            which = (which > $('#slider li').length) ?
                    1 : // if last child loop back to beginning
                    which;
            slideIt( which ); // call again with new child
        });
};

slideIt( 1 ); // start the process


Animations are implemented behind the scenes by using many incremental calls to setTimeout()/setInterval(), which basically just queues up future tasks. So, the actual function calls you made in your code are not synchronous operations, it all finished within a microsecond, and many future tasks were enqueued.

This shows it a bit better, the second animation being scheduled to start far enough into the future so as not to interfere.

for(var i = 0; i < 3; i++)
{
    $('#slider li:nth-child('+ i +')')
        .delay(2000 * i)
        .fadeIn()
        .delay(1000)
        .fadeOut();
}

I don't do much animation in jquery, but I do know that some animation functions accept a function as an argument, which will be called once it's animation finishes. This makes it easier to do serial animations because you dont need to do time/math calculation trickery.

As for why it's done like this- javascript is single threaded, and synchronous operations that don't complete quickly can easily block the ui. SO you gotta fudge it and queue stuff up, which the browser does at its liesure.


A much simpler method will be

$(document).ready(function () {
    $('#slider li:gt(0)').hide();
    setInterval(
        function () {
            $('#slider li:first-child')
                .fadeOut()
                .next('li')
                .fadeIn()
                .end()
                .appendTo('#slider');
        }
    , 3000);
});

It uses JavaScript SetInterval method.

You can view the code in action here

P.S: jQuery's implementation of :nth-child(n) is strictly derived from the CSS specification, the value of n is "1-indexed"

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜