搜索

首页  >  问答  >  正文

javascript - JS中for循环的变量i能否用于在for循环中定义的函数?

JS初入者,请问如图所示,该如何才能设置背景?

黄舟黄舟2776 天前769

全部回复(3)我来回复

  • ringa_lee

    ringa_lee2017-04-10 15:45:10

    你定义的函数是一个事件回调函数,该函数得以执行的前提是 mouseover 事件发生了,然而在那一时刻 for 循环里的变量 i 已经被垃圾回收了,所以 li_line_left[i] 这个表达式是无效的。

    解决的办法可以用闭包——但没必要,也容易搞晕你;比较合理的方案是使用事件对象获取当前的 DOM 元素,例如:

    li_line_right[i].onmouseover = function(event) {
        event.currentTarget.style.backgroundColor = '#add8e6'
    }

    我去~没留神差点踩坑里,仔细一看你要的是 mouseoverli_line_right 然后改变 li_line_left 的背景色!而且看样子你是有多个成对的,所以你要循环遍历用相同的下标去找到另外一个,我这么理解没错吧?

    好吧之前的代码无效,现在的问题变成了:“当事件发生在右边的 li 时,如何获取左边对应的 li“。

    循环里的 i 为什么失效我已经解释过了,如果你一定要依赖这个下标,那就得上闭包了。然而我依然不推荐,因为首先闭包对初学者有点难,我懒得解释……二来,你这种写法等于为每一个 li 都绑定了事件回调函数——这是我最后说你槽点多多的其中之一——即使用了闭包也解决不了这个问题。

    如果是我的话,我可能会在这些 li 生成的时候为它们添加一些可以一一对应的标记(比如利用 data-*id 之类的属性),这样事件捕获之后我可以知道当前这个 li_line_right 对应的标记是什么,然后遍历 li_line_left 找出相同标记的那一个,就可以改变背景色了,这是比较简单的办法。有一个好处是我不需要绑定 n 个事件回调,利用事件委托机制可以在上层 DOM 绑定一次即可。

    然而,你的代码槽点真是多……建议看一些比较新的 Javascript/DOM 相关的书籍,否则你会走很多冤枉路。

    回复
    0
  • 迷茫

    迷茫2017-04-10 15:45:10

    javascript没有块级作用域,只有函数作用域和全局作用域。

    在循环完成之后,i变量的值为lilineright.length,显然lilineright[lilineright.length]为undefined。


    `lilineright[i].onmouseover = function (){

    li_line_right[i].style.backgroudColor = "#ADD8E6";

    }`中,每次触发mouseover,由于回调函数中并没有i的值,i的值都是从上级作用域寻找,即值为lilineright.length。

    要解决这个问题只需改为:

    li_line_right[i].onmouseover = (function (i){
        return function(){
                li_line_right[i].style.backgroudColor = "#ADD8E6";
        }
    })(i);

    回复
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-10 15:45:10

    循环完之后 i 的值变成了 li_line_right.length 的值,因此会出现这个问题。要解决这个问题就是要构造出一个闭包:

    改成下面这样:

    (function (i) {
        li_line_right[i].onmouseover = function () {
            li_line_left[i].style.backgroundColor = '#ADD8E6';
        };
    })(i);

    上面的代码在事件绑定的外面加了个匿名的闭包,在闭包(这里就是匿名函数)里面定义的函数(这里是指事件处理函数)会「记住」它所处的上下文(这是指匿名函数中所有的变量)环境。

    SF 上有很多关于闭包的讲解,有兴趣的话可以搜索一下。

    回复
    0
  • 取消回复