滚动事件和加载事件
滚动事件:
当页面进行滚动时触发的事件
事件名:scroll
监听整个页面滚动
语法:
document.addEventListener('scroll', function () {
console.log('滚动了')
})
加载事件:
加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
为什么要学?
Ø 有些时候需要等页面资源全部处理完了做一些事情
Ø 老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到
事件名:load
监听页面所有资源加载完毕:
给 window 添加 load 事件:
window.addEventListener('load', function () {
// 把代码写在load的事件处理函数中
let div = document.querySelector('div')
div.addEventListener('click', function () {
alert('嘻嘻')
})
})
注意:不仅可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件
1.2 加载事件:
当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、 图像等完全加载
事件名:DOMContentLoaded
监听页面DOM加载完毕: Ø 给 document 添加 DOMContentLoaded 事件
document.addEventListener('DOMContentLoaded', function () {
console.log('测试')
// 把代码写在DOMContentLoaded的事件处理函数中
let div = document.querySelector('div')
div.addEventListener('click', function () {
alert('嘻嘻')
})
})
元素大小和位置
scroll家族
获取宽高:
获取元素的内容总宽高(不包含滚动条)返回值不带单位
scrollWidth
scrollHeight
只读属性,不能修改
获取位置:
获取元素内容往左、往上滚出去看不到的距离
scrollLeft
scrollTop
这两个属性是可以修改的t
获取页面的滚动卷曲距离: document.documentElement.scrollTop
案例:页面滚动显示返回顶部按钮
// 获取元素
let backtop = document.querySelector('.backtop')
// 需求:
// 1. 滚动的时候控制返回顶部的按钮显示还是隐藏
// 1.1 当页面滚动卷曲的距离 超过了 500, 就显示,否则隐藏
// 1.2 要监听页面滚动事件 给页面注册scroll滚动事件
// 2. 点击按钮,实现返回顶部
// 需求1
window.addEventListener('scroll', function () {
// 来页面滚动卷曲的距离
let y = document.documentElement.scrollTop
// console.log(y)
// 判断是否有超过600
if (y >= 600) {
backtop.style.display = 'block'
} else {
backtop.style.display = 'none'
}
})
// 需求2:
backtop.addEventListener('click', function () {
// 返回顶部
document.documentElement.scrollTop = 0
})
offset家族
获取宽高:
offsetWidth和offsetHeight
获取元素的真实宽高、包含元素自身设置的宽高、padding、border
获取位置:
offsetLeft和offsetTop
获取元素距离自己定位父级元素的左、上距离
注意:都是只读属性
案例:仿京东固定导航栏案例
let sk = document.querySelector('.sk')
let header = document.querySelector('.header')
// 需求:当页面滚动距离超过秒杀模块的时候,显示header(top为0) 否则隐藏(top为-80px)
// 分析:
// 1. 给window注册scroll滚动事件
// 2. 获取页面滚动距离 scrollTop
// 3. scrollTop 和 秒杀模块到页面顶部的距离 offsetTop
// 3.1 scrollTop >= sk.offsetTop 显示header
// 3.2 否则隐藏(top为-80px)
// 1.
window.addEventListener('scroll', function () {
// 2
let y = document.documentElement.scrollTop
console.log(y, sk.offsetTop)
// 3.
if (y >= sk.offsetTop) {
// 注意:style别落下
// 0的时候,单位px可以不写
header.style.top = 0
} else {
header.style.top = '-80px'
}
})
案例:电梯导航案例
// 导航
let items = document.querySelectorAll('.item')
// 内容
let neirongs = document.querySelectorAll('.neirong')
// 需求: 点击导航的时候
// 1. 当前点击的导航高亮,其他导航不高亮 ==> 排他效果 (升级效果)
// 2. 页面滚动到对应的位置上 ==> 该代码写在 点击导航的事件处理函数里面
// 给所有导航注册click ==> 别落下for循环,items 是伪数组
for (let i = 0; i < items.length; i++) {
// console.log(items[i])
items[i].addEventListener('click', function () {
// 需求1: 排他
// 1. 先获取到高亮的元素,将其高亮类名active移出掉
document.querySelector('.active').classList.remove('active')
// 2. 点击的导航添加高亮类名active
this.classList.add('active')
// 需求2. 页面滚动到对应的位置上
document.documentElement.scrollTop = neirongs[i].offsetTop
})
}
client家族
获取宽高:
clientWidth和clientHeight
获取元素的可见部分宽高(不包含边框,滚动条等)
获取位置:
clientLeft和clientTop
获取左边框和上边框宽度
注意:都是只读属性
会在窗口尺寸改变的时候触发事件: resize,用于获取页面可视区大小
window.addEventListener('resize', function () {
console.log(document.documentElement.clientWidth, document.documentElement.clientHeight)
})
综合案例:轮播图案例
// 轮播图开始啦
// 需求①:小图标鼠标经过事件
// 鼠标经过小图片,当前高亮,其余兄弟变淡 添加类
let lis = document.querySelectorAll('.indicator li')
let piclis = document.querySelectorAll('.slides ul li')
let text = document.querySelector('.extra h3')
let next = document.querySelector('.next')
let prev = document.querySelector('.prev')
let main = document.querySelector('.main')
// 给多个小li绑定事件
for (let i = 0; i < lis.length; i++) {
lis[i].addEventListener('mouseenter', function () {
// 选出唯一的那个active ,删除类
document.querySelector('.indicator .active').classList.remove('active')
// 鼠标经过谁,谁加上active 这个类
this.classList.add('active')
// 需求② :大图片跟随变化 一定要放到鼠标经过事件里面
// 对应的大图片跟着显示,如果想要过渡效果,可以使用opacity效果,可以利用CSS淡入 淡出的效果,还是添加类
// 选出唯一的那个active ,删除类
document.querySelector('.slides ul .active').classList.remove('active')
// 对应序号的那个 li,谁加上active 这个类
piclis[i].classList.add('active')
text.innerHTML = `第${i + 1}张图的描述信息`
// 需求④:解决一个BUG
// 点击右侧按钮可以实现播放下一张,但是鼠标经过前面的,播放就会乱序
// 解决方案: 让变化量 index 重新赋值为 当前鼠标经过的索引号
// 鼠标经过了那个小li 他的索引号就是 i
// 右侧按钮是通过 index 来了控制播放的
index = i
})
}
// 需求③:右侧按钮播放效果
// 点击右侧按钮,可以自动播放下一张图片
// 需要一个变化量 index 不断自增
// 然后播放下一张图片
// 如果到了最后一张,必须要还原为第1张图片
// 教你一招: 索引号 = 索引号 % 数组长度 (放到播放前面)
let index = 0 // 全局变量 信号量 控制器 为了给 右侧按钮和左侧按钮同时使用
next.addEventListener('click', function () {
index++
// 选出 index 小图片 做操作
// console.log(index)
// if (index === lis.length) {
// index = 0
// }
index = index % lis.length
common()
})
// 需求⑤:左侧按钮播放效果
// 点击左侧按钮,可以自动播放上一张图片
// 需要一个变化量 index 不断自减
// 然后播放上一张图片
// 如果到了第一张,必须要从最后一张播放
// 教你一招: 索引号 = (数组长度 + 索引号) % 数组长度
prev.addEventListener('click', function () {
index--
// 选出 index 小图片 做操作
// console.log(index)
if (index < 0) {
index = lis.length - 1
}
// index = (lis.length + index) % lis.length
common()
})
// 需求⑥:
// 因为左侧按钮和右侧按钮里面有大量相同的操作,可以抽取封装一个函数 common
function common() {
document.querySelector('.indicator .active').classList.remove('active')
lis[index].classList.add('active')
// 选出 index 大图片 做操作
document.querySelector('.slides ul .active').classList.remove('active')
piclis[index].classList.add('active')
text.innerHTML = `第${index + 1}张图的描述信息`
}
// 需求⑦:开启定时器
// 其实定时器自动播放,就相当于点击了右侧按钮,此时只需要, next.click()
let timer = setInterval(function () {
// 自动调用右侧按钮的点击事件
next.click()
}, 1000)
// 需求⑧:
// 鼠标经过停止定时器 (清除定时器)
main.addEventListener('mouseenter', function () {
clearInterval(timer)
})
// 鼠标离开开启定时器 (开启定时器)
main.addEventListener('mouseleave', function () {
timer = setInterval(function () {
// 自动调用右侧按钮的点击事件
next.click()
}, 1000)
})