简体   繁体   English

在 JavaScript 中滚动时添加 className

[英]add className on scroll in JavaScript

I'm trying to add a className on scroll.我正在尝试在滚动时添加className I keep getting a我不断得到一个

document is undefined文档未定义

edit: I found out I was getting the error from the typo.编辑:我发现我从错字中得到错误。 When I define document.getElementsByClassName("main-nav").scrollTop nothing comes up in the console .当我定义document.getElementsByClassName("main-nav").scrollTop时, console什么也没有出现。 As well as the page does not get affected.以及页面不会受到影响。

window.onscroll = function() {
  windowScroll();
};

function windowScroll() {
  if (document.getElementsByClassName("main-nav").scrollTop > 50 || document.documentElement.scrollTop > 50) {
    document.getElementsByClassName("main-nav").className = "test";
  } else {
    document.getElementsByClassName("main-nav").className = "";
  }
}

CSS is CSS 是

.test {
  background: pink
}

I'm not necessarily looking for the answer, I just want guidance我不一定在寻找答案,我只是想要指导

There are 2 problems:有2个问题:

getElementsByClassName returns an array of HTMLCollection and it has no property scrollTop . getElementsByClassName返回一个HTMLCollection数组,它没有属性scrollTop You probably want the first item so the code shoul be document.getElementsByClassName("main-nav")[0] (or document.querySelector(".main-nav") )您可能想要第一项,因此代码应该是document.getElementsByClassName("main-nav")[0] (或document.querySelector(".main-nav")

But if you try it, you will get an error:但是如果你尝试一下,你会得到一个错误:

Cannot read property 'scrollTop' of undefined无法读取未定义的属性“scrollTop”

 window.onscroll = function() { windowScroll(); }; function windowScroll() { if (document.getElementsByClassName("main-nav").scrollTop > 50 || document.documentElement.scrollTop > 50) { document.getElementsByClassName("main-nav").className = "test"; } else { document.getElementsByClassName("main-nav").className = ""; } }
 html, body { height: 150%; } .test { background: pink }
 <div class="main-nav"></div>

The reason is that you override the class attribute of .main-nav by this assignment:原因是你通过这个赋值覆盖了.main-navclass属性:

document.getElementsByClassName("main-nav").className = "";

In this line you set the class attribute to empty string.在这一行中,您将class属性设置为空字符串。 You probably want to add / remove the test call but keeping the main-nav class.您可能想要添加/删除测试调用但保留main-nav类。

There are 2 things you can do:你可以做两件事:

  1. Set the id attribute to main-nav instead of the class attribute, then use document.getElementById method.id属性设置为main-nav而不是class属性,然后使用document.getElementById方法。

 window.onscroll = function() { windowScroll(); }; function windowScroll() { if (document.getElementById("main-nav").scrollTop > 50 || document.documentElement.scrollTop > 50) { document.getElementById("main-nav").className = "test"; } else { document.getElementById("main-nav").className = ""; } }
 html, body { height: 150%; } #main-nav { position: fixed; width: 100%; } .test { background: pink }
 <div id="main-nav">Main Nav</div>

  1. Toggle only the test class using classList.toggle .使用classList.toggle仅切换test类。

 window.onscroll = function() { windowScroll(); }; function windowScroll() { if (document.getElementsByClassName("main-nav")[0].scrollTop > 50 || document.documentElement.scrollTop > 50) { document.getElementsByClassName("main-nav")[0].classList.add("test"); } else { document.getElementsByClassName("main-nav")[0].classList.remove("test"); } }
 html, body { height: 150%; } .main-nav { position: fixed; width: 100%; } .test { background: pink }
 <div class="main-nav">Main Nav</div>


The final approach with some optimisations:带有一些优化的最终方法:

 var mainNav = document.querySelector('.main-nav'); window.onscroll = function() { windowScroll(); }; function windowScroll() { mainNav.classList.toggle("test", mainNav.scrollTop > 50 || document.documentElement.scrollTop > 50); }
 html, body { height: 150%; } .main-nav { position: fixed; width: 100%; } .test { background: pink }
 <div class="main-nav">Main Nav</div>

The changes:变化:

  1. Store the .main-nav element on the global context (the window object)..main-nav元素存储在全局上下文( window对象)上。 It will not change so you don't need to find it in any scroll.它不会改变,所以你不需要在任何卷轴中找到它。
  2. Use querySelector so you will get a single DOM element, not collection.使用querySelector这样您将获得单个 DOM 元素,而不是集合。
  3. Use classList.toggle to toggle the class by condition.使用classList.toggle按条件切换类。

The issue with your console.log is that you're trying to pull the scrollTop for an HTML Collection (a collection of elements in your page) of 1 or more divs - therefore it can't check for the scrollTop as the console.log as it doesn't actually have that property.您的 console.log 的问题是您试图为 1 个或多个 div 的 HTML 集合(页面中的元素集合)拉出 scrollTop - 因此它无法像 console.log 一样检查 scrollTop因为它实际上没有那个属性。

Assuming you only have one element with the "main-nav" class (or there is a particular element with this class that you wish to apply it to), you would be better off using one of the following: document.getElementsByClassName("main-nav")[0] or document.getElementById("main-nav") (the latter would require you to create a main-nav id rather than a class).假设您只有一个具有“main-nav”类的元素(或者您希望将它应用于该类的特定元素),您最好使用以下之一: document.getElementsByClassName("main-nav")[0]document.getElementById("main-nav") (后者需要您创建一个 main-nav id 而不是一个类)。

For the first one, however, using className reassigns the class name rather than adding to that particular div, therefore you can use document.getElementsByClassName("main-nav")[0].classList.add("test") (and remove instead of add if it does not match your criteria).但是,对于第一个,使用 className 重新分配类名而不是添加到该特定 div,因此您可以使用document.getElementsByClassName("main-nav")[0].classList.add("test") (并remove如果它不符合您的标准,则不要add )。

If there is more than one element with the "main-nav" class, you can still use the first option I suggested - only you would need to wrap it around in a for loop and replace the 0 with your variable of choice.如果“main-nav”类有多个元素,您仍然可以使用我建议的第一个选项 - 只有您需要将它包装在 for 循环中并用您选择的变量替换 0。

for (i = 0; i < document.getElementsByClassName("main-nav").length; i++) {
  //your code here using document.getElementsByClassName("main-nav")[i]
}

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

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