0
点赞
收藏
分享

微信扫一扫

JavaScript循环绑定事件问题及解决方法

巧乐兹_d41f 2022-01-08 阅读 59

html代码

  <ul>
        <li>Lorem.<button>删除</button></li>
        <li>Commodi.<button>删除</button></li>
        <li>Tenetur!<button>删除</button></li>
        <li>Corrupti?<button>删除</button></li>
        <li>Obcaecati.<button>删除</button></li>
        <li>Praesentium.<button>删除</button></li>
        <li>Vero?<button>删除</button></li>
        <li>Voluptates.<button>删除</button></li>
        <li>Perferendis?<button>删除</button></li>
        <li>Aliquam!<button>删除</button></li>
    </ul>

如果我们想实现点击按钮删除一行li,第一反应是用一个for循环给按钮绑上点击事件,下面我们用这个思路写出来,看问题出在哪里

问题代码

 var btns = document.querySelectorAll('button');
        for(var i = 0;i < btns.length;i++){
            btns[i].onclick = function(){
                console.log(i);// 每次都打印 10
                 btns[i].parentElement.remove();
            }
        }

运行点击删除,却出现报错

 不管点击哪个按钮,输出的都是10。 以我的理解是因为for循环是瞬发的,事件是绑定上了,但是这个函数是点击时调用的,绑定事件的时候i并没有被传入执行函数里,执行函数里没有声明i这个变量,所以它会去外部寻找i,此时循环早已结束,外部的i的值等于10;

解决方案

方案1

 var btns = document.querySelectorAll('button');
        for(var i = 0;i < btns.length;i++){
            btns[i].onclick = function(){
                console.log(i);// 每次都打印 10
                 this.parentElement.remove();
            }
        }

这个方法是利用this关键字,涉及到了this指向的问题,这里是btns这个对象调用这个函数,所以此时的this是指向这个对象本身。

方案2

 var ul = document.getElementsByTagName('ul')[0];
        ul.onclick = function(e){
            // 判断当前点击的目标元素是不是button,只有点击的元素时button 才能做删除操作
            if(e.target.nodeName === 'BUTTON'){
                // 一个元素的父节点一定是一个元素节点
                e.target.parentElement.remove();
            }
           
        }

用事件委托实现这个功能,button不再处理事件,委托给父元素,利用事件对象Event进行判断,

 判断当前点击的目标元素是不是button,只有点击的元素时button 才能做删除操作;

方案3

       var btns = document.querySelectorAll('button');
        for (var i = 0; i < btns.length; i++) {
            (function fn(index) {
                
                btns[i].onclick = function() {
                    btns[i].parentElement.remove();
                 
                }
            })(i)
        }

利用闭包解决,将一个函数的内部的函数返回到函数外部去,这一现象可以称作闭包;此时btns为全局变量,每次循环会生成一个立即执行函数,立即执行函数里的事件函数给到了一个全局变量btns,所以也是闭包。

每个立即执行函数里都会传入i;这个i的值保存在这个立即执行函数的作用域里,所以此时点击按钮时,查询 这个值会在这个立即执行函数的作用域里找,并不会去找到全局的 i

举报

相关推荐

0 条评论