简体   繁体   中英

jQuery doesn't work in <head>?

This code is supposed to make a slideshow out of stacked list-elements (I commented out the CSS so I can see what's going on) by fading out the topmost elements until only the first one is visible, then fade in the topmost element and the rest and start anew. If I put the script below my content inside the <body> and throw out the $(function() { it works perfectly fine, but in the <head> nothing happens. I wrote this yesterday and today I still can't see the mistake, so I'm posting it here.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        ul {
            position: relative;
        }
        ul li {
            /*position: absolute;
            left: 0;
            top: 0;*/
        }
    </style>
    <script src="jquery-1.5.1.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(function() {
            var i = 0;
            var count = $('ul li').size();      

            function fade() {
                if (i < count-1) {
                $('ul li:nth-child('+(count-i)+')').fadeOut(300);
                    i++;
                } else {
                    $('ul li:nth-child('+count+')').fadeIn(300, function(){$('ul li').show();});    
                    i = 0;
                }
            }

            $('button').click(function() {
                setInterval('fade()', 1000);
            });
        });
    </script>
</head>

<body>
    <button>Slideshow GO!</button>
    <ul id="slider">
        <li><img src="1.jpg" /></li>
        <li><img src="2.jpg" /></li>    
        <li><img src="3.jpg" /></li>
        <li><img src="4.jpg" /></li>
    </ul>
</body>
</html>

Thanks

The difference is that wrapping your code inside $(function () {}) causes the fade function to be declared locally , and not globally . setTimeout evaluates 'fade()' in the global scope, so it can't find the function.

It's generally bad practice to give setTimeout a string anyway, so replace it with a pointer to the function:

setTimeout(fade, 1000);

I answered a similar question not long ago here , but that question also relies on access to local variables from within the setTimeout.

The essential way to program in jQuery is to enclose all DOM accessing code in the $(document).ready() event handler. Redo your javascript as follows:

var i = 0;
var count;

function fade() {
    if (i < count-1) {
        $('ul li:nth-child('+(count-i)+')').fadeOut(300);
            i++;
        } else {
            $('ul li:nth-child('+count+')').fadeIn(300, function(){$('ul li').show();});    
            i = 0;
        }
    }
}

$(document).ready(function() {
    count = $('ul li').size();
    $('button').click(function() {
        setInterval('fade()', 1000);
    });
} );

Note that i, count and fade are declared outside $(document).ready, because their scope is global. This is the key, because the your setInterval handler needs them available globally.

One of the big advantages of jQuery is that no matter where you put your code, you are guaranteed that it will execute just when it should. Code inside $(document).ready won't execute until your entire DOM tree is loaded, thus ensuring all elements you refer are available when accessed.

If you open your browser's JavaScript console, it'll tell you what the exact issue is:

fade is not defined
setInterval('fade()', 1000); 

Try this instead:

    $(function() {
        var i = 0;
        var count = $('ul li').size();      


        $('button').click(function() {
            setInterval(function(){
                if (i < count-1) {
                $('ul li:nth-child('+(count-i)+')').fadeOut(300);
                    i++;
                } else {
                    $('ul li:nth-child('+count+')').fadeIn(300, function(){$('ul li').show();});    
                    i = 0;
                }
            }, 1000);
        });
    });

Using strings in setInterval is difficult to get right.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM