首先,感慨一下:做个网站是 真费劲,本以为有个域名,服务器,其他的都不是问题,但是我真的错了...
今天做网站副页的时候突然遇到一个特别不起眼的问题,但它确实是个问题,先上错误代码吧...
<script> var a = document.getElementsByClassName("box9"); var left1 = document.getElementsByClassName("left"); for(var i= 0;i<a.length;i++){ a[i].onmouseover = function () { this.style.left = '200px' } } </script>
我就想做个for循环的鼠标移入事件,但是都成功不了,一直报错如下:
Uncaught TypeError: Cannot read property 'style' of undefined
at HTMLAnchorElement.a.(anonymous function).onmouseover (http://localhost:63342/Untitled/media/my_pro.html?_ijt=lqksf11hvkpu0utkikj2ii5fvi:97:30);
看到这个错误感觉好熟悉,没想百度,第一反应想是不是style属性不存在,然后我在class = left 标签行内设置style属性,还是没有成功,检查各种是不是变量名、属性名写错了(作为一只小白,写代码最头疼的就是:费时费力还找不到的很多错误等找到的时候才发现就是一个字母写错了、一个分号没加、丢了一个括号...总之,撸代码,细心很关键。)
然而...找了半天,还是没有找到哪里错了...(丝毫没有考虑到是逻辑错误)
最后,求助百度....
才发现,这原来就是for循环与异步回调的问题,
追其根源,是因为JS是单线程运行的,所以所有的异步操作要等同步操作执行完毕后再执行,所以,上面的代码,点击事件在执行的时候都要放到回调队列里面,等主线程执行完之后,回调队列的事件才会执行,所以,等那时候,i 已经等于4 了(a.length = 4),那么a【4】就为undefined了,undefined 的 style 属性可不就是报错 undefined 嘛?
下面上修改过后的代码:
<script> var a = document.getElementsByClassName("box9"); var left1 = document.getElementsByClassName("left"); for(var i= 0;i<2;i++){//第一个i (function (i) {//第二个i a[i].onmouseover = function () { left1[i].style.left = '200px' } })(i)//第三个i } </script>
上面的代码,声明一个匿名函数并且立即调用,参数设置为 i ,那么全局变量 i 就可以作为实参传进去,这里啰嗦一句:上面的三个 i 其实本质上是不一样的,第一个 i 是全局变量 i ,它在for循环里面,为什么还是全局变量呢?因为for循环并不能构成作用域,只有函数才能构成作用域。第二个 i 是形参,通俗的说就是形式上的参数,就是用来装参数的盒子,相当于载体,所以把第二个 i 改成 j/k/l/m/n....都可以..因为它就是走的一个形式,那么实质是谁呢?对,实质就是第三个 i ,第三个 i 值与第一个 i 相等 ,但是本质不一样的,第三个 i 就是实际上的参数,叫实参。