简体   繁体   English

如何突出显示用户在 javascript 中查看的当前部分?

[英]How to highlight the current section the user is viewing in javascript?

I am coding a simple navigation bar for a project that has four sections, and I made it interactive enough to have a specific color when hovering/clicking on a section and then it returns back to its original color after clicking.我正在为一个有四个部分的项目编写一个简单的导航栏,并且我使它具有足够的交互性,以便在悬停/单击一个部分时具有特定的颜色,然后在单击后返回其原始颜色。 But what if I want the selected section to still be colored/highlighted when a user is viewing it?但是,如果我希望选定的部分在用户查看时仍然被着色/突出显示怎么办? So if the hovering color is coded blue, i want the section in the Navbar to still be blue when a user has selected it, and then changes when a user selects another section.因此,如果悬停颜色编码为蓝色,我希望导航栏中的部分在用户选择它时仍为蓝色,然后在用户选择另一个部分时更改。 Here's my code so far.到目前为止,这是我的代码。

// The mouse hover functiona and commands. Here we specificy the color of the buttons/mouse
 // when the user clicks on them, there's a color for hovering/clicking
 // and a color for leaving the button

 function mouseOver () {
    let anchor = document.getElementsByTagName('a');

    for (i = 0; i < anchor.length; i++) {
        anchor[i].addEventListener('mouseover', function handleMouseOver() {
            event.target.style.backgroundColor = "#72a6ca";
            event.target.style.color = "#fff";
        })
        //the color returns to its normal state after clicking away
        anchor[i].addEventListener('mouseout', function handleMouseOut() {
            event.target.style.backgroundColor = "rgb(220, 220, 220)";
            event.target.style.color = "black";
            })
        }
    }

and here is my navbar display code这是我的导航栏显示代码

function navBarStyle () {
    let anchor = document.getElementsByTagName('a');
    let styles = `
        display: flex;
        flex-direction: row;
        align-items: stretch;
        color: #000;
        text-decoration: none;
        margin: 0 0.5em 0 0.5em;
        padding: 0.5em;
        background-color: rgb(220, 220, 220);
        font-size: large;
        transform:translateX(-0.5em);
    `;

    for (i = 0; i < anchor.length; i++) {
        anchor[i].setAttribute('style', styles);
    } }

if i was vague enough i am sorry, but any help would be appreciated to put me on the right track如果我不够含糊,我很抱歉,但任何帮助将不胜感激,让我走上正轨

Firstly, a note for your current implementation.首先,为您当前的实现做一个说明。 It works and it is pretty well coded.它可以工作,而且编码得很好。 But for this thing browsers offer native functionality using the :hover selector and it would be better to use than to reinvent it.但是对于这件事,浏览器使用 :hover 选择器提供本机功能,使用它比重新发明它更好。

I don't have your HTMl but you would most likely need to add a class to each 'a' tag in the nav, something like this:我没有您的 HTMl,但您很可能需要为导航中的每个“a”标签添加一个类,如下所示:

<nav>
    <a href="link1" class="nav-link">Link 1</a>
    <a href="link2" class="nav-link">Link 2</a>
</nav>

and then you would need a style tag in the head (or better, external css)然后你需要在头部有一个样式标签(或者更好,外部css)

<head>
...
<style>
  .nav-link {
    background-color: 72a6ca;
    color: #fff;
  }

  .nav-link:hover {
     background-color: rgb(220, 220, 220);
     color: black;
  }
</style>
</head>

As for the current section, your best bet would be to use https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API至于当前部分,您最好的选择是使用https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

See here for an example: Intersection observer API scroll aware navigation请参阅此处的示例: Intersection Observer API 滚动感知导航

or this codepen: https://codepen.io/mishunov/pen/opeRdL或者这个codepen: https ://codepen.io/mishunov/pen/opeRdL

Using IntersectionObserver you can detect when the user scrolls in/out of the section.使用 IntersectionObserver,您可以检测用户何时滚动进/出该部分。 You can toggle another class on and off of the related nav-link then.然后,您可以打开和关闭相关导航链接的另一个类。 For example - say you toggle the .current class, your style could look like this to style both cases (hovering and currently scrolled) in 1 place:例如 - 假设您切换 .current 类,您的样式可能看起来像这样,将两种情况(悬停和当前滚动)设置在一个位置:

  .nav-link:hover, 
  .nav-link.current {
     background-color: rgb(220, 220, 220);
     color: black;
  }

You can make a class named active like this您可以像这样使一个名为 active 的类

.active {
    backgroundColor: #72a6ca;
    color: #fff;
}

and assign it to each anchor that's clicked(or hovered), simultaneously remove .active from the other anchors并将其分配给单击(或悬停)的每个锚点,同时从其他锚点中删除.active

let anchors = document.getElementsByTagName('a');


for (let anchor of anchors) {
        anchor.addEventListener('mouseover', function handleMouseOver() {
        const target = event.currentTarget;
        if (target.classList.contains('active')) {
            target.classList.remove('active')
        } else {
            [...anchors].forEach((anchor) => anchor.classList.remove('active'))
            target.classList.add('active')
        }
    })
}

If you want to give the class active to the anchors in viewPort use this code:如果你想给 viewPort 中的锚active类,请使用以下代码:

const anchors = document.getElementsByTagName('a');

const isInViewport = el => {
  const rect = el.getBoundingClientRect();
  return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <=
      (window.innerHeight || document.documentElement.clientHeight) &&
    rect.right <= (window.innerWidth || document.documentElement.clientWidth)
  );
};

const run = () =>
  anchors.forEach(item => {
    if (isInViewport(item)) {
      item.classList.add('active');
    }
  });

// Events
window.addEventListener('load', run);
window.addEventListener('resize', run);
window.addEventListener('scroll', run);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM