以下代码按预期工作。
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
mySelector[i].classList.add('myClass');
}
}
但是,此代码会生成错误:&#34;未捕获的TypeError:无法读取属性&#39; classList&#39;未定义&#34;
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
setTimeout(function(i){
mySelector[i].classList.add('myClass');
}, 1000);
}
}
我确定有一个非常简单的解释,为什么会这样,但我不知道。
为什么?
更新:从setTimeout函数中删除参数的新代码
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
setTimeout(function(){
mySelector[i].classList.add('myClass');
}, 1000);
}
}
更新2:
Barmar建议这与另一个问题完全相同:JavaScript closure inside loops – simple practical example
我承认它通常是相似的,并且Barmar链接到的答案可能可以帮助那些拥有更多JavaScript体验的人,而不是我所面临的驼峰。但我认为我的问题不同,只能保持开放,原因如下:(1)我的案例更简单,正确的答案可能会使像我这样的技能较低的JavaScript从业者受益,(2)我&#39; m特别关注setTimeout,因为它与for循环有关。再说一遍,我会批准Barmar引用的答案对许多人有帮助,但对我个人来说并不是特别有帮助。
答案 0 :(得分:0)
js循环有一个简单的情况。因为js执行代码异步,变量$(document).ready(function() {
previousScroll=0 //this means we are starting from top
$(window).scroll(function() {
var currentScroll = window.pageYOffset || document.documentElement.scrollTop;
if (currentScroll > previousScroll){
// Change header style cause you are down scrolling
} else {
// Do something else? You are up scrolling anyway...
}
previousScroll = currentScroll;
);
});
比i
的有效索引更多。您可以使用mySelector
代替let i
,或使用js闭包。 Here您可以找到有关此内容的更多信息。
答案 1 :(得分:0)
正如Carcigenicate所说,你无法访问我。以下将只打印undefined。
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
setTimeout(function(i){
console.log(i);
}, 1000);
}
}
myFunction();
<div class='mySelector'></div>
<div class='mySelector'></div>
<div class='mySelector'></div>
<div class='mySelector'></div>
<div class='mySelector'></div>
试试这个:
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
setTimeout(addClass(i), 1000);
}
}
myFunction();
function addClass(i) {
return function() {
mySelector[i].classList.add('myClass');
}
}
<div class='mySelector'>1</div>
<div class='mySelector'>2</div>
<div class='mySelector'>3</div>
<div class='mySelector'>4</div>
<div class='mySelector'>5</div>