学习记录-js基础-电梯导航

电梯导航功能描述

  1. 当页面滚动指定位置时侧边导航栏出现
  2. 点击侧边导航栏,页面滚动到指定位置
  3. 页面滚动到指定位置时,侧边导航栏出现提示

实现效果

在这里插入图片描述

电梯导航实现步骤

1. 概念理解

  1. 理解事件委托和自定义属性的用法
    事件委托:利用冒泡的特性:子元素绑定事件触发,父元素事件也触发
    自定义属性:用户自行定义的属性,通常以data-开头
  2. 电梯导航的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改变

  1. 隐藏侧边栏
    	 .aside {
            position: fixed;
            left: -100%;		//隐藏侧边栏
            top: 50%;
            transform: translateY(-50%);
            transition: all 1s;
        }
  1. 给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类名

  1. 定义自定义属性
<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>
  1. 遍历所有元素,给自定义属性所对应的元素添加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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值