1.事件流
1.1事件流与两个阶段 (捕获事件和事件冒泡)
1.2.事件捕获(true)
目标 简单了解事件捕获执行过程
概念 从DOM的根元素开始执行对应的事件
事件类型不一样的时候 也不会触发
L0事件就是 onclick事件(老版本的写法) L0时间没有捕获
案例 1
<script>
const fa = document.querySelector('.father')
const son = document.querySelector('.son')
// 山东 济南 蓝翔 目标(pink老师) 捕获阶段 ,true 开启捕获!
// 捕获 从上往下 执行
// 蓝翔 济南 山东 冒泡阶段
document.addEventListener('click', function () {
alert('我是爷爷')
},false)
fa.addEventListener('click', function () {
alert('我是爸爸')
})
son.addEventListener('click', function (e) {
alert('我是儿子')
// 组织流动传播 事件对象.stopPropagation()
// e.stopPropagation()
})
</script>
演示效果:
1.3事件冒泡(false)
当一个元素的事件被触发的时候,其祖上同名元素 都会被依次触发。
L2事件 监听第三个元素 就是false。L0默认也是false.所以事件冒泡是默认存在的。所以false可以省略。注意捕获 L0 是没有的
也就是说冒泡是默认存在的。
1.4阻止冒泡
事件对象.stopProgation() 方法
可以阻止除了调用了阻止冒泡方法的函数 进行冒泡
阻止默认行为 也就是阻止事件的类型
事件对象.preventDefault 阻止调用自身默认行为,比如跳转其他网址
案例 1 阻止事件
案例2 阻止默认行为
<!--注意botton 在form表单中 没有type属性为submit 也会提交 -->
1.5解绑事件
on事件解绑 直接使用 null覆盖就可以实现事件的解绑
存放位置 会使解绑事件有区别
L2事件解绑 但是匿名函数不支持解绑
鼠标经过事件的区别
两种 注册事件区别
2.事件委托
综合案例 tap栏改造
1.案例中需要使用自定义属性 data- 通过事件对象.target.dataset.属性名 来获取索引
事件对象.target 可以获取目标,也就是触发事件的元素
<div class="tab">
<div class="tab-nav">
<h3>每日特价</h3>
<ul>
<li><a class="active" href="javascript:;" data-id="0">精选</a></li>
<li><a href="javascript:;" data-id="1">美食</a></li>
<li><a href="javascript:;" data-id="2">百货</a></li>
<li><a href="javascript:;" data-id="3">个护</a></li>
<li><a href="javascript:;" data-id="4">预告</a></li>
</ul>
</div>
<div class="tab-content">
<div class="item active"><img src="./images/tab00.png" alt="" /></div>
<div class="item"><img src="./images/tab01.png" alt="" /></div>
<div class="item"><img src="./images/tab02.png" alt="" /></div>
<div class="item"><img src="./images/tab03.png" alt="" /></div>
<div class="item"><img src="./images/tab04.png" alt="" /></div>
</div>
</div>
<script>
const ul = document.querySelector('.tab-nav ul')
const items = document.querySelectorAll('.tab-content .item')
ul.addEventListener('click',function(e){
if(e.target.tagName == 'A'){
document.querySelector('.tab-nav .active').classList.remove('active')
e.target.classList.add('active')
// console.log(e.target.dataset.id) 打印自定义对象索引
document.querySelector('.tab-content .active').classList.remove('active')
const id = e.target.dataset.id;
console.log(e.target.dataset.id);
items[id].classList.add('active');
}
})
// // 采取事件委托的形式 tab栏切换
// // 1. 获取 ul 父元素 因为 ul只有一个
// const ul = document.querySelector('.tab-nav ul')
// // 获取 5个 item
// const items = document.querySelectorAll('.tab-content .item')
// // 2. 添加事件
// ul.addEventListener('click', function (e) {
// // console.log(e.target) // e.target是我们点击的对象
// // 我们只有点击了 a 才会 进行 添加类和删除类操作
// // console.log(e.target.tagName) // e.target.tagName 点击那个对象的 标签名
// if (e.target.tagName === 'A') {
// // console.log('我选的是a')
// // 排他思想 ,先移除原来的active
// document.querySelector('.tab-nav .active').classList.remove('active')
// //当前元素添加 active 是 e.target
// // this 指向ul 不能用this
// e.target.classList.add('active')
// // 下面大盒子模块
// // console.log(e.target.dataset.id)
// const i = +e.target.dataset.id
// // 排他思想 ,先移除原来的active
// document.querySelector('.tab-content .active').classList.remove('active')
// // 对应的大盒子 添加 active
// // document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
// items[i].classList.add('active')
// }
// })
</script>
</body>
3.其他事件
3.1页面加载事件
加载外部资源(外链的CSS 图片JS等),加载完毕时触发的资源
有时候需要等页面资源全部处理完了做一些事情
老代码喜欢吧script写在head中,这个时候直接找Dom元素找不到
事件名 load 通常使用window.
注意 不止能等待页面,也可以等待图片等资源
有弊端
DOMContentLoaded 事件 只需要网页结构标签加载完了 就可以使用 无需等待图像等
通常使用document.
3.2元素滚动事件
触发条件 :滚动条在滚动的时候触发的
例子:很得多网页 导航栏在滚动到某个区域的时候 会改成固定定位,还会产生一个返回顶部
scroll 事件 也可以操作 页面内部元素的 滚动
<div>
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
我里面有很多很多的文字
</div>
<script>
const div = document.querySelector('div')
// 页面滚动事件
window.addEventListener('scroll', function () {
// console.log('我滚了')
// 我想知道页面到底滚动了多少像素, 被卷去了多少 scrollTop 滚动的是html 整体
// 获取html元素写法
// document.documentElement
console.log(document.documentElement.scrollTop)
//scrollTop 被卷去的头部 滚动条距离顶部的位置
const n = document.documentElement.scrollTop
if (n >= 300) {
div.style.display = 'block' //修改div盒子属性为显示 超过则隐藏
} else {
div.style.display = 'none'
}
})
// 测试里面元素子盒子的滚动
// const div = document.querySelector('div')
// div.addEventListener('scroll', function () {
// // console.log(111)
// // scrollTop 被卷去的头部
// console.log(div.scrollTop) 可以直接获取到被卷去的
// })
</script>
综合案例-小兔儿鲜 仅展示部分代码
<script>
const elevator = document.querySelector('.xtx-elevator')
window.addEventListener('scroll',function(){
// 获取被卷去了 多少
// console.log(document.documentElement.scrollTop)
const n= document.documentElement.scrollTop;
// n >=300 ? elevator.style.opacity = 1 : elevator.style.opacity = 0;
elevator.style.opacity = n >=300 ? 1:0;
})
const backTop = document.querySelector('#backTop');
backTop.addEventListener('click',function(){
//利用 scrollTop 可以读写的特性 赋值0 给她
// document.documentElement.scrollTop=0; 方法1
window.scrollTo(0,0); //方法2 第一个0代表X轴 第2个0代表Y轴
})
</script>
3.3页面尺寸事件
resize属性 当浏览器窗口大小发生改变的时候触发的事件
<script>
const div = document.querySelector('div')
console.log(div.clientWidth)
// resize 浏览器窗口大小发生变化的时候触发的事件
window.addEventListener('resize', function () {
console.log(1)
})
</script>
也可以用来检测 屏幕宽度
也可以获取元素宽高
屏幕的尺寸是物理尺寸 根据屏幕变化的是逻辑尺寸
通常用来进行媒体查询的适配 类似案例 flexible.js 这个整体函数是一个立即执行函数
4.元素尺寸 位于位置
通过JS方式 得到元素在页面中的位置! 使用场景 在滚动到某个位置产生的导航栏
offsetleft和top 如果有定位的父级元素 则以父级为基准。就是 他距离附近的距离
如果没则 已 文档左上角为准