我试图为一组元素创建一个动画效果并在jquery中成功创建了效果,但我正在尝试学习vanilla javascript并想要一些帮助来翻译我已经拥有的内容:
<div id="vertical-lines">
<span class="one item"></span>
<span class="two item"></span>
<span class="three item"></span>
<span class="four item"></span>
<span class="five item"></span>
</div>
这是可以正常使用的jquery。
$('.item').each(function(i){
setTimeout(function(){
$('.item').eq(i).addClass('is-visible');
}, 200 * i);
});
这就是我一直在尝试的但是继续从[i]
返回未定义var lineItem = document.querySelectorAll('.item'), i
lineItem.forEach(i => {
setTimeout(function(i){
console.log(lineItem[i])
// lineItem[i].className += "otherclass"
}, 20)
});
我很感激我对错误的解释!我是javascript的新手,但是到目前为止一直喜欢它,想要了解更多并从错误中吸取教训。
答案 0 :(得分:1)
在Array.prototype.forEach()
中,三个参数自动(按顺序)提供:
我建议您按如下方式重写您的方法:
var lineItem = Array.from (document.querySelectorAll('.item'))
lineItem.forEach((arrayElement, index) => {
setTimeout(function(){
console.log(lineItem[index]);
lineItem[index].className += " otherclass";
}, 20);
});
此外,我建议您不要操纵Element.className
返回的字符串,而应使用Element.classList.add('otherclass');
方法。
答案 1 :(得分:0)
您与setTimeout
一起使用的闭包的参数i
将是未定义的。 setTimeout
不会将任何参数传递给闭包。
.forEach()
将当前元素作为第一个参数传递,将索引作为第二个参数传递。
为了将每个项目的延迟增加20ms,您应该使用以下公式:20 * (index + 1)
。
您的代码应如下所示:
var lineItem = document.querySelectorAll('.item')
lineItem.forEach((item, index) => { // Add item to closure
setTimeout(() => { // Removed i from closure
console.log(item) // Console logging item. Could use lineItem[index] instead
item.className += "otherclass"
}, 20 * (index + 1)) // Increase the delay time by 20ms for each item
});
答案 2 :(得分:-1)
为什么不使用递归调用而不是ForEach?
var lineItem = [...document.querySelectorAll('.item')], i = 0;
function delayIt(arr, i) {
var item = arr.shift();
setTimeout(() => {
console.log(item);
arr.length && delayIt(arr, i);
}, 20 * ++i)
}
delayIt(lineItem, i)