1. 滚动事件和加载事件
1. 滚动事件scroll
-
当页面进行滚动时触发的事件
-
很多网页需要检测用户把页面滚动到某个区域后做一些处理, 比如固定导航栏,比如返回顶部
-
监听整个页面滚动给 window 或 document 加
-
监听某个元素的内部滚动直接给某个元素加即可
// 监听整个页面滚动
// 1. 滚动事件 监听整个页面滚动 固定导航/返回顶部
window.addEventListener('scroll', function () {
console.log(1)
})
let num1 = document.querySelector('.box')
num1.addEventListener('scroll', function () {
console.log(2)
})
2. 加载事件load
-
加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
-
有些时候需要等页面资源全部处理完了做一些事情
-
-
注意:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件
监听页面所有资源加载完毕:
// 监听整个页面资源给 window 加
// 2. 加载事件 监听页面资源加载完毕才执行load事件
// 也可以针对别的资源绑定load事件
// 把js写在head上面 导致dom元素找不到 用load事件
let n1 = document.querySelector('.box')
window.addEventListener('load', function () {
console.log(11)
})
3. 加载事件DOMContentLoaded
-
当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表 、图像等完全加载
监听页面DOM加载完毕:
// 给 document 添加 DOMContentLoaded 事件
// 2. 加载事件 等HTML文档加载完后再加载 无需等样式 图片就可以加载
document.addEventListener('DOMContentLoaded', function () {
console.log(3)
})
2. scroll家族
-
我们想要页面滚动一段距离,比如100px,就让某些元素显示隐藏, 就可以使用scroll 来检测页面滚动的距离~
-
获取宽高: 获取元素的内容总宽高(不包含滚动条)返回值不带单位
-
scrollWidth和scrollHeight
获取位置:
-
获取元素内容往左、往上滚出去看不到的距离
-
scrollLeft和scrollTop
-
这两个属性是可以修改的
// 1. scroll家族 (了解)
let num1 = document.querySelector('.box')
// 当前宽度 不包含滚动条
console.log(num1.scrollWidth)
// 内容高度
console.log(num1.scrollHeight)
// 2. 被卷去的头部和左侧
num1.addEventListener('scroll', function () {
console.log(this.scrollTop)
})
开发中,我们经常检测页面滚动的距离,比如页面滚动100像素,就可以显示一个元素,或者固定一个元素
-
document.documentElement HTML 文档返回对象为HTML元素
// 3. 检测页面滚动的距离
window.addEventListener('scroll', function () {
// 返回HTML元素距离
console.log(document.documentElement.scrollTop)
// 可以给值/修改 但不要带单位
document.documentElement.scrollTop = 200
})
-
被卷去的头部或者左侧用那个属性?是否可以读取和修改?
-
可以读取,也可以修改(赋值)
页面滚动显示返回顶部按钮
//需求:当页面滚动500像素,就显示返回顶部按钮,否则隐藏, 同时点击按钮,则返回顶部
//①:用到页面滚动事件
//②:检测页面滚动大于等于100像素,则显示按钮
//③:点击按钮,则让页面的scrollTop 重置为 0
<div class="content"></div>
<div class="backtop">
<img src="./images/close2.png" alt="">
<a href="javascript:;"></a>
</div>
let btn = document.querySelector('.backtop')
// 1. 页面滚动事件
window.addEventListener('scroll', function () {
// 2. 页面检测滚动距离
let num1 = document.documentElement.scrollTop
// 3. 判断显示隐藏
// 如果大于200 就显示 小于隐藏
if (num1 >= 200) {
btn.style.display = 'block'
} else {
btn.style.display = 'none'
}
})
// 4. 点击链接返回顶部
btn.children[1].addEventListener('click', function () {
document.documentElement.scrollTop = 0
})
3. offset家族
-
使用场景: 前面案例滚动多少距离,都是我们自己算的,最好是页面 滚动到某个元素,就可以做某些事
-
简单说,就是通过js的方式,得到元素在页面中的位置 这样我们可以做,页面滚动到这个位置,就可以返回 顶部的小盒子显示…
获取宽高:
-
获取元素的自身宽高、包含元素自身设置的宽高、padding、border, offsetWidth和offsetHeight
// 1. offset家族 宽高 (了解)
let num1 = document.querySelector('.box')
// 盒子大小 = 盒子本身宽高 + padding + border
// 盒子多大 offset就多大
console.log(num1.offsetWidth)
console.log(num1.offsetHeight)
获取位置:
-
获取元素距离自己定位父级元素的左、上距离
-
offsetLeft和offsetTop 注意是只读属性
// 2. 位置以带定位的父级 如果没有就以左上角为准
console.log(num1.offsetTop)
console.log(num1.offsetLeft)
仿京东固定导航栏案例
//当页面滚动到秒杀模块,导航栏自动滑入,否则滑出
//①:用到页面滚动事件
//②:检测页面滚动大于等于 秒杀模块的位置 则滑入,否则滑出
<div class="header">我是顶部导航栏</div>
<div class="content">
<div class="sk">秒杀模块</div>
</div>
<div class="backtop">
<img src="./images/close2.png" alt="">
<a href="javascript:;"></a>
</div>
<script>
let box = document.querySelector('.sk')
let head = document.querySelector('.header')
// 1.页面滚动事件
window.addEventListener('scroll', function () {
// 2.检测页面滚动距离 >= 秒杀模块的offsetTop 则划入
if (document.documentElement.scrollTop >= box.offsetTop) {
// 3.如果大于则显示 小于则-80px
head.style.top = '0px'
} else {
head.style.top = '-80px'
}
})
</script>
电梯导航案例
<!--需求:点击可以页面调到指定效果
①:点击当前 小导航,当前添加active,其余移除active
②:得到对应 内容 的 offsetTop值
③:让页面的 scrollTop 走到 对应 内容 的 offsetTop-->
<div class="aside">
<div class="item active">男装/女装</div>
<div class="item">儿童服装/游乐园</div>
<div class="item">电子产品</div>
<div class="item">电影/美食</div>
</div>
<div class="content">
<div class="neirong content1">男装/女装</div>
<div class="neirong content2">儿童服装/游乐园</div>
<div class="neirong content3">电子产品</div>
<div class="neirong content4">电影/美食</div>
</div>
<script>
let btn = document.querySelectorAll('.item')
let btn1 = document.querySelectorAll('.neirong')
// 1. 点击谁谁添加类
for (let num1 = 0; num1 < btn.length; num1++) {
btn[num1].addEventListener('click', function () {
document.querySelector('.aside .active').classList.remove('active')
this.classList.add('active')
// 2. 右侧内容跟随走动
// 让页面滚动对应offsettop值位置
document.documentElement.scrollTop = btn1[num1].offsetTop
})
}
</script>
4. client家族
-
获取宽高:获取元素的可见部分宽高(不包含边框,滚动条等), clientWidth和clientHeight
-
获取位置: 获取左边框和上边框宽度, clientLeft和clientTop 注意是只读属性
let num1 = document.querySelector('.box')
// 可见区域的宽高 不包含滚动条 边框...
console.log(num1.clientWidth)
console.log(num1.clientHeight)
// 3. client TOP/Left (了解) 就是边框的宽高
console.log(num1.clientTop)
console.log(num1.clientLeft)
会在窗口尺寸改变的时候触发事件:resize
// 2. resize事件 当窗口变化时触发的事件
window.addEventListener('resize', function () {
// 检测屏幕宽度
console.log(document.documentElement.clientWidth)
// 检测页面的宽度不同而改变颜色
let num2 = document.documentElement.clientWidth
if (num2 >= 1000) {
document.body.style.backgroundColor = 'skyblue'
} else if (num2 >= 850) {
document.body.style.backgroundColor = 'pink'
} else {
document.body.style.backgroundColor = 'green'
}
})
5. 三大家族的区别
offset家族
-
获取元素自身大小:包括自身设置的宽高、padding、border
-
获取元素距离定位父级的左和上距离 只读属性
scroll家族
-
获取元素内容的总大小
-
获取元素向左向上滚出去看不见的距离 可读写属性
client家族
-
获取元素可见区域的大小
-
获取元素左、上边框距离 只读属性
6. 轮播图案例
需求①:小图标鼠标经过事件
需求② :大图片跟随变化
需求③:右侧按钮播放效果
需求④:解决一个BUG
需求⑤:左侧按钮播放效果
需求⑥: 因为左侧按钮和右侧按钮里面有大量相同的操作,可以抽取封装一个函数 common
需求⑦:开启定时器需求
需求⑧: 鼠标经过停止定时器 (清除定时器) 鼠标离开开启定时器 (开启定时器)
<div class="main">
<div class="slides">
<ul>
<li class="active"><a href="#"><img src="./images/b_01.jpg" alt="第1张图的描述信息"></a></li>
<li><a href="#"><img src="./images/b_02.jpg" alt="第2张图的描述信息"></a></li>
</ul>
<div class="extra">
<h3>第1张图的描述信息</h3>
<a class="prev" href="javascript:;"></a>
<a class="next" href="javascript:;"></a>
</div>
</div>
<div class="indicator">
<ul>
<li class="active">
<img src="images/s_01.jpg">
<span class="mask"></span>
<span class="border"></span>
</li>
<li>
<img src="images/s_02.jpg">
<span class="mask"></span>
<span class="border"></span>
</li>
</ul>
</div>
</div>
let xl = document.querySelectorAll('.indicator li')
let dl = document.querySelectorAll('.slides ul li')
let text = document.querySelector('.extra h3')
let btn = document.querySelector('.next')
let btn1 = document.querySelector('.prev')
let main = document.querySelector('.main')
for (let num1 = 0; num1 < xl.length; num1++) {
// 1.鼠标经过小图片变高亮
xl[num1].addEventListener('mouseenter', function () {
document.querySelector('.indicator .active').classList.remove('active')
this.classList.add('active')
// 2. 鼠标经过当前小图片后大图片变化
// 利用opacity实现淡入淡出效果
document.querySelector('.slides .active').classList.remove('active')
dl[num1].classList.add('active')
// 3. 鼠标经过图片 文字改变
text.innerHTML = `第${num1 + 1}张图的描述信息`
// 6. 解决Bug 如果鼠标经过后 再次点击播放会乱序
// 让index重新赋值为 当前鼠标经过索引号
index = num1
})
}
// 4. 右侧按钮点击事件
// 全局变化量变量 不断自增 控制器/给左右按钮同时使用
let index = 0
btn.addEventListener('click', function () {
index++ // 变量点击后自增
// 1. 解决点击最后一张后报错 等于10之后index为0
if (index == 10) {
index = 0
}
// 2. // 10 10 余 0
// index = index % 10
fn()
})
// 5.左侧按钮点击事件
btn1.addEventListener('click', function () {
index--
if (index < 0) {
index = 9
}
// 10 + -1 = 9 % 10 余 1
// index = (10 + index) % xl.length
fn()
})
// 6. 因为左右按钮有大量相同代码 可以封装成函数 然后调用
function fn() {
// 选出 index 大/小图片 排它思想
document.querySelector('.indicator .active').classList.remove('active')
xl[index].classList.add('active')
document.querySelector('.slides .active').classList.remove('active')
dl[index].classList.add('active')
text.innerHTML = `第${index + 1}张图的描述信息`
}
// 7. 开启轮播定时器
let timer = setInterval(function () {
// 自动调用右侧按钮点击事件
btn.click()
}, 800)
// 如果不清除 点击哪个就不会停止
// 8.鼠标经过清除定时器
main.addEventListener('mouseenter', function () {
clearInterval(timer)
})
// 9. 鼠标经过开启定时器
main.addEventListener('mouseleave', function () {
// 直接再开启一个定时器 不要重新赋值了
timer = setInterval(function () {
btn.click()
}, 800)
})