DOM事件流:
事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。
目标阶段:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。
事件冒泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。
事件委托
如果在需要有多个DOM事件需要监听的情况下,给每一个DOM都绑定监听函数,对性能会有极大的影响,事件委托便应运而生。
事件委托利用了利用冒泡的原理,把本应该添加到某个元素上的事件委托给他的父级,从而减少DOM交互达到网页优化。
例如:
写法1
<body>
<ul id="ul">
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
</ul>
</body>
<script>
window.onload=()=>{
var ul=document.getElementById('ul');
ul.onmouseover=(e)=>{
var e=e||window.event;
var _target=e.srcElement||e.target;
console.log(_target) //触发事件的源头li
console.log(e.currentTarget) //此事件绑定的元素 ul
if(_target.nodeName.toLowerCase() == 'li'){
console.log(_target.innerHTML) //输入目标li中的值
}
}
}
</script>
event.target和event.currentTarget
currentTarget:表示此事件绑定的元素
target:表示触发一系列事件的源头(具体的子元素)
按照上方的写法,就不需要给每个li添加事件,减少DOM操作。
写法2
window.onload=()=>{
var ul=document.getElementById('ul');
ul.addEventListener('mouseover',(e)=>{
var e=e||window.event;
var _target=e.srcElement||e.target;
console.log(_target)
console.log(e.currentTarget)
if(_target.nodeName.toLowerCase() == 'li'){
_target.style.background = 'red';
console.log(_target.innerHTML)
}
})
ul.addEventListener('mouseout',(e)=>{
var e=e||window.event;
var oli=e.srcElement||e.target;
if(oli.nodeName.toLowerCase() == 'li'){
oli.style.background = '';
}
})
这种写法又叫DOM2级事件
此时的事件名不带on,例如mouseover;
添加事件监听器:addEventListener(事件名,处理函数,布尔值(是否发生在捕获阶段。默认为false,事件发生在冒泡阶段))
移除事件监听器:removeEventListener(事件名,处理函数)
IE下的事件监听器:attachEvent(事件名,处理函数),detachEvent(事件名,处理函数)
此时的事件名带on,onmouseover
事件的传播是可以阻止的:
- 在W3c中,使用stopPropagation()方法
- 在IE下设置event.cancelBubble = true;
在捕获的过程中stopPropagation()后,后面的冒泡过程就不会发生了。
使用stopPropagation
<body>
<div id='outside'>
<ul id="ul">
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
</ul>
</div>
</body>
<script>
window.onload=()=>{
var ul=document.getElementById('ul');
ul.onmouseover=(e)=>{
var e=e||window.event;
e.stopPropagation() //防止冒泡
var _target=e.srcElement||e.target;
console.log(_target) //触发事件的源头li
console.log(e.currentTarget) //此事件绑定的元素 ul
if(_target.nodeName.toLowerCase() == 'li'){
console.log(_target.innerHTML) //输入目标li中的值
}
}
var div=document.getElementById('outside')
div.addEventListener('mouseover',(e)=>{
console.log('显示不了')
})
}
</script>
来源:CSDN
作者:DrAlexsander
链接:https://blog.csdn.net/qq_42880714/article/details/104671805