APIs学习记录-小兔鲜电梯导航案例(页面滚动事件,元素尺寸和位置)
一. 知识储备
1)页面滚动事件(scroll)
页面滚动时触发的事件
参数:scrollTop
和scrollLeft
常用scrollTop
来监测或设置元素的位置
2)元素尺寸和位置
获取元素尺寸
clientWidth
与 clientHeight
盒子原本宽高+padding
offsetWidth
与 offsetHeight
盒子原本宽高+padding+border
获取元素位置
offsetTop
与offsetLeft
到上一个具有定位的父元素的位置顶部,左侧
二.小兔鲜电梯导航案例
1)案例需求
- 页面滚动到对应位置,电梯导航显示;点击返回页面顶部
- 点击电梯导航小模块,页面会跳到对应大模块的位置
- 页面大模块滚动到对应位置,电梯导航对应小模块发生变化
2)关键代码
第一大模块,页面滑动可以显示和隐藏
(function () {
//获取位置目标元素和电梯导航元素
const entry = document.querySelector('.xtx_entry')
const elevator = document.querySelector('.xtx-elevator')
window.addEventListener('scroll', function () {
const n = document.documentElement.scrollTop
//判断条件:scrollTop是否大于目标元素的offsetTop
elevator.style.opacity = n >= entry.offsetTop ? 1 : 0
})
// 点击返回页面顶部
const backTop = document.querySelector('#backTop')
backTop.addEventListener('click', function () {
document.documentElement.scrollTop = 0
})
})();
第二大模块,点击电梯导航小模块,小模块添加active类高亮,页面滚动到大模块对应位置
(function () {
// 获取电梯导航元素
const list = document.querySelector('.xtx-elevator-list')
list.addEventListener('click', function (e) {
if (e.target.tagName === 'A') {
// 排他思想
// 先移除原来的类active
// 先获取这个active的对象
const old = document.querySelector('.xtx-elevator-list .active')
// 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错
if (old) old.classList.remove('active')
e.target.classList.add('active')
// 根据小盒子的自定义属性值 去选择 对应的大盒子
// 获得对应大盒子的 offsetTop
const top = document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop
// 让页面滚动到对应的位置
document.documentElement.scrollTop = top
}
})
第三大模块,页面滚动,根据大盒子的位置给小盒子添加active类高亮
window.addEventListener('scroll', function () {
const old = document.querySelector('.xtx-elevator-list .active')
if (old) old.classList.remove('active') // 类似之前
// 判断页面当前滑动的位置,选择小盒子
// 获取4个大盒子
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 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')
}
})
})();