首页 > 这个JavaScript我就是想不通,我明明有定义,为什么老报错没有定义!

这个JavaScript我就是想不通,我明明有定义,为什么老报错没有定义!

<!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);
            }
        }

onmouseoverthis 就是当前的这个, 所以不需要根据它对应的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]都是不存在的,

【热门文章】
【热门文章】