我正在努力建立一个画廊。
我成功完成了除最后一个步骤之外的所有步骤,点击缩略图会将段落中的文本更改为我放入数组的另一个文本。
当我在for循环中时,我希望当我单击索引2的图像时显示索引2的文本。我似乎遵循了正确的语法,但段落仍显示“未定义”结果是。但是当我选择一个索引时,就像我点击的那个图片一样,我想显示索引3的文本,它可以工作。
这是我的简化代码,可以让我在点击段落时显示文字。如果你们不使用jQuery,那将是很棒的。谢谢大家!
<!DOCTYPE html>
<html>
<body>
<p class="demo">1</p>
<p class="demo">2</p>
<p class="demo">3</p>
<script>
var cars = ["Saab", "Volvo", "BMW"];
var para = document.getElementsByClassName("demo");
for (k=0;k<cars.length;k++){
para[k].onclick=function(){
this.innerHTML = cars[k];
}
}
</script>
</body>
</html>
答案 0 :(得分:4)
这是javascript的范围问题。你的变量k,注意你每次都增加它。当点击事件调用onclick时,无论您点击什么图像,k都会以3
作为其值。
您可以尝试这种解决方法(请注意我稍微清理了一下代码)
<!DOCTYPE html>
<html>
<body>
<p class="demo">1</p>
<p class="demo">2</p>
<p class="demo">3</p>
<script>
var cars = ["Saab", "Volvo", "BMW"];
var para = document.getElementsByClassName("demo");
for (k = 0; k < cars.length; k++) {
(function (index) {
para[index].onclick = function() {
this.innerHTML = cars[index];
}
}(k));
}
</script>
</body>
</html>
在这种情况下,对于它所使用的每个值,单独的副本由k组成,该副本在函数内部可用作“索引”。
有关具体问题的详细信息,请参阅此帖:JavaScript closure inside loops – simple practical example
答案 1 :(得分:3)
使用关闭:
<script>
var cars = ["Saab", "Volvo", "BMW"];
var para = document.getElementsByClassName("demo");
for (var k = 0; k < cars.length; k++) {
(function (k) {
para[k].onclick = function () {
this.innerHTML = cars[k];
}
}(k));
}
</script>
小提琴:http://jsbin.com/zezuhitige
<强>原因:强>
该值始终是循环的最后一个值。因此,当点击发生时,您将始终获得k = 3
,在点击时执行k
值,即3
。闭包通过在分配时执行值来防止这种情况。
答案 2 :(得分:0)
更灵活的做法是这样的:
<div id="container">
<p class="demo" data-car="Saab">1</p>
<p class="demo" data-car="Volvo">2</p>
<p class="demo" data-car="BMW">3</p>
</div>
JS:
document.getElementById('container').onclick = function(e) {
e = e || window.event;
var target = e.srcElement || e.target;
while( target != this && !target.className.match(/\bdemo\b/)) {
target = target.parentNode;
}
if( target != this) {
// target is now one of the .demo elements
target.innerHTML = target.getAttribute("data-car");
}
};
这会将数据本身放入其引用的元素中,并且只附加一个事件监听器而不是每个汽车一个 - 在更大的应用程序中,您拥有的事件处理程序越少越好!
答案 3 :(得分:0)
查看JS闭包并尝试以下内容:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
document.addEventListener("DOMContentLoaded", function(event) {
var cars = ["Saab", "Volvo", "BMW"];
var para = document.getElementsByClassName("demo");
for (k=0;k<cars.length;k++){
var clojureCar = cars[k];
para[k].onclick=function(){
this.innerHTML = clojureCar;
}
}
});
<!DOCTYPE html>
<html>
<body>
<p class="demo">1</p>
<p class="demo">2</p>
<p class="demo">3</p>
<script>
var cars = ["Saab", "Volvo", "BMW"];
var para = document.getElementsByClassName("demo");
for (k=0;k<cars.length;k++){
para[k].onclick=function(){
this.innerHTML = cars[k];
}
}
</script>
</body>
</html>
答案 4 :(得分:0)
我认为添加像这样的事件监听器是一个很好的做法。并且因为你的click事件是在你的循环完成之后执行的所以它总是3是未定义的。
var cars = ["Saab", "Volvo", "BMW"];
var para = document.getElementsByClassName("demo");
for (k=0;k<cars.length;k++){
var div = para[k];
(function (i) {
div.addEventListener('click', function() { this.innerHTML = cars[i]; });
})(k);
}