我想通过for循环内嵌一个事件监听,捕获我点击的是哪个个区域,执行对应函数。可是为什么点击第一个或第二个区域,输出都是2呢?
不是应该对应 0 和 1 吗
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>为什么</title>
<style type="text/css">
.container{
width: 100px;
height: 100px;
border: 1px solid black;
}
</style>
</head>
<body>
<div class="container">container1</div>
<div class="container">container2</div>
<script type="text/javascript">
var container = document.getElementsByClassName("container");
console.log(container.length); //2
for (var i = 0; i < container.length; i++) {
container[i].onmouseup = function(){
console.log(i) //2 (不明白为什么,不是应该0或1吗)
}
}
</script>
</body>
</html>
绑定结束时,i的值就是2,跳出循环,这时候i的值就是2,而不是你触发这个事件时,才绑定的,才执行这个函数,而是文档流加载完以后,就一直是2,所以你触发输出i就一直是2,你把两个标签的内容换一下,就能看到,i还是2,但触发标签是不同的
http://www.zhihu.com/question/20019257
设计到闭包,。。。
var container = document.getElementsByClassName("container");
console.log(container.length); //2
for (var i = 0; i < container.length; i++) {
container[i].onmouseup = (function (i) {
return function () {
console.log(container)
console.log(i)
}
})(i)
}
这个类似于函数闭包,i的值在执行完绑定函数后就一直为2,所以触发是都输出2,你改为输出this.innerHTML,会发现不同,但i还是2
在for循环中,你给每个container的mouseup事件绑定一个函数,因为是绑定的是函数,他不是立即执行,而是延迟执行的,也就是在真正事件触发的时候才绑定变量。在函数内部调用了变量i,而函数内部没有定义变量i,而且也没有传入参数i,按照Javascript的规则,他会从最近原则查找i,直到找到位置,或者报错未定义变量。虽然循环中止执行了i=0和1,但i其实最后的值是2,因为等于2之后,i < container.length为false,才停止了i++的计算,退出了循环。
所以mouseup事件执行console.log(i) 且i=2
首先你是在dom文档中定义的var,所以属于GO链也就是说var定义的基础类型在本方法和子方法中中间无论你改变多少次只会有一个储存起来的也会跟着变化,定义引用的不同,和储存内存有关。你这个代码可以有两种方法改,一种把var改成let,还有一种用闭包在事件和循环外面加一个方法,都可以。let定义的变量只在本循环有效每次循环会自动帮你重新定义一个。