事件
事件流
指的是事件完整执行过程中的流动路径
两个阶段:
- 捕获阶段:从大到小
- 冒泡阶段:从小到大
实际开发中都是使用事件冒泡为主
事件捕获
从DOM的根元素开始取执行对应的事件(从外到里)
document.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
第三个参数传入true代表是捕获阶段触发,默认false(很少使用)
事件冒泡
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程称为冒泡
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
事件冒泡默认时存在的(L2事件监听也是默认事件冒泡)
<style>
.father{
w 500px;
h 500px;
bgc blue;
}
.son{
w 200px;
h 200px;
bgc skyblue;
}
</style>
<div class="father">
<div class="son">
</div>
</div>
const father = document.querySelector('.father')
const son = document.querySelector('son')
document.addEventListener('click',function(){
alert('我是爷爷')
})
father.addEventListener('click',function(){
alert('我是爸爸')
})
son.addEventListener('click',function(){
alert('我是儿子')
})
此时点击son盒子会先弹出提示儿子---> 爸爸----> 爷爷
阻止冒泡
-
问题:因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素
-
需求:若想把时间就限制在当前元素内,就需要阻止事件冒泡
-
前提:阻止事件冒泡需要拿到事件对象
-
语法:
事件对象.stopPropagation();//事件对象:回调函数中的参数
此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效
const father = document.querySelector('.father')
const son = document.querySelector('son')
document.addEventListener('click',function(){
alert('我是爷爷')
})
father.addEventListener('click',function(){
alert('我是爸爸')
})
son.addEventListener('click',function(e){
alert('我是儿子')
e.stopPropagrtion();//阻断事件流动传播
})
解绑事件
事件解绑传统方式(L0)
on事件方式,直接使用null覆盖就可以实现事件的解绑
语法:
btn.onclick=function(){
alert('点击了我');
}
btn.onclick=null;
事件解绑(L2)
addEventListener方式,必须使用removeEventListener(事件类型,事件处理函数,[获取捕获或者冒泡阶段])
function fn(){
alert('点击了我')
}
btn.addEventListener('click',fn);//绑定事件
btn.removeEventListener('click',fn);//解绑事件
注意:匿名函数无法被解绑
鼠标经过事件的区别
鼠标经过事件:
- mouseover和mouseout会有冒泡效果
- mouseenter和mouseleave没有冒泡效果(推荐使用)
事件委托
事件委托是利用事件流的特征解决一些特定的开发需求
优点:减少注册次数,可以提高程序性能
原理:事件委托其实是利用事件冒泡的特点
给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<p>我不需要变色</p>
</ul>
//点击li标签,当前标签变为红色(p标签不变色)
const ul =document.querySelector('ul');
ul.addEventListener('click',function(e){//传递事件对象
if(e.target.tagName==='LI'){//判断获取到的元素标签类型是否为li标签
e.target.style.color='red';//通过target属性获得,点击对象的信息,并设置颜色
}
})
阻止默认行为
语法:
e.preventDefault()
<form action="https//www.baidu.com">
<input type="submit" value="提交">
</form>
<a href="www.baidu.com">百度</a>
<script>
const form = document.querySelector('form');
form.addEventListener('submit',function(e){
e.preventDefault();
});
const a = document.querySelector('a');
a.addEventListener('click',function(e){
e.preventDefault();//阻止默认行为,点击不会跳转
});
</script>
页面加载事件
加载外部资源(如图片,外联CSS和JavaScript等)加载完毕时触发的事件
事件名:load
监听页面所有资源加载完毕:给window添加load事件
window.addEventListener('load',function(){
})
事件名:DOMContentLoaded
作用:当初始的HTML文档被完全加载和解析完成之后,DOMContentLoaded事件被触发,而无需等待样式表、图片等完全加载
document.addEventListener('DOMContentLoaded',function(){
});
页面滚动事件
滚动条在滚动的时候持续触发的事件
事件名:scroll
监听整个页面的滚动:给window(推荐)或document添加scroll事件
window.addEventListener('scroll',function(){//页面滚动事件
})
也可以给某个元素添加,监听某个元素内部的滚动
页面平滑滚动:给html标签添加以下css样式
html{
scroll-behavior: smooth;
}
获取位置
scrollLeft和scrollTop(属性)
- 获取被卷去的大小
- 获取元素内容往左,往上滚出去看不到的距离
- 这两个值是可读写的
- 在scoll事件里面获取被卷去的距离
window.addEventListener('scroll',function(){
//document.documentElement 获取当前页面的html元素
console.log(document.documentElement.scrollTop);//★打印垂直方向卷去的像素
const n =document.documentElement.scrollTop;
if(n>=100){
元素.style.display='block'
}else{
元素.style.display='none'
}
});
滚动到指定的坐标
语法:元素.scrollTo(x,y)
window.scrollTo(0,1000)
页面尺寸事件
-
会在窗口尺寸改变的时候触发事件:resize
window.addEventListener('resize',function(){ })
-
检测屏幕宽度
获取元素的可见部分宽高(不包含边框,margin,滚动条等)
clientWidth和clientheight
window.addEventListener('resize',function(){ let w = document.documentElement.clientWidth; console.log(w); })
元素的尺寸与位置
获取宽高:
- 获取元素的自身宽高、包含元素自身设置的宽高、padding、border
- offsetWidth和offsetHeigth
- 获取出来的是数值,方便计算
- 注意:获取的是可视宽高,如果盒子是隐藏的,获取的结果是0
获取位置:
- 获取元素距离自己定位父级元素的左、上距离
- offsetLeft和offsetTop注意是只读属性
获取元素大小及相对于视口的位置
element.getBoundingClientRect()//返回当前元素的位置信息对象