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 :(得分: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
的{{1}}元素。
另一种方法是使用事件委托,将处理程序放在容器上,并提供一个选择器来确定是否应该调用处理程序。
如果您使用的是jQuery 1.7或更高版本,则可以使用3
...
.on()
或者在jQuery 1.7之前,你使用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
});
}
...
.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>
调用一点。
答案 1 :(得分:1)
为了简化代码并使其更高效,您可以使用委托方法
$('.carouselTabs', '#carousel').delegate('a', 'click', function(){
var ind = $('.carouselTabs a').index(this);
$('.item', '#carousel').hide().eq(ind).show();
return false;
});