循环中的变量

时间:2012-01-13 14:38:47

标签: javascript jquery loops

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>

2 个答案:

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