事件监听方法
1.运行结果会覆盖
const btn = document.querySelector('button')
// btn.onclick = function(){
// alert(11)
// }
// btn.onclick = function(){
// alert(22)
// }
2.运行的时候会一一的出现,不会覆盖。
const btn = document.querySelector('button')
btn.addEventListener('click',function(){
alert(11)
})
btn.addEventListener('click',function(){
alert(22)
})
焦点事件
focus有焦点触发
blur失去焦点触发
<body>
<input type="text">
<script>
const input = document.querySelector('input')
input.addEventListener('focus',function(){
console.log('有焦点触发');
})
input.addEventListener('blur',function(){
console.log('失去焦点触发');
})
</script>
</body>
事件流
事件流是对时间执行过程的描述,了解事件的执行过程有助于对事件的理解,提升开发实践中对事件运用的灵活度。
任意时间被触发总会经历两个阶段:【捕获阶段】和【冒泡阶段】。
捕获阶段是【从父到子】的过程,而冒泡阶段是【从子到父】。
<body>
<h3>事件流</h3>
<p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上</p>
<div class="outer">
<div class="inner">
<div class="child"></div>
</div>
</div>
<script>
//获取嵌套的3个节点
const outer = document.querySelector('.outer')
const inner = document.querySelector('.inner')
const child = document.querySelector('.child')
//html元素添加事件
document.documentElement.addEventListener('click',function(){
console.log('html....');
})
//body元素添加事件
document.body.addEventListener('click',function(){
console.log('body....');
})
//外层盒子添加事件
outer.addEventListener('click',function(){
console.log('outer....');
})
//中间的盒子添加事件
outer.addEventListener('click',function(){
console.log('inner....');
})
//内层盒子添加事件
outer.addEventListener('click',function(){
console.log('child....');
})
</script>
</body>
执行上述代码后,当单击事件触发时,其祖先元素的单击事件也相机触发
结合事件流的特征可知,当某个元素被触发时,事件总会先经过祖先才能达到当前元素,然后再由当前元素向祖先传递,事件在流动的过程中遇到相同的事件便会被触发。
事件相继触发的【执行顺序】,事件的执行顺序是可控的,即在捕获阶段或者在冒泡阶段。
如果在冒泡阶段执行的,就称其为冒泡模式,先执行子盒子事件,再执行父盒子事件,默认是冒泡模式。
如果是在捕获阶段执行的,就称其为捕获模式,先执行父盒子事件再执行子盒子事件。
<body>
<h3>事件流</h3>
<p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p>
<div class="outer">
<div class="inner"></div>
</div>
<script>
const outer = document.querySelector('.outer')
const inner = document.querySelector('.inner')
//外层盒子
outer.addEventListener('click',function(){
console.log('outer...');
})//这里的true表示捕获阶段执行事件
inner.addEventListener('click',function(){
console.log('inner...');
},true)
</script>
</body>
结论:
-
addEventListener第三个参数决定了事件是在捕获阶段还是冒泡阶段触发。
-
addEventListener第三个参数是true表示捕获阶段触发,默认值false为冒泡阶段触发。
-
事件流只会在父子元素具有相同事件类型才会产生影响。
-
绝大部分场景都采用默认的冒泡模式(其中一个原因是早期 IE 不支持捕获)。
阻止冒泡
阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响其对应的祖先元素。
<body>
<h3>阻止冒泡</h3>
<p>阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。</p>
<div class="outer">
<div class="inner">
<div class="child"></div>
</div>
</div>
<script>
//获取嵌套的3个节点
const outer = document.querySelector('.outer')
const inner = document.querySelector('.inner')
const child = document.querySelector('.child')
//外层的盒子
outer.addEventListener('click',function(){
console.log('outer...');
})
//中间的盒子
inner.addEventListener('click',function(ev){
console.log('inner...');
//阻止事件冒泡
ev.addEventListener()
})
//内层的盒子
child.addEventListener('click',function(ev){
console.log('child...');
//借助事件对象,阻止事件向上冒泡
ev.stopPropagation()
})
</script>
</body>
结论;事件对象中的ev.stopPropagation方法,专门用来阻止事件冒泡。
鼠标经过事件:
mouseover 和 mouseout 会有冒泡效果
mouseenter 和 mouseleave 没有冒泡效果 (推荐)