一:事件流
事件流指事件完整执行过程中流动的路径
相同的事件才会有事件流
1,捕获阶段 (由大到小)
L0 没有事件捕获,只有事件冒泡
事件捕获:从DOM根元素开始去执行对应的事件(从外到里)
需要写相应代码才能看到结果
第三个参数传入为 true时, 代表捕获阶段触发 (L2)
如果不传,或传入为false时,为事件冒泡
2,冒泡阶段 (由小到大)
实际开发中以事件冒泡为主
事件冒泡:当一个元素事件触发时,同样的事件将会在该元素的所有祖先元素中依次被触发
2.1阻止冒泡
阻止事件流(流动)传播,保证事件在当前元素执行,从而不会影响其它的祖先元素
前提:阻止事件冒泡需要拿到事件对象
语法:
事件对象.stopPropagation()
erzi.addEventListener('click',function(e){
e.stopPropagation()
alert('我是儿子')
})
2.2阻止默认行为
事件对象.preventDefault
应用场景:比如阻止表单提交,链接跳转
const a = document.querySelector('a')
a.addEventListener('click',function(e){
e.preventDefault()
})
2.3解绑事件
// 事件解绑 L0版本
btn1.onclick = function(){
console.log('绑定事件')
}
// 解绑 给btn2注册绑定事件 将btn1解绑
btn2.onclick = function(){
btn1.onclick = null
}
// L2 版本 匿名函数无法做事件解绑
function fn () {
console.log('绑定事件');
}
//绑定
btn1.addEventListener('click',fn)
//解绑 给btn2注册绑定事件 将btn1解绑
btn2.addEventListener('click',function(){
btn1.removeEventListener('click',fn)
})
二:事件委托
利用事件冒泡的特点,给父元素注册事件,当我们触发子元素时,会冒泡到父元素身上,从而触发父元素的事件
优点:减少次数,提高性能
const ul = document.querySelector('ul')
//委托给Ul
ul.addEventListener('click',function(e){
//事件对象 .target.tagName 才能获取正在被触发的元素
if (e.target.tagName === 'LI') {
e.target.style.color = 'red'
}
})
<!-- 需求 点击每个 li 让当前的li变红色 -->
<ul>
<li>第一个</li>
<li>第二个</li>
<li>第三个</li>
<li>第四个</li>
<li>第五个</li>
</ul>
三 :其它事件
页面加载事件
加载外部资源(如图片,外联css和js等)加载完毕时触发的事件
// 等待页面所有资源加载完毕 再去执行回调函数
// load 事件
window.addEventListener('load',function(){
//获取
const btn = document.querySelector('button')
//点击事件
btn.addEventListener('click',function(){
console.log('111');
})
})
// DOMContentLoaded 事件 无需等待样式,图片等完全加载 给document添加
document.addEventListener('DOMContentLoaded',function(){
const btn = document.querySelector('button')
//点击事件
btn.addEventListener('click',function(){
console.log('111');
})
})
元素滚动事件
滚动条在滚动时持续触发的事件
事件名 :scroll
scroll事件可以被两个对象注册
document(文档)对象注册
window 对象注册
//document(文档)对象注册
document.addEventListener('scroll',function(){
console.log('滚起来了');
})
//1,监听整个页面滚动
window.addEventListener('scroll',function(){
console.log('滚起来了');
})
// 2,监听某个元素内部的滚动
//直接给元素添加
const box = document.querySelector('.box')
box.addEventListener('scroll',function(){
console.log('内部滚动');
//scrollTop 被卷的头部
console.log(box.scrollTop);
})
-scrollTop.html是可读写的小细节
//滚动事件
//scrollTop 可读写
document.documentElement.scrollTop = 100
window.addEventListener('scroll',function(){
//必须写到滚动事件里面 获取最新数据
const n = document.documentElement.scrollTop
// 得到的是数字型 不带单位
console.log(n);
})
页面尺寸事件
- 窗口尺寸发生改变的时候触发的事件
resize
//resize 浏览器窗口大小发生变化时触发的事件
window.addEventListener('resize',function(){
console.log(1);
})
- 检测屏幕宽度
获取元素可见部分宽高(不包含边框,margin,滚动条等)
clientWidth 和 clientHeight
//clientWidth 和 clientHeight 获取元素可见部分宽高(不包含边框,margin,滚动条等)
const div = document.querySelector('div')
console.log(div.clientWidth);
console.log(div.clientHeight);
四:元素尺寸于位置-尺寸
获取宽高:
- 获取元素 自身宽高,包含元素自身设置的宽高 (内容 + padding + border)
- offserWitch 和 offsetHeight
- 获取出来的是数值,方便计算
- 注意:获取的是可视宽高,如果盒子是隐藏的,获取的结果是0
获取位子:
- 获取元素距离自己定位父级元素的左 ,上距离
const div = document.querySelector('div')
const p = document.querySelector('p')
//检测盒子的位置
// console.log(div.offsetLeft);
//offsetLeft 受父亲的影响 父级如果有定位 以父亲位置 父亲 没有定位找最近带有定位的元素
console.log(p.offsetLeft);
offsetLeft 和 offsetTop得到的位置以谁为准?
带有定位的父级
如果都没有则以 文档左上角 为准
- offsetLeft 和 offsetTop 注意只读属性
\