簡體   English   中英

添加 class 在滾動時處於活動狀態。 香草JS

[英]Add class active on scroll. Vanilla JS

我是香草js的新手。 我有一個帶有部分鏈接的導航欄。 我想在該部分激活后立即激活 class。 如果沒有活動部分,則移除活動 class。 找到了這樣一個腳本,但是有一個缺點。 如果我處於非活動部分,則活動 class 將保留在前一個活動部分。

 const links = document.querySelectorAll('.nav-link'); const sections = document.querySelectorAll('.forJS'); 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);
 section{ height:100vh; scroll-y:auto; }.nav-link.active{ color: red; }
 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet"/> <body> <header class="fixed-top"> <nav class="navbar navbar-expand-lg navCustom"> <div class="container"> <ul class="navbar-nav justify-content-center"> <li class="nav-item"> <a class="nav-link" href="#main">Main</a> </li> <li class="nav-item"> <a class="nav-link" href="#about">About us</a> </li> <li class="nav-item"> <a class="nav-link" href="#portfolio">Portfolio</a> </li> <li class="nav-item"> <a class="nav-link" href="#contacts">Contacts</a> </li> </ul> </div> </nav> </header> <section class="forJS text-center">Some info 1</section> <section class="forJS text-center">Some info 2</section> <section class="forJS text-center">Some info 3</section> <section class="text-center">Some info 4</section> <section class="text-center">Some info 5</section> <section class="text-center">Some info 6</section> <section class="text-center">Some info 7</section> <section class="text-center">Some info 8</section> <section class="text-center">Some info 9</section> <section class="forJS text-center">Some info 10</section> </body>

PS看最后一行,有changeLinkState 它應該沒有括號()嗎? 而里面while是空的,為什么?

使用當前設計實現所需功能的最小更改是測試部分的高度以確保其可見,而不是像當前代碼中那樣無條件地將活動 class 添加到最近的導航鏈接。

if (window.scrollY - sections[index].offsetHeight < 
      sections[index].offsetTop) {
  links[index].classList.add('active');
}

代替:

links[index].classList.add('active');

您可以使用像scrollY + 50這樣的偏移量來調整截止點,但在這里硬編碼數字似乎並不理想。

完整代碼:

 const links = document.querySelectorAll('.nav-link'); const sections = document.querySelectorAll('.forJS'); function changeLinkState() { let index = sections.length; while (--index && window.scrollY + 50 < sections[index].offsetTop) {} links.forEach((link) => link.classList.remove('active')); // add the active class if within visible height of the element if (scrollY - sections[index].offsetHeight < sections[index].offsetTop) { links[index].classList.add('active'); } } changeLinkState(); window.addEventListener('scroll', changeLinkState);
 section { height: 100vh; }.nav-link.active { color: red; } section { border: 1px solid #555; }
 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" /> <body> <header class="fixed-top"> <nav class="navbar navbar-expand-lg navCustom"> <div class="container"> <ul class="navbar-nav justify-content-center"> <li class="nav-item"> <a class="nav-link" href="#main">Main</a> </li> <li class="nav-item"> <a class="nav-link" href="#about">About us</a> </li> <li class="nav-item"> <a class="nav-link" href="#portfolio">Portfolio</a> </li> <li class="nav-item"> <a class="nav-link" href="#contacts">Contacts</a> </li> </ul> </div> </nav> </header> <section class="forJS text-center">Some info 1</section> <section class="forJS text-center">Some info 2</section> <section class="forJS text-center">Some info 3</section> <section class="text-center">Some info 4</section> <section class="text-center">Some info 5</section> <section class="text-center">Some info 6</section> <section class="text-center">Some info 7</section> <section class="text-center">Some info 8</section> <section class="text-center">Some info 9</section> <section class="forJS text-center">Some info 10</section> </body>

您的其他問題已在評論中解決,但我將在這里重申答案:

  • changeLinkState上沒有使用括號,因為我們將 function object 本身傳遞給稍后調用的回調。 如果我們像changeLinkState()那樣調用它,我們最終會將undefined傳遞給回調並過早地觸發處理程序,如此所述。
  • while是空的,因為它操縱終止條件(即--index )的塊作為簡寫形式合並到條件中,如此所述。

除此之外,我將簡要說明設計存在多個問題,並將其作為練習留給讀者:

  • 引導布局將側邊欄 header 擴展到整個頁面,因此 header 和元素之間可能存在無意的重疊。 如果 header 有背景,則內容將被遮擋。 我將重新審視這里的結構,以確保使用多個不重疊的列或流布局。
  • <section>標簽應該在父容器中。
  • CSS 屬性不應該是camelCased forJS不是特別明確的 class 名稱。
  • scroll-y:auto; 是無效的 CSS 屬性。 也許您的意思是overflow-y: auto; .
  • 觸發滾動事件偵聽器和迭代部分的策略有些原始。 查看throttling並考慮重構以使用Intersection Observer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM