Javascript 循环中的变量
如您所见,我正试图在每个“选项卡”上附加一个单击事件,以选择每个“项目”。我做错了什么。所有选项卡都指向第一项 如果我在循环中记录Javascript 循环中的变量,javascript,jquery,loops,Javascript,Jquery,Loops,如您所见,我正试图在每个“选项卡”上附加一个单击事件,以选择每个“项目”。我做错了什么。所有选项卡都指向第一项 如果我在循环中记录$('.item',$itemCr)[i],它将返回所有不同的项目,而不仅仅是第一个 简化的HTML结构 carousel: function(){ var $carouselCr = $('#carousel'), $tabCr = $('.carouselTabs', $carouselCr),
$('.item',$itemCr)[i]
,它将返回所有不同的项目,而不仅仅是第一个
简化的HTML结构
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();
})
}
}
循环不会创建新的变量范围。您需要在单独的函数中创建click处理程序,并将需要限定范围的内容传递给该函数
<div id="carousel" class="block">
<div class="carouselTabs">
<a href="#">
</a>
<!-- repeating -->
</div>
<div class="carouselContents">
<div class="item">
</div>
<!-- repeating -->
</div>
</div>
还请注意,不应在循环中进行DOM选择。在循环外部缓存它一次,并像上面那样在循环中引用它
从最初的问题来看,代码似乎有了一些变化。我会像这样重写代码:
// 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) );
}
现在,每个.click()
处理程序都引用一个唯一的i
,它是迭代中当前$a_els
元素的索引
例如,当在索引3
的$a_els
上单击时,$items.eq(i).show()
将显示同样位于索引3
的$items
元素
另一种方法是使用事件委托,将处理程序放置在容器上,并提供一个选择器来确定是否应调用该处理程序 如果您使用的是jQuery 1.7或更高版本,那么您应该使用
.on()
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();
});
});
}
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
});
}
这样,只有一个处理程序绑定到$tabCr
容器。它检查单击的项是否与'a'
选择器匹配,如果匹配,则调用处理程序
如果在
..
元素或..
元素之间存在其他元素,因此索引不会自然匹配,我们需要稍微调整.index()
调用。循环不会创建新的变量范围。您需要在单独的函数中创建click处理程序,并将需要限定范围的内容传递给该函数
<div id="carousel" class="block">
<div class="carouselTabs">
<a href="#">
</a>
<!-- repeating -->
</div>
<div class="carouselContents">
<div class="item">
</div>
<!-- repeating -->
</div>
</div>
还请注意,不应在循环中进行DOM选择。在循环外部缓存它一次,并像上面那样在循环中引用它
从最初的问题来看,代码似乎有了一些变化。我会像这样重写代码:
// 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) );
}
现在,每个.click()
处理程序都引用一个唯一的i
,它是迭代中当前$a_els
元素的索引
例如,当在索引3
的$a_els
上单击时,$items.eq(i).show()
将显示同样位于索引3
的$items
元素
另一种方法是使用事件委托,将处理程序放置在容器上,并提供一个选择器来确定是否应调用该处理程序 如果您使用的是jQuery 1.7或更高版本,那么您应该使用
.on()
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();
});
});
}
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
});
}
这样,只有一个处理程序绑定到$tabCr
容器。它检查单击的项是否与'a'
选择器匹配,如果匹配,则调用处理程序
如果在
..
元素或..
元素之间存在其他元素,因此索引不能自然匹配,我们需要稍微调整.index()
调用。为了简化代码并提高性能,可以使用委托方法
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
});
}
为了简化代码并提高性能,可以使用委托方法
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
});
}
第21行缺少一个分号<代码>})至
})代码>和的可能重复。第21行中缺少分号<代码>})
至})代码>可能重复的和许多,许多,许多其他。感谢所有的建议!使用.each()实际上是我通常做的事情。我想我在什么地方读到过,使用常规javascript循环速度更快。@typelj:是的,for
语句的通常会更快,因为。each()
需要在循环的每次迭代中调用一个函数。但是,由于无论如何都需要调用函数来创建变量作用域,因此使用哪一个并不重要。可能有一些方法可以在不使用范围变量的情况下实现您所需的功能,但我们需要查看您的HTML结构。我理解。我添加了一些HTML结构。不要觉得有义务进一步讨论这个问题。我的问题解决了。@LJ:我在底部添加了一个事件委派解决方案。这取决于您使用的是jQuery1.7还是更早的版本。享受!:)谢谢你的建议!使用.each()实际上是我通常做的事情。我想我在什么地方读到过,使用常规javascript循环速度更快。@typelj:是的,for
语句的通常会更快,因为。each()
需要在循环的每次迭代中调用一个函数。但是,由于无论如何都需要调用函数来创建变量作用域,因此使用哪一个并不重要。可能有一些方法可以在不使用范围变量的情况下实现您所需的功能,但我们需要查看您的HTML结构。我理解。我添加了一些HTML结构。不要觉得有义务进一步讨论这个问题。我的问题解决了。@LJ:我在底部添加了一个事件委派解决方案。这取决于您使用的是jQuery1.7还是更早的版本。享受!:)