电梯导航功能描述
- 当页面滚动指定位置时侧边导航栏出现
- 点击侧边导航栏,页面滚动到指定位置
- 页面滚动到指定位置时,侧边导航栏出现提示
实现效果
电梯导航实现步骤
1. 概念理解
- 理解事件委托和自定义属性的用法
事件委托:利用冒泡的特性:子元素绑定事件触发,父元素事件也触发
自定义属性:用户自行定义的属性,通常以data-开头 - 电梯导航的html框架
<div class="aside">
<div class="item active">男装/女装</div>
<div class="item">儿童服装/游乐园</div>
<div class="item">电子产品</div>
<div class="item">电影/美食</div>
</div>
<div class="box">
<div class="content">
<div class="neirong content1">男装/女装</div>
<div class="neirong content2">儿童服装/游乐园</div>
<div class="neirong content3">电子产品</div>
<div class="neirong content4">电影/美食</div>
</div>
</div>
2. 实现侧边栏出现效果
修改侧边栏left属性,给html绑定页面滚动事件,当html滚动到指定位置时,侧边栏left改变
- 隐藏侧边栏
.aside {
position: fixed;
left: -100%; //隐藏侧边栏
top: 50%;
transform: translateY(-50%);
transition: all 1s;
}
- 给window绑定滚动事件,当页面滚动距离大于指定元素向上的距离,改变aside元素的样式
window.addEventListener('scroll', function (e) {
if (i.scrollTop >= box.offsetTop) { //i为html页面:document.documentElement
aside.style.left = '0'
} else {
aside.style.left = '-100%'
}
for (let j = 0; j < contents.length; j++) {
if (i.scrollTop >= contents[j].offsetTop) {
console.log(1111)
document.querySelector('.aside .active').classList.remove('active')
document.querySelector(`[data-id='${j}']`).classList.add('active')
}
}
})
3. 实现侧边栏点击效果
给侧边栏选项卡的父级元素绑定点击事件,当点击对应的选项卡时,页面的scrollTop等于选项卡的offsetTop
aside.addEventListener('click', function (e) { //父元素绑定点击事件
if (e.target.tagName === 'DIV') { //判断选项卡类型
document.querySelector('.active').classList.remove('active')
e.target.classList.add('active')
i.scrollTop = contents[e.target.dataset.id].offsetTop
}
})
4.实现侧边栏对应位置高亮效果
遍历所有内容元素,当页面的scrollTop等于某一内容(自定义属性所对应)的offsetTop,使用排它利己思想给对应的选项卡active类名
- 定义自定义属性
<div class="aside">
<div data-id='0' class="item active">男装/女装</div> //自定义属性通常以data-开头
<div data-id='1' class="item">儿童服装/游乐园</div>
<div data-id='2' class="item">电子产品</div>
<div data-id='3' class="item">电影/美食</div>
</div>
- 遍历所有元素,给自定义属性所对应的元素添加active类名
for (let j = 0; j < contents.length; j++) { //遍历所有内容元素
if (i.scrollTop >= contents[j].offsetTop) {
document.querySelector('.aside .active').classList.remove('active')
document.querySelector(`[data-id='${j}']`).classList.add('active') //查询带有指定属性名和属性值的元素
}
}
排它:查找该位置上所有.active类名的元素,清除类名。如有多个可用querySelectorAll获取,并用循环遍历清除
document.querySelector('.aside .active').classList.remove('active')
利己:让所对应的选项卡加上active类名
document.querySelector(`[data-id='${j}']`).classList.add('active')
完整实例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
height: 3000px;
}
.aside {
position: fixed;
left: -100%;
top: 50%;
transform: translateY(-50%);
transition: all 1s;
}
.item {
height: 40px;
line-height: 40px;
text-align: center;
padding: 0 10px;
cursor: pointer;
}
.active {
background-color: red;
color: #fff;
}
.content {
width: 660px;
margin: 0 auto;
}
.neirong {
height: 300px;
margin-bottom: 20px;
color: #fff;
}
.content1 {
background-color: red;
}
.content2 {
background-color: blue;
}
.content3 {
background-color: orange;
}
.content4 {
background-color: yellowgreen;
}
.box {
width: 100%;
height: 100%;
background-color: #c1c1c1;
padding: 240px 0px;
margin: 300px 0px;
}
</style>
</head>
<body>
<div class="aside">
<div data-id='0' class="item active">男装/女装</div>
<div data-id='1' class="item">儿童服装/游乐园</div>
<div data-id='2' class="item">电子产品</div>
<div data-id='3' class="item">电影/美食</div>
</div>
<div class="box">
<div class="content">
<div class="neirong content1">男装/女装</div>
<div class="neirong content2">儿童服装/游乐园</div>
<div class="neirong content3">电子产品</div>
<div class="neirong content4">电影/美食</div>
</div>
</div>
<script>
const aside = document.querySelector('.aside')
const box = document.querySelector('.box')
const i = document.documentElement
const contents = document.querySelectorAll('.content div')
// 指定位置出现侧边栏
window.addEventListener('scroll', function (e) {
if (i.scrollTop >= box.offsetTop) {
aside.style.left = '0'
} else {
aside.style.left = '-100%'
}
for (let j = 0; j < contents.length; j++) {
if (i.scrollTop >= contents[j].offsetTop) {
document.querySelector('.aside .active').classList.remove('active')
document.querySelector(`[data-id='${j}']`).classList.add('active')
}
}
})
// 侧边栏点击事件
aside.addEventListener('click', function (e) {
if (e.target.tagName === 'DIV') {
document.querySelector('.active').classList.remove('active')
e.target.classList.add('active')
i.scrollTop = contents[e.target.dataset.id].offsetTop
}
})
</script>
</body>
</html>