(笔试题)下面程序有什么问题,怎么修改?

<body>
  <ul>
    <li>test1</li>
    <li>test2</li>
    <li>test3</li>
  </ul>
  
  <script>
      var lis = document.querySelectorAll("ul li");
      for(var i = 0,len = lis.length; i < len; i++){
        lis[i].addEventListener('click',function(){
           console.log(i);
        },false);
      }
  </script>
</body>
阅读 2.2k
3 个回答

js的块级作用域问题,在你点击时,for已经完成循环,此时i为3
1.var 改成let

 for(let i = 0,len = lis.length; i < len; i++){
        lis[i].addEventListener('click',function(){
           console.log(i);
        },false);
      }

2.加个闭包

   for(var i = 0,len = lis.length; i < len; i++){
          (function(i){
            lis[i].addEventListener('click',function(){
           console.log(i);
        },false);
          })(i)   
      }

3.给每个 lis[i]一个自定义属性把i暂存起来

  for(var i = 0,len = lis.length; i < len; i++){
          lis[i].index = i;
        lis[i].addEventListener('click',function(){
           console.log(this.index);
        },false);
      }

有2个问题。

  • 第一个问题就是性能不好。假设以后里面的li有1000个,你每一个都绑定一个事件,会占用大量内存。推荐使用事件委托。代码示例如下:
var ul = document.querySelector('ul');
ul.addEventListener('click',function(e){
    alert(e.target.innerText);
 });

如果面试官非要点击弹出li的相对顺序的话,改成下面的代码即可

var lis = document.querySelectorAll("ul li");
var ul = document.querySelector('ul');
for(let i = 0,len = lis.length; i < len; i++){
  lis[i].index  = i
}
ul.addEventListener('click',e => {
    alert(e.target.index);
});
  • 第二个问题就是点击所有li,输出结果都是3。可以参考陌路凡歌的答案,可以把代码改成es6方便装逼
// 使用es6的let和箭头函数
for(let i = 0; i < lis.length; i++){
   lis[i].addEventListener('click',() => {
     alert(i);
   },false);
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题