<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
#div1,#div2,#div3 {
width: 200px;
height: 200px;
background: red;
margin: 10px;
}
</style>
</head>
<body>
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<script type="text/javascript">
var timer = null;
oDiv = document.getElementsByTagName("div");
function test(i) {
timer = setInterval(function() {
oDiv[i].style.height = oDiv[i].offsetHeight + 2 + 'px'
}, 30)
};
for (var i = 0; i < 3; i++) {
oDiv[i].onmouseover = function() {
test(i);
}
oDiv[i].onmouseout = function() {
clearInterval(timer);
}
}
</script>
</body>
</html>
1.楼主最好去学习一下MARKDOWN怎么写。
2.这个是闭包陷阱
@小_秦 已经指出问题了,也提供了解决方法。我再补充两种,其他朋友如果有其他方法的话不妨贴上来。
/*
var timer = null;
oDiv = document.getElementsByTagName("div");
for (var i = 0; i < 3; i++) {
oDiv[i].onmouseover = function() {
var _this=this;
timer = setInterval(function() {
_this.style.height = _this.offsetHeight + 2 + 'px'
}, 30);
//方法一:避免在闭包里面引用外包函数的变量,用this来代替
}
oDiv[i].onmouseout = function() {
clearInterval(timer);
}
}
*/
//===================================================================
/*
var timer = null;
oDiv = document.getElementsByTagName("div");
for (var i = 0; i < 3; i++) {
oDiv[i].onmouseover = function() {
timer = setInterval(function() {
this.style.height = this.offsetHeight + 2 + 'px'
}.bind(this), 30);
//方法一改良
}
oDiv[i].onmouseout = function() {
clearInterval(timer);
}
}
*/
//===================================================================
var timer = null;
oDiv = document.getElementsByTagName("div");
function test(i) {
timer = setInterval(function() {
oDiv[i].style.height = oDiv[i].offsetHeight + 2 + 'px'
}, 30)
};
for (var i = 0; i < 3; i++) {
oDiv[i].onmouseover = function(num){
return function() {
test(num);
}
}(i);
//方法二:用iife来替换,事实上,就是用iife的形参作为桥梁在两个作用域之间传值
oDiv[i].onmouseout = function() {
clearInterval(timer);
}
}
在 onmouseover
里 this
就是当前的这个, 所以不需要根据它对应的i
再从 oDiv
中去找.
况且你的 i
, 在循环跑完之后, 它的值等于 3
, 所以你在后面触发 mouseover
并使用 i
的时候, 是传递的 3
过去的, 而你的oDiv
的最大下标是 2
所以出错的.
推荐的做法如下:
var timer = null;
oDiv = document.getElementsByTagName("div");
function test(obj) {
timer = setInterval(function() {
obj.style.height = obj.offsetHeight + 2 + 'px'
}, 30)
};
for (var i = 0; i < 3; i++) {
oDiv[i].onmouseover = function() {
test(this);
}
oDiv[i].onmouseout = function() {
clearInterval(timer);
}
}
再次优化后:
(function(){
var timer = null,
onMouseOver = function(){
var obj = this;
timer = setInterval(function() {
obj.style.height = obj.offsetHeight + 2 + 'px';
obj = null;
}, 30);
},
onMouseOut = function(){
clearInterval(timer);
},
oDiv = document.getElementsByTagName("div");
for (var i = oDiv.length; i--; ) {
oDiv[i].onmouseover = onMouseOver;
oDiv[i].onmouseout = onMouseOut;
}
})();
1)div1,#div2,#div3{width:200px;height:200px;background:red;margin:10px;}
==》#div1,#div2,#div3{width:200px;height:200px;background:red;margin:10px;}
2)div,mouseover事件触发函数中的i为3,这里涉及到js中变量作用域
3) div的事件绑定推荐使用代理的方式-不用为每一个div绑定事件回调
你声明变量时,要用var,如果是全局变量时函数内部不用var,儿最外层原始变量需要var的,这段代码,错误百出啊,以上楼层说了闭包的问题,就不多说了
timer = null; 后面应该是逗号
var timer=null,
oDiv=document.getElementsByTagName("div");
你可以使用闭包实验一下你这个for绑定事件肯定不对的,绑定的i都是3所以肯定oDiv[3]都是不存在的,