事件代理

事件代理: 利用事件冒泡,把事件监听绑定到事件容器上。应用场景就是页面上有一些新增的元素,这些元素也都是需要绑定事件的。
举列说明: 这个列子实现的效果是,点击li,能够把li的文本显示在下方,同时点击添加按钮,能添加进新的文本。

<style>
        .container {
            margin: 30px auto;
            width: 900px;
        }
        ul, li {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        ul {
            background: pink;
        }
        .container li {
            border: 1px solid #ccc;
            line-height: 1.5;
            margin-right: 30px;
        }
        #show {
            background: #ccc;
        }
    </style>
---------
<body>
    <div class="container">
        <ul>
            <li>aa</li>
            <li>bb</li>
            <li>cc</li>
            <li>dd</li>
        </ul>
        <input type="text" id="add-input"><button id="btn">添加</button>
        <div id="show"></div>
    </div>
         <script>
var liNodes = document.querySelector('.container li');
var oDiv = document.querySelector('#show');
liNodes.forEach(function() {
console.log(this);      // window
 this.addEventListener('click', function() {
 oDiv.innerText = this.innerText;
}, false);
})
   </script>

此时点击li出现"undefined", 而并不是文本内容,查看控制台,this此时指代的window。下面就不用this,而是通过传参的方式。修改代码如下。

liNodes.forEach(function(node) {
console.log(node);     
 node.addEventListener('click', function() {
 oDiv.innerText = this.innerText;
}, false);
})
 // 此时得到就是li标签了,同时点击也会在下面显示li文本内容。

// 添加文本内容的代码

var oBtn = document.querySelector("#btn");
var addText = document.querySelector("#add-input");
var oUl = document.querySelector(".container ul");
oBtn.addEventListener('click', function() {
var node = document.createElement('li');
node.innerText = addText.value;
oUl.appendChild(node);
}, false);

此时点击添加按钮,能够添加上新的文本,但是点击新增的li,并不会把文本内容给显示出来。修改代码,并且将两部分合并起来。

<script>
        var liNodes = document.querySelectorAll('.container li');
        var oBtn = document.querySelector('#btn');
        var oDiv = document.querySelector("#show");
        var addText = document.querySelector("#add-input");
        var oUl = document.querySelector(".container ul");
        liNodes.forEach(function(node) {
            console.log(node);
            node.addEventListener('click', function() {
                oDiv.innerText = this.innerText;
            }, false)
        });
        oBtn.addEventListener('click', function() {
            var node = document.createElement('li');
              /*  修改的地方,新添加的li,即node也要添加点击事件,
才能达到效果。*/
            node.addEventListener('click', function() {
                oDiv.innerText = this.innerText;
            }, false)
            node.innerText = addText.value;
            oUl.appendChild(node);
        }, false);
</script>

但是上面写的太过繁琐。事件冒泡,即我们无论是点击哪一个li,都会冒到父容器ul上,所以我们直接给ul,添加点击事件。

// 事件代理的写法
oUl.addEventListener('click', function(e) {
            var target = e.target || e.srcElement;  // 获取事件的目标元素
// 加if条件判断是为了,防止点击ul里除了li的空白处,会触发点击事件。
            if(target.tagName.toLowerCase() === 'li') {  
                oDiv.innerText = target.innerText;
            }
        }, false);
oBtn.addEventListener('click', function() {
            var  newNode = document.createElement('li');
            newNode.innerText = addText.value;
            oUl.appendChild(newNode);
        }) 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容