Vanilla JS меняет активное состояние ссылок при прокрутке рефакторинга - PullRequest
0 голосов
/ 26 августа 2018

Я пытаюсь отбросить jQuery из моих будущих проектов.Я нашел способ создать липкую навигацию при прокрутке с помощью чистого Vanilla JS и хотел, чтобы ссылки на моей навигации меняли свое активное состояние при достижении соответствующих разделов.

Ниже приведено рабочее решение, которое я придумал, но я уверен, что код можно улучшить, чтобы он работал программно, без необходимости выбирать и создавать условия для каждого элемента.

Я также использую множество различных селекторов, и я уверен, что тамДолжен быть способ улучшить это, возможно, используя querySelectorAll и добавив eventListener в цикл forEach, но я не могу заставить это работать.Спасибо за вашу помощь!

// select links
const allLinks = document.querySelectorAll('header nav ul li');
const linkTop = document.querySelector('#linkTop');
const linkAbout = document.querySelector('#linkAbout');
const linkServices = document.querySelector('#linkServices');
const linkClients = document.querySelector('#linkClients');
const linkContact = document.querySelector('#linkContact');
// select sections
const sectionTop = document.querySelector('#top');
const sectionAbout = document.querySelector('#about');
const sectionServices = document.querySelector('#services');
const sectionClients = document.querySelector('#clients');
const sectionContact = document.querySelector('#contact');

function changeLinkState() {
  // home
  if (window.scrollY >= sectionTop.offsetTop) {
    allLinks.forEach(link => {
      link.classList.remove('active');
    });
    linkTop.classList.add('active');
  }
  // about
  if (window.scrollY >= sectionAbout.offsetTop) {
    allLinks.forEach(link => {
      link.classList.remove('active');
    });
    linkAbout.classList.add('active');
  }
  // services
  if (window.scrollY >= sectionServices.offsetTop) {
    allLinks.forEach(link => {
      link.classList.remove('active');
    });
    linkServices.classList.add('active');
  }
  clients
  if (window.scrollY >= sectionClients.offsetTop) {
    allLinks.forEach(link => {
      link.classList.remove('active');
    });
    linkClients.classList.add('active');
  }
  contact
  if (window.scrollY >= sectionContact.offsetTop) {
    allLinks.forEach(link => {
      link.classList.remove('active');
    });
    linkContact.classList.add('active');
  }
}

window.addEventListener('scroll', changeLinkState);
<nav>
  <ul>
    <li id="linkTop">
      <a href="#top">Home</a>
    </li>
    <li id="linkAbout">
      <a href="#about">About Us</a>
    </li>
    <li id="linkServices">
      <a href="#services">Services</a>
    </li>
    <li id="linkClients">
      <a href="#clients">Clients</a>
    </li>
    <li id="linkContact">
      <a href="#contact">Contact</a>
    </li>
  </ul>
</nav>

Большое спасибо!

1 Ответ

0 голосов
/ 26 августа 2018

Вы можете получить все разделы и ссылки, используя document.querySelectorAll(). При прокрутке повторяйте список разделов от последнего к первому, пока не найдете тот, который соответствует. Затем удалите класс .active из всех ссылок и добавьте его к ссылке в активном index.

Примечание: Вы должны использовать throttling , чтобы предотвратить вызов changeLinkState несколько раз в секунду. Другой вариант - использовать API наблюдателя пересечения .

const links = document.querySelectorAll('.links');
const sections = document.querySelectorAll('section');

function changeLinkState() {
  let index = sections.length;

  while(--index && window.scrollY + 50 < sections[index].offsetTop) {}
  
  links.forEach((link) => link.classList.remove('active'));
  links[index].classList.add('active');
}

changeLinkState();
window.addEventListener('scroll', changeLinkState);
nav {
  position: fixed;
  top: 0;
  right: 0;
  width: 10em;
}

section {
  height: 100vh;
  margin: 1em 0;
  background: gold;
}

.active {
  background: silver;
}
<nav>
  <ul>
    <li id="linkTop" class="links">
      <a href="#top">Home</a>
    </li>
    <li id="linkAbout" class="links">
      <a href="#about">About Us</a>
    </li>
    <li id="linkServices" class="links">
      <a href="#services">Services</a>
    </li>
    <li id="linkClients" class="links">
      <a href="#clients">Clients</a>
    </li>
    <li id="linkContact" class="links">
      <a href="#contact">Contact</a>
    </li>
  </ul>
</nav>

<section>
  Home
</section>

<section>
  About Us
</section>

<section>
  Services
</section>

<section>
  Clients
</section>

<section>
  Contact
</section>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...