【问题标题】:change the active list when scrolling navbar滚动导航栏时更改活动列表
【发布时间】:2021-11-12 09:51:27
【问题描述】:

我正在尝试让导航栏在部分之间移动,我会向下滚动。

我试图用 JS 来实现它,但我不能让它工作 当我点击事件监听器时它会改变活动类,但当我滚动时我无法让它工作

感谢您的帮助

这是我的js代码

let section = document.querySelectorAll('section')
let lists = document.querySelectorAll('.list');
function activeLink(){
    lists.forEach((item) =>
    item.classList.remove('active'));
    this.classList.add('active');
}
lists.forEach((item) =>
item.addEventListener('click',activeLink));

window.onscroll = () =>{
  section.forEach(sec =>{
    let top = window.scrollY;
    let offset = sec.offsetTop;
    let height = sec.offsetHeight;
    let id = sec.getAttribute('id');

    if(top >= offset && top < offset + height){
      lists.forEach(sec =>{
        activeLink;
      })
    }
  })
};

这是我的html

<nav class="navigation">
        <ul>
            <li class="list active">
                <a href="#home">
                    <span class="icon">
                        <ion-icon name="home-outline"></ion-icon>
                    </span>
                    <span class="title">Home</span>
                </a>
            </li>
            <li class="list">
                <a href="#about">
                    <span class="icon">
                        <ion-icon name="person-outline"></ion-icon>
                    </span>
                    <span class="title">About Me</span>
                </a>
            </li>
            <li class="list">
                <a href="#working">
                    <span class="icon">
                        <ion-icon name="newspaper-outline"></ion-icon>
                    </span>
                    <span class="title">Working</span>
                </a>
            </li>
            <li class="list">
                <a href="#">
                    <span class="icon">
                        <ion-icon name="code-slash-outline"></ion-icon>
                    </span>
                    <span class="title">Learned</span>
                </a>
            </li>
            <li class="list">
                <a href="#contact">
                    <span class="icon">
                        <ion-icon name="chatbox-outline"></ion-icon>
                    </span>
                    <span class="title">Contact</span>
                </a>
            </li>
        </ul>
    </nav>

【问题讨论】:

  • 我不确定你的问题是否正确,但对我来说这听起来像是一个固定的导航栏,不是吗?为什么不直接设置position: fixed?
  • 它在位置:固定,我尝试让导航栏在滚动时在部分之间移动
  • fixed 表示它与您的视口相关,因此它应该在部分之间自动移动。也许您也可以提供您的 HTML,以便更好地关注。
  • 我添加了 HTML

标签: javascript frontend navbar nav onscroll


【解决方案1】:

您的代码的第一个问题是您没有正确调用“activeLink”函数。

 if(top >= offset && top < offset + height){
  lists.forEach(sec =>{
    activeLink;
  })
}

如果您添加括号,那么它会起作用并由于“this”关键字在这种情况下引用窗口对象而引发错误。

要工作,在“onScroll”处理程序中,您可以用这段代码替换您的代码:

if (top >= offset && top < offset + height) {
    lists.forEach((item) => {
        item.classList.remove('active');
        if(item.querySelector('a').getAttribute('href') == '#' + id){
            item.classList.add('active');
        }
     });            
}

当然,您的目标不是重复您的代码。所以,我们可以先这样选择目标:

const target = document.querySelector(`[href='#${id}']`).parentElement;
activeLink(target);

直接将它传递给“activeLink”函数将引导您检查传入的参数是“点击事件”还是列表项,并处理这两种情况。相反,您可以像这样编辑处理程序代码:

lists.forEach((item) =>
  item.addEventListener('click', function(){
     activeLink(this);
  }));

这是最终状态下的“activeLink”功能代码:

function activeLink(li) {
    lists.forEach((item) => item.classList.remove('active'));
    li.classList.add('active');
}

这里是sn-p的代码:

let section = document.querySelectorAll('section');
        let lists = document.querySelectorAll('.list');
        function activeLink(li) {
            lists.forEach((item) => item.classList.remove('active'));
            li.classList.add('active');
        }
        lists.forEach((item) =>
            item.addEventListener('click', function(){
                activeLink(this);
            }));

        window.onscroll = () => {
            section.forEach(sec => {
                let top = window.scrollY;
                let offset = sec.offsetTop;
                let height = sec.offsetHeight;
                let id = sec.getAttribute('id');

                if (top >= offset && top < offset + height) {
                    const target = document.querySelector(`[href='#${id}']`).parentElement;
                    activeLink(target);
                }
            })
        };
.sec {
            height: 500px;
        }

        nav {
            position: fixed;
            width: 100%;
            top: 0;
            left: 0;
            z-index: 10;
            background-color: #fff;
        }

        .active a {
            color: palevioletred;
        }
<nav class="navigation">
        <ul>
            <li class="list active">
                <a href="#home">
                    <span class="icon">
                        <ion-icon name="home-outline"></ion-icon>
                    </span>
                    <span class="title">Home</span>
                </a>
            </li>
            <li class="list">
                <a href="#about">
                    <span class="icon">
                        <ion-icon name="person-outline"></ion-icon>
                    </span>
                    <span class="title">About Me</span>
                </a>
            </li>
            <li class="list">
                <a href="#working">
                    <span class="icon">
                        <ion-icon name="newspaper-outline"></ion-icon>
                    </span>
                    <span class="title">Working</span>
                </a>
            </li>
            <li class="list">
                <a href="#Learned">
                    <span class="icon">
                        <ion-icon name="code-slash-outline"></ion-icon>
                    </span>
                    <span class="title">Learned</span>
                </a>
            </li>
            <li class="list">
                <a href="#contact">
                    <span class="icon">
                        <ion-icon name="chatbox-outline"></ion-icon>
                    </span>
                    <span class="title">Contact</span>
                </a>
            </li>
        </ul>
    </nav>

    <section class="sec" style="background-color: beige;" id="home"></section>
    <section class="sec" style="background-color: yellow;" id="about"></section>
    <section class="sec" style="background-color: orange;" id="working"></section>
    <section class="sec" style="background-color: orangered;" id="Learned"></section>
    <section class="sec" style="background-color: olive;" id="contact"></section>

【讨论】:

  • 首先,非常感谢您的回答和解释,我复制并粘贴了它,但它仍然无法滚动但可以点击
  • 它对我不起作用,因为我的代码中有另一个 onScroll 函数,所以我将它们合并,现在它可以工作了,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 2013-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-23
相关资源
最近更新 更多