【JavaScript】二十、电梯导航栏的实现
文章目录
- 1、案例:电梯导航
- 1.1 需求分析与实现
- 1.2 关键思路梳理
- 2、属性选择器补充
1、案例:电梯导航
1.1 需求分析与实现
需求:点击不同的模块,页面可以自动跳转不同的位置
模块分析:
- 页面滚动到对应位置,导航显示,否则隐藏模块
- 点击导航对应小模块,页面 会跳到对应大模块位置
- 页面滚动到对应位置,电梯导航对应模块自动发生变化
//.....html见文章关联压缩包
</div>
</div>
</div>
<!-- 电梯 -->
<div class="xtx-elevator">
<ul class="xtx-elevator-list">
<li><a href="javascript:;" data-name="new">新鲜好物</a></li>
<li><a href="javascript:;" data-name="popular">人气推荐</a></li>
<li><a href="javascript:;" data-name="brand">热门品牌</a></li>
<li><a href="javascript:;" data-name="topic">最新专题</a></li>
<li><a href="javascript:;" id="backTop"><i class="sprites"></i>顶部</a></li>
</ul>
</div>
<script>
// 每做完一个功能,用立即执行函数封装下,防止变量污染
// 需求1、实现页面滚动到对应的位置,电梯导航显示,否则隐藏
(function () {
const elevator = document.querySelector('.xtx-elevator')
// 大盒子2
const entry = document.querySelector('.xtx_entry')
window.addEventListener('scroll', function () {
const n = document.documentElement.scrollTop
if (n >= entry.offsetTop) {
elevator.style.opacity = 1 // opacity即淡入淡出,温柔版的display
} else {
elevator.style.opacity = 0
}
// elevator.style.opacity = n >= 300 ? 1 : 0
})
})();
// 需求2、实现点击⬆️,返回顶部
(function () {
const backTop = document.querySelector('#backTop')
backTop.addEventListener('click', function () {
//document.documentElement.scrollTop = 0
window.scrollTo(0, 0)
})
})();
// 需求3、实现点击电梯导航每一楼,跳转到对应的位置并且电梯导航对应楼层高亮
(function () {
const list = document.querySelector('.xtx-elevator-list')
// 事件委托,不给每一个li绑定事件,给li的父元素ul绑定
list.addEventListener('click', function (e) {
// 导航栏的一楼 返回顶部,不参与这个需求,自己有返回顶部功能
if (e.target.tagName === 'A' && e.target.dataset.name) {
const old = document.querySelector('.xtx-elevator-list .active')
// 刚开始,没有人高亮选中,if (null)就是false
if (old) {
old.classList.remove('active')
}
// 被点击的当前楼层高亮
e.target.classList.add('active')
// 实现点击电梯对应楼层,跳转对应位置,其实就是把html滚动的scrollTop改成对应盒子的offsetTop
const className = e.target.dataset.name
// 选出对应的大盒子
const bigDiv = document.querySelector(`.xtx_goods_${className}`)
// 让页面滚动
document.documentElement.scrollTop = bigDiv.offsetTop
}
})
// 需求4、实现页面滚动到对应的位置,对应的电梯导航那一项就高亮(根据大盒子选择小盒子)
window.addEventListener('scroll', function () {
// 先移除已有的高亮
const old = document.querySelector('.xtx-elevator-list .active')
// 刚开始,没有人高亮选中,if (null)就是false
if (old) {
old.classList.remove('active')
}
// 当页面的scrollTop大于等于div大盒子1的offsetTop,并且小于等于div大盒子2的offsetTop,那就是滑动到对应的div1了
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 scrollTop = document.documentElement.scrollTop
if (scrollTop >= news.offsetTop && scrollTop < popular.offsetTop) {
// 属性选择器选择电梯的对应的那一楼
document.querySelector('[data-name=new]').classList.add('active')
} else if (scrollTop >= popular.offsetTop && scrollTop < brand.offsetTop) {
document.querySelector('[data-name=popular]').classList.add('active')
} else if (scrollTop >= brand.offsetTop && scrollTop < topic.offsetTop) {
document.querySelector('[data-name=brand]').classList.add('active')
} else if (scrollTop >= topic.offsetTop) {
document.querySelector('[data-name=topic]').classList.add('active')
}
})
})();
</script>
</body>
</html>
效果:
电梯导航栏效果
1.2 关键思路梳理
- 每个功能点,写完后可以放到自执行函数里面,防止变量污染
- 实现页面滚动到对应的位置,电梯导航显示,否则隐藏,本质上是html页面的scrollTop和你需要的元素的offsetTop的大小比较
- 回到顶部,即
document.documentElement.scrollTop = 0
- 点击电梯的每一层,跳转到对应的大盒子,使用事件委托最好,不然得给每一层绑定点击事件,而这个跳转,则是通过让html滚动的scrollTop改成对应盒子的offsetTop实现,可以看到,电梯每一层的对象的自定义属性,和其对应的div大盒子的类选择器名字有关系,由此,可以通过电梯每一层的小盒子找到其对应的大盒子,这是自定义属性的一个运用
- 最后一个,实现页面滚动到对应的位置,对应的电梯导航那一项就高亮,实际就是根据大盒子选择小盒子,思路是:当页面滚动了,先移除所有小li 里面a 的状态 active 防止有多个 active,再获取所有的大盒子,判断页面滚动的距离document.documentElement.scrollTop,和每一个div大盒子offsetTop的大小关系,从而锁定页面现在滑动到哪儿了,再给对应的电梯的那一楼添加active样式即可
2、属性选择器补充
如下,有两个input标签,使用属性选择器选择其中一个input标签:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 选择type属性是text的input标签 */
input[type=text] {
color: red;
}
/* 选择有value属性的input标签 */
input[value] {
color: red;
}
</style>
</head>
<body>
<input type="text" value="123" data-id="0" data-name="tom">
<input type="password">
<script>
// 属性选择器,用自定义属性
const input = document.querySelector('input[value]')
console.log(input.dataset)
console.log(input.dataset.name)
</script>
</body>
</html>
效果:
自定义属性的使用: