一、知识点
1.事件流两个阶段:事件捕获阶段、事件冒泡阶段
2.阻止冒泡
//阻止冒泡
const btn=document.querySelector('button')
btn.addEventListener('click',function(e){
e.stopPropagation()
})
3.事件解绑
//事件解绑
//如果是匿名函数,无法被解绑
function fn(e){
alert('点击了')
}
btn.addEventListener('click',fn)
btn.removeEventListener('click',fn)
4.事件委托:利用事件冒泡的特点
//给父元素注册事件,当触发子元素时,会冒泡到父元素上,从而触发父元素的事件
const ul=document.querySelector('ul')
//事件委托给父级
ul.addEventListener('click',function(e){
//需求:只点击li才变红色
if (e.target.tagName === 'LI'){
e.target.style.color='red'
}
})
5.阻止元素默认行为:比如阻止链接的跳转、表单域跳转
const form=document.querySelector('form')
form.addEventListener('submit',function(e){
e.preventDefault()
})
const a=document.querySelector('a')
a.addEventListener('click',function(e){
e.preventDefault()
})
6.其它事件:页面加载事件、页面滚动事件、页面尺寸事件
//页面加载事件
//给window加,需等待页面资源全部加载完毕
window.addEventListener('load',function(){})
//给document加,无需等待样式表、图像等完全加载
document.addEventListener('DOMContentLoaded',function(){})
//图片加载
img.addEventListener('load',function(){})
//页面滚动事件
document.documentElement.scrollTop = 800
window.addEventListener('scroll',function(){
//获取html元素的写法
//页面头部被卷去了多少,得到数字型,没有单位,可读写
console.log(document.documentElement.scrollTop)
})
//页面尺寸事件
//浏览器窗口大小发生变化时触发的事件
const div=document.querySelector('div')
window.addEventListener('resize',function(){})
//获取元素可见部分的宽高(包括padding,不包含border)
console.log(div.clientWidth);
//获取元素自身宽高(包括padding,border,若盒子是隐藏的,获取结果是0)
console.log(div.offsetWidth);
//检测盒子位置,最近一级带有定位的祖先元素
console.log(div.offsetLeft);
console.log(div.offsetTop);
二、综合案例
1.全选反选
<script>
const checkAll=document.querySelector('#checkAll')
const cks=document.querySelectorAll('.ck')
//大复选框
checkAll.addEventListener('click',function(){
for (let i = 0; i < cks.length; i++){
cks[i].checked=this.checked
}
})
//小复选框
//给所有小复选框添加点击事件
for (let i = 0; i < cks.length; i++){
cks[i].addEventListener('click',function(){
//判断选中的小复选框个数是否等于总个数
checkAll.checked=document.querySelectorAll('.ck:checked').length === cks.length
})
}
</script>
2.仿新浪固定头部
<script>
const sk=document.querySelector('.sk')
const header=document.querySelector('.header')
//页面滚动事件
window.addEventListener('scroll',function(){
//当页面滚动到秒杀模块,改变头部的top值
//页面scrollTop >= 秒杀模块.offsetTop
const n = document.documentElement.scrollTop
if (n >= sk.offsetTop) {
header.style.top = 0
}
else {
header.style.top = '-80px'
}
// header.style.top = n >= sk.offsetTop ? 0 : '-80px'
})
</script>
3.tab栏切换(事件委托版)
<script>
//获取父元素 ul
const ul=document.querySelector('.tab-nav ul')
// //获取5个item
// const items=document.querySelectorAll('.tab-content .item')
//添加事件
ul.addEventListener('click',function(e){
//只有点击了 a ,才会进行添加类和删除类操作
if (e.target.tagName === 'A'){
//删除类
document.querySelector('.tab-nav .active').classList.remove('active')
//添加类,当前元素是 e.target
//this指向ul,不能用this
e.target.classList.add('active')
//拿到自定义属性作为 i
const i = parseInt(e.target.dataset.id)//+e.target.dataset.id 转数字型
//排他思想
document.querySelector('.tab-content .active').classList.remove('active')
document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
//5选1 items[i].classList.add('active')
}
})
</script>
4.电梯导航
<script>
//第一模块:页面滑动可以显示和隐藏
(function(){
//获取元素
const elevator = document.querySelector('.xtx-elevator')
const entry=document.querySelector('.xtx_entry')
//当页面滚动大于300像素,就显示电梯导航
//给页面添加滚动事件
window.addEventListener('scroll',function(){
const n = document.documentElement.scrollTop
elevator.style.opacity = n >= entry.offsetTop ? 1 : 0
})
//点击返回页面顶部
const backTop=document.querySelector('#backTop')
backTop.addEventListener('click',function(){
document.documentElement.scrollTop=0
// window.scrollTo(0,0)
})
})();
//第二第三模块
(function(){
//1.点击页面可以滑动
//获取元素
const list=document.querySelector('.xtx-elevator-list')
list.addEventListener('click',function(e){
if(e.target.tagName === 'A' && e.target.dataset.name){
//先获取这个类名
const old = document.querySelector('.xtx-elevator-list .active')
//判断
if (old) old.classList.remove('active')
//当前点击元素添加active类名
e.target.classList.add('active')
//根据小盒子的自定义属性值去选择对应的大盒子,获得对应大盒子的scrollTop值
const top = document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop
//让页面滚动到对应的位置
document.documentElement.scrollTop=top
}
})
//2.页面滚动,可以根据大盒子选小盒子,添加active类
window.addEventListener('scroll',function(){
//获取元素
const news = document.querySelector('.xtx_goods_new')
const popular = document.querySelector('.xtx_goods_popular')
const brand = document.querySelector('.xtx_goods_brand')
const topic = document.querySelector('.xtx_goods_topic')
//先获取这个类名
const old = document.querySelector('.xtx-elevator-list .active')
//判断
if (old) old.classList.remove('active')
const n = document.documentElement.scrollTop
if (n >= news.offsetTop && n< popular.offsetTop){
//选择第一个小盒子 属性选择器
document.querySelector('[data-name="new"]').classList.add('active')
}
else if (n >= popular.offsetTop && n< brand.offsetTop) {
document.querySelector('[data-name="popular"]').classList.add('active')
}
else if (n >= brand.offsetTop && n< topic.offsetTop) {
document.querySelector('[data-name="brand"]').classList.add('active')
}
else if (n >= topic.offsetTop ) {
document.querySelector('[data-name="topic"]').classList.add('active')
}
})
})();
</script>