1 .DOM事件模型
DOM事件模型是W3C制定的标准模型,既一次事件的发生包含三个过程:事件捕获阶段、事件目标阶段、事件冒泡阶段
2.事件捕获
事件的触发响应会从最外层目标一层层地向内到最内层
3.事件冒泡
事件的触发响应会从最底层目标一层层地向外到最外层
<style>
#parent {
position: relative;
border: 1px solid;
height: 300px;
width: 300px;
background: yellow;
}
#child {
position: absolute;
border: 1px solid;
height: 100px;
width: 100px;
background: red;
top: 300px;
left: 200px;
display: none;
}
</style>
<body>
<div id="parent">
我是父元素
<div id="child">
我是子元素
</div>
</div>
<script>
let parent = document.getElementById('parent')
let child = document.getElementById('child')
parent.onclick = (e) => {
console.log('显示啦')
child.style.display = 'block'
}
window.onclick = (e) => {
console.log('隐藏啦')
child.style.display = 'none'
}
</script>
</body>
点击父元素,子元素未显示,因为事件冒泡,点击父元素会触发window,导致子元素被隐藏。
4.阻止冒泡
stopBubble函数:
function stopBubble(e) {
//如果提供了事件对象,则这是一个非IE浏览器
if (e && e.stopPropagation)
//因此它支持W3C的stopPropagation()方法
e.stopPropagation();
else
//否则,我们需要使用IE的方式来取消事件冒泡
window.event.cancelBubble = true;
}
上面例子在点击父元素时调用stopBubble(e),子元素正常显示
5.阻止默认行为
function stopDefault(e){
if(e && e.preventDefault){
e.preventDefault();
}else{
window.event.returnValue = false;
}
}
6.事件委托
- 利用冒泡的原理,将子元素事件加到 父元素 或 祖先元素上,触发执行效果
- 适用于可能会新增子元素并且需要对子元素绑定事件的场景
- 事件代理实际上是事件冒泡的一种应用
例1:
<ul id="list">
<li>red</li>
<li>yellow</li>
<li>blue</li>
</ul>
点击页面中的li元素,输出li中的颜色,不用事件委托:
(function(){
var list = document.getElementById('list');
var colors = list.getElementsByTagName('li');
for(var i=0;i<colors.length;i++){
colors[i].addEventListener('click',showColor,false);
};
function showColor(e){
var x = e.target;
alert("The color is " + x.innerHTML);
};
})();
利用事件委托:
(function(){
var list = document.getElementById('list');
list.addEventListener('click',showColor,false);
function showColor(e){
var x = e.target;
if(x.nodeName.toLowerCase() === 'li'){
alert('The color is ' + x.innerHTML);
}
}
})();
利用事件委托大量减少内存占用,减少事件注册。
例2:
<body>
<ul id="thl">
<li>001</li>
<li>002</li>
<li>003</li>
</ul>
<button onclick="fun()">touch</button>
<script>
var thl= document.getElementById('thl');
var aLi = thl.getElementsByTagName('li');
for (var i = 0; i < aLi.length; i++) {
aLi[i].onclick = fn;
}
function fn (){
console.log(this.innerHTML);
}
function fun(){
var node=document.createElement("li");
var textnode=document.createTextNode("maomaoliang");
node.appendChild(textnode); document.getElementById("thl").appendChild(node);
}
</script>
</body>
每新增元素要手动添加事件
利用事件委托:
<script>
var thl= document.getElementById('thl');
thl.onclick = function(e) {
e = e || event;
//兼容处理
var target = e.target || e.srcElement;
//找到li元素
if (target.nodeName.toLowerCase() == 'li') {
console.log(target.innerHTML);
}
};
function fun(){
var node=document.createElement("li");
var textnode=document.createTextNode("maomaoliang");
node.appendChild(textnode);
document.getElementById("thl").appendChild(node);
}
</script>
利用事件委托实现了新增元素实现动态绑定事件