事件代理: 利用事件冒泡,把事件监听绑定到事件容器上。应用场景就是页面上有一些新增的元素,这些元素也都是需要绑定事件的。
举列说明: 这个列子实现的效果是,点击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);
})
网友评论