2012-01-13 95 views
1
carousel: function(){ 
      var $carouselCr = $('#carousel'), 
       $tabCr = $('.carouselTabs', $carouselCr), 
       $itemCr = $('.carouselContents', $carouselCr), 
       tabAmount = (function(){ 
        if($('a', $tabCr).length === $('.item', $itemCr).length){ 
         return $('a', $tabCr).length; 
        }else{ 
         throw "error: verschillend aantal tabs vs items"; 
        }    
       })(); 

      var i = tabAmount; 
      while(i--){          
       var item = $($('.item', $itemCr)[i]), 
        tab = $($('a', $tabCr)[i]); 
       console.log(item, tab); 
       $(tab).click(function(){ 
        $('.item', $itemCr).hide(); 
        $(item).show(); 
       }) 

      } 

     } 

正如您所看到的,我試圖爲每個「選項卡」附加一個點擊事件,以選擇每個「項目」。我做錯了什麼。所有選項卡都引用第一項。循環中的變量

如果我在循環內記錄$('.item', $itemCr)[i]它將返回所有不同的項目,而不僅僅是第一個。

簡體HTML結構

<div id="carousel" class="block"> 
    <div class="carouselTabs"> 
     <a href="#"> 
     </a> 
    <!-- repeating --> 
    </div> 
    <div class="carouselContents">      
     <div class="item"> 
     </div> 
    <!-- repeating -->     
    </div> 
</div> 
+0

請出示你的HTML。 – 2012-01-13 14:40:37

+0

第21行缺少分號。'})'to'});' – 2012-01-13 14:40:44

+2

whats $ itemCr和$ tabCr? – Evan 2012-01-13 14:40:44

回答

3

環路不會創建一個新的變量範圍。您需要在單獨的函數中創建點擊處理程序,並將需要作用的任何需求傳遞給該函數。

// creates the handler with the scoped item, and returns the handler 
function create_handler(this_item) { 
    return function() { 
     $('.item', $itemCr).hide(); 
     $(this_item).show(); 
    }; 
} 

var i = tabAmount; 
var a_els = $('a', $tabCr); 
var items = $('.item', $itemCr); 
while (i--) { 
    var item = items[i], 
     tab = a_els[i]; 
    $(tab).click(create_handler(item)); 
} 

另外請注意,你不應該做DOM選擇在一個循環。像在上面那樣在循環外緩存一次,並在循環中引用它。


看起來原來的問題代碼有一些變化。我想改寫這樣的代碼:

carousel: function(){ 
    var $carouselCr = $('#carousel'), 
     $tabCr = $('.carouselTabs', $carouselCr), 
     $itemCr = $('.carouselContents', $carouselCr), 
     $items = $('.item', $itemCr), 
     $a_els = $('a', $tabCr); 

    if($a_els.length !== $items.length) 
     throw "error: verschillend aantal tabs vs items"; 

    $a_els.each(function(i) { 
     $(this).click(function() { 
      $items.hide(); 
      $items.eq(i).show(); 
     }); 
    }); 
} 

現在每個.click()處理程序引用獨特i,這是在迭代當前$a_els元素的索引。

因此,例如,當點擊發生在$a_els在指數3$items.eq(i).show();將顯示$items元素,這也是在指數3


另一種方法是使用事件委託,將處理程序放在容器上,並提供一個選擇器以確定是否應該調用處理程序。

如果你正在使用jQuery 1.7或更高版本,你會使用.on() ...

carousel: function(){ 
    var $carouselCr = $('#carousel'), 
     $tabCr = $('.carouselTabs', $carouselCr), 
     $itemCr = $('.carouselContents', $carouselCr), 
     $a_els = $('a', $tabCr), 
     $items = $('.item', $itemCr); 

    if($a_els.length !== $items.length) 
     throw "error: verschillend aantal tabs vs items"; 

    $tabCr.on('click','a',function() { 
     var idx = $a_els.index(this); // get the index of the clicked <a> 
     $items.hide(); 
     $items.eq(idx).show(); // ...and use that index to show the content 
    }); 
} 

或者jQuery的1.7之前,你會使用.delegate() ...

carousel: function(){ 
    var $carouselCr = $('#carousel'), 
     $tabCr = $('.carouselTabs', $carouselCr), 
     $itemCr = $('.carouselContents', $carouselCr), 
     $a_els = $('a', $tabCr), 
     $items = $('.item', $itemCr); 

    if($a_els.length !== $items.length) 
     throw "error: verschillend aantal tabs vs items"; 

    $tabCr.delegate('a','click',function() { 
     var idx = $a_els.index(this); // get the index of the clicked <a>... 
     $items.hide(); 
     $items.eq(idx).show(); // ...and use that index to show the content 
    }); 
} 

這方法只有一個綁定到$tabCr容器的處理程序。它會檢查單擊的項目是否與'a'選擇器匹配,如果是,則調用處理程序。

如果有在<a>...</a>元素或<div class="item">...</div>元件,使得指數不自然匹配,我們就需要調整.index()呼叫只是有點之間的其他元素。

+0

感謝您的所有建議!使用.each()實際上是我通常做的。我以爲我讀過的地方使用普通的JavaScript循環更快。 – dubbelj 2012-01-13 15:06:30

+1

@dubbelj:是的,'for'語句通常會更快,因爲'.each()'需要在循環的每次迭代中調用一個函數。但是由於你需要調用一個函數來創建變量範圍,所以你使用哪一個並不重要。可能有方法可以在不確定變量範圍的情況下完成所需內容,但我們需要查看HTML結構。 – 2012-01-13 15:11:12

+0

我明白了。我添加了一些HTML結構。不要有任何進一步深入的義務。我的問題解決了。 – dubbelj 2012-01-13 15:24:48

1

簡化代碼,並使其具有更好的性能,你可以使用委託方法

$('.carouselTabs', '#carousel').delegate('a', 'click', function(){ 

    var ind = $('.carouselTabs a').index(this); 
    $('.item', '#carousel').hide().eq(ind).show(); 

    return false; 
});