2011-03-08 90 views
3

這段代碼應該是通過淡出最頂層的元素,直到只有第一個元素可見,然後淡入最頂層的元素,從堆疊的list-elements(我註釋掉了CSS,這樣我就可以看到發生了什麼)其餘的重新開始。如果我把腳本放在<body>裏面的內容下面並丟掉$(function() {,它的工作原理很好,但是在<head>中沒有任何反應。我昨天寫了這個,今天我仍然看不到這個錯誤,所以我在這裏發佈。jQuery在<head>不工作?

<!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> 

感謝

回答

4

不同的是,包裹內$(function() {})你的代碼將導致fade函數聲明本地,而不是全球setTimeout在全局範圍內評估'fade()',所以無法找到該功能。

這是一般不好的做法給setTimeout一個字符串,無論如何,所以用函數指針替換:

setTimeout(fade, 1000); 

我回答了類似的問題,不久前here,但這個問題也依賴於訪問setTimeout中的局部變量。

+0

非常感謝,有效。我曾試過'setTimeout(fade(),1000);',沒有引號,但沒有做任何事情。現在沒有它的括號,但我真的不明白爲什麼。 – Hanz 2011-03-08 08:29:09

+0

@Hanz,用括號括起來,'fade'獲取**,並將返回值傳遞給'setTimeout'。相反,您希望傳遞函數本身,以便稍後調用它。 – 2011-03-08 08:33:29

+0

這很有道理,謝謝。我也驚訝於我在這裏得到答覆的速度有多快。乾杯。 – Hanz 2011-03-08 08:36:21

0

在jQuery中編程的基本方法是將所有DOM訪問代碼放在$(document).ready()事件處理函數中。重做你的JavaScript如下:

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

注意我,計數和褪色聲明以外的$(document)。就緒,因爲它們的範圍是全球性的。這是關鍵,因爲您的setInterval處理程序需要它們全局可用。

jQuery的一大優勢是,無論您將代碼放在哪裏,都可以保證它會在應該執行時執行。 $(document).ready內部的代碼在加載完整的DOM樹之前不會執行,因此確保您訪問時引用的所有元素都可用。

0

如果你打開瀏覽器的JavaScript控制檯,它會告訴你確切的問題是:

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

試試這個:

$(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); 
     }); 
    }); 

使用字符串setInterval是難以得到的權利。

+0

謝謝,我確實想過把所有內容放在一個匿名函數中,但它看起來並不「整齊」。這被認爲是良好的做法?有什麼優勢? – Hanz 2011-03-08 08:39:32

+0

@Hanz:當您的小片段不會在其他地方運行時,匿名函數非常方便。我無法真正地告訴你,這是否是良好的做法是一般條款。無論如何,關鍵在於使用函數本身作爲參數而不是字符串eval()'d(並且,當然,將它定義在適當的範圍內,正如接受的@ Box9指出的那樣)。 – 2011-03-09 11:31:14