为 clickTags 的 var 名称实现循环
Implementing loop for var names for clickTags
需要为横幅添加三个 clickTag,它们的名称类似于 clickTag1、clickTag2、clickTag3。现在代码如下所示:
for(var i = 1; i <= 3; i++) {
document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
window.open(clickTag2, '_blank'); //here I want clickTag look like clickTag + i, but its not working.
})
}
所以问题是如何循环变量名,这样我就不需要像现在这样手动输入了。
您想为此使用数组。数组是值的索引列表。
var clickTags = ["","www.nba.com","www.nhl.com","www.nfl.com"];
for(var i = 1; i <= 3; i++) {
document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
window.open(clickTags[i], '_blank'); //here I want clickTag look like clickTag + i, but its not working.
})
}
请注意,由于您是从 1
而不是 0
开始循环,因此我为 clickTags
数组的索引 0 添加了一个空白条目。
解决这个问题最干净的方法是使用 Array.
[, clickTag1, clickTag2, clickTag3].forEach(function(e, i) {
document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
window.open(e, '_blank');
})
})
另一种方法:如果您的 clickTag
是全局变量,您始终可以将它们作为 window
对象的全局属性进行访问:
for(var i = 1; i <= 3; i++) (function (i) {
document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
window.open(window['clickTag' + i], '_blank')
})
)(i)
额外的包装函数修复了上面评论中提到的闭包错误。
为什么它目前没有按您预期的方式工作:
for (var i = 1; i <= 3; i++) {
// During your first loop there is a local variable `i` whose value is 1
document.getElementById('Destination_cta_' + i)
// Here you pass an anonymous function as the second argument to addEventListener
// This creates a closure, which means the function's context includes variables
// that were in scope when it was created. Right now we have the `for` loop's variable
// `i` in the current scope, so the function keeps a *reference* to that variable.
.addEventListener('click', function() {
// When this get executed in the future, the function has to know about the variable `i`,
// and thankfully there is a reference to it in this function's closure. But remember that
// the for loop executed 3 times, using that same variable. That means that every function
// was created with a closure that is keeping a reference to the same variable, whose final
// value after the loop finished, was 4.
window.alert('clickTag' + i); // Will always alert 'clickTag4' no matter which is clicked
})
}
<div id="Destination_cta_1">1</div>
<div id="Destination_cta_2">2</div>
<div id="Destination_cta_3">3</div>
如何解决这个问题?
确保每个 addEventListener
调用在其自身的闭包中获得具有正确值的函数。做到这一点的方法是使用一个立即调用的函数表达式,你可以将你想要的值传递给它:
for (var i = 1; i <= 3; i++) {
var element = document.getElementById('Destination_cta_' + i)
element.addEventListener('click', (function(index) {
// This function is now a closure with a reference to index
return function() {
window.alert('clickTag' + index);
}
})(i)) // calling the anonymous function with the current value of `i` binds that value
// to the function's scope
}
<div id="Destination_cta_1">1</div>
<div id="Destination_cta_2">2</div>
<div id="Destination_cta_3">3</div>
需要为横幅添加三个 clickTag,它们的名称类似于 clickTag1、clickTag2、clickTag3。现在代码如下所示:
for(var i = 1; i <= 3; i++) {
document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
window.open(clickTag2, '_blank'); //here I want clickTag look like clickTag + i, but its not working.
})
}
所以问题是如何循环变量名,这样我就不需要像现在这样手动输入了。
您想为此使用数组。数组是值的索引列表。
var clickTags = ["","www.nba.com","www.nhl.com","www.nfl.com"];
for(var i = 1; i <= 3; i++) {
document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
window.open(clickTags[i], '_blank'); //here I want clickTag look like clickTag + i, but its not working.
})
}
请注意,由于您是从 1
而不是 0
开始循环,因此我为 clickTags
数组的索引 0 添加了一个空白条目。
解决这个问题最干净的方法是使用 Array.
[, clickTag1, clickTag2, clickTag3].forEach(function(e, i) {
document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
window.open(e, '_blank');
})
})
另一种方法:如果您的 clickTag
是全局变量,您始终可以将它们作为 window
对象的全局属性进行访问:
for(var i = 1; i <= 3; i++) (function (i) {
document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
window.open(window['clickTag' + i], '_blank')
})
)(i)
额外的包装函数修复了上面评论中提到的闭包错误。
为什么它目前没有按您预期的方式工作:
for (var i = 1; i <= 3; i++) {
// During your first loop there is a local variable `i` whose value is 1
document.getElementById('Destination_cta_' + i)
// Here you pass an anonymous function as the second argument to addEventListener
// This creates a closure, which means the function's context includes variables
// that were in scope when it was created. Right now we have the `for` loop's variable
// `i` in the current scope, so the function keeps a *reference* to that variable.
.addEventListener('click', function() {
// When this get executed in the future, the function has to know about the variable `i`,
// and thankfully there is a reference to it in this function's closure. But remember that
// the for loop executed 3 times, using that same variable. That means that every function
// was created with a closure that is keeping a reference to the same variable, whose final
// value after the loop finished, was 4.
window.alert('clickTag' + i); // Will always alert 'clickTag4' no matter which is clicked
})
}
<div id="Destination_cta_1">1</div>
<div id="Destination_cta_2">2</div>
<div id="Destination_cta_3">3</div>
如何解决这个问题?
确保每个 addEventListener
调用在其自身的闭包中获得具有正确值的函数。做到这一点的方法是使用一个立即调用的函数表达式,你可以将你想要的值传递给它:
for (var i = 1; i <= 3; i++) {
var element = document.getElementById('Destination_cta_' + i)
element.addEventListener('click', (function(index) {
// This function is now a closure with a reference to index
return function() {
window.alert('clickTag' + index);
}
})(i)) // calling the anonymous function with the current value of `i` binds that value
// to the function's scope
}
<div id="Destination_cta_1">1</div>
<div id="Destination_cta_2">2</div>
<div id="Destination_cta_3">3</div>