【问题标题】:classList.remove and .add not working for some reasonclassList.remove 和 .add 由于某种原因无法正常工作
【发布时间】:2022-01-20 17:19:20
【问题描述】:

切换开关时,我从浏览器控制台收到这些错误。出于某种原因,它不起作用,我无法解决为什么它不起作用我刚刚开始使用 Javascript,所以如果我做了一些愚蠢的事情,请不要生我的气。

Uncaught TypeError: Cannot read properties of undefined (reading 'remove')
    at getValue (darkModeSwitch.js:8)
    at window.onload (index.html:17)

Uncaught TypeError: Cannot read properties of undefined (reading 'add')
    at getValue (darkModeSwitch.js:13)
    at HTMLInputElement.onclick (index.html:26)

HTML:

<div>
        <ul>
            <li><a href="kapcsolat/kapcsolat.html?version=691">Kapcsolat</a></li>
            <li><a href="projects/projects.html?version=691">Projektek</li>
            <li><a class="active" href="index.html?version=692">Kezdőlap</a></li>
            <li><label class="switch"><input onclick="getValue()" id="darkModeToggle" type="checkbox" checked><span class="slider round"></span></label><script src="scripts/darkModeSwitch.js"></script>
            </li>
            <h1 class="jayden" style="float: left;"><a class="jayden" href="index.html?version=-23424893215">jayden.hu</a></h1>  
        </ul>
    </div>

CSS:

      .lightmode{
    background-color: white;
    color: black;
}

Javascript:

const body = document.body
const anchor = document.getElementsByTagName("a");
const darkModeToggle = document.getElementById('darkModeToggle');

function getValue(){
if (darkModeToggle.checked) {
    body.classList.remove("lightmode")
    anchor.classList.remove("lightmode")
    console.log("checked")
} else{
    console.log("not checked")
    body.classList.add("lightmode")
    anchor.classList.add("lightmode")
}
};

【问题讨论】:

  • 是 JS 代码 const body = document.body 等 - 在页面加载后执行吗?尝试将变量初始化包装在 window.addEventListener('DOMContentLoaded', () =&gt; {
  • 我有这样的。
  • document.getElementsByTagName 返回元素的数组[],这就是为什么 anchor.classList 是 undefined 。您应该专门找到要切换类的元素。

标签: javascript html css web


【解决方案1】:

错误是因为您试图一次修改多个元素上的classList;您的 anchor 变量包含一组 HTML 元素(所有锚点)而不是一个特定元素。

谢天谢地,因为 CSS 级联,除了你的身体,你不需要改变任何元素的类。只需在 CSS 中像这样处理 a 元素,以便它们继承 body 的颜色:

function getValue() {
  document.body.classList.toggle("lightmode")
};
body {
  background-color: black;
  color: white;
}

.lightmode {
  background-color: white;
  color: black;
}

a {
  color: inherit;
}
<body>
  <ul>
    <li><a href="kapcsolat/kapcsolat.html?version=691">Kapcsolat</a></li>
    <li><a href="projects/projects.html?version=691">Projektek</a></li>
    <li><a class="active" href="index.html?version=692">Kezdőlap</a></li>
    <li><label class="switch"><input onclick="getValue()" id="darkModeToggle" type="checkbox" checked><span class="slider round"></span></label></li>
    <h1 class="jayden" style="float: left;"><a class="jayden" href="index.html?version=-23424893215">jayden.hu</a></h1>
  </ul>
</body>

【讨论】:

    【解决方案2】:

    问题不在于 Body 而在于 anchor 。 您使用 getElementsByTagName 返回一个 List ( array ) 而不是单个元素,即使您有一个 a anchor 常量值将是一个长度为 1 的数组。

    要么通过 ID 使用 querySelector 要么选择第一项 document.getElementsByTagName("a")[0] -> 不是真正的最佳实践。

    或者,如果您有多个锚标记,只需遍历它们

    见下文

    const body = document.body
    const anchor = document.querySelectorAll("a.jayden");
    const darkModeToggle = document.getElementById('darkModeToggle');
    
    function getValue() {
      if (darkModeToggle.checked) {
        body.classList.remove("lightmode")
        anchor.forEach(a => a.classList.remove("lightmode"))
        console.log("checked")
      } else {
        console.log("not checked")
        body.classList.add("lightmode")
         anchor.forEach(a => a.classList.add("lightmode"))
      }
    };
    .lightmode {
      background:blue
      }
      a.lightmode {
        color: white
        }
    <input onclick="getValue()" id="darkModeToggle" type="checkbox" checked />
    <a class="jayden" href="#" >jayden.hu</a>
    <a class="jayden" href="#" >jayden.hu</a>

    【讨论】:

    • 它不返回一个数组它返回一个实时HTMLCollection
    • @pilchard HTMLCollection 和数组有什么区别(尤其是在这种特定情况下)?
    • 谢谢,这确实有效,但如果我在一个元素上还有另一个类,它就不起作用了。我该如何解决这个问题?
    • 区别很明显:首先是 HTMLCollection 是实时的,这意味着在 DOM 中所做的更改会反映在集合中,反之亦然,接下来该集合不实现任何内置的数组方法(包括 forEach)。 (querySelectorAll 返回一个 NodeList,它确实实现了 forEach 方法,但它与同名的 Array 方法是分开的)
    • @Jayden 你想从你的 html 中选择所有的锚标签吗?另外,为什么要在“a”中添加与 body 相同的类?如果您想根据主题(浅色/深色)将某些东西更改为 alla 元素,只需将类添加到 body 并在 CSS 中直接依赖 body 类设置 a 元素(和其他元素)
    【解决方案3】:

    Anchor 是一个 HTML 集合,应该循环遍历:

    const body = document.body;
    
    const anchor = document.getElementsByTagName('a');
    const darkModeToggle = document.getElementById('darkModeToggle');
    
    function getValue(){
     
    if (darkModeToggle.checked) {
    
        console.log("checked");
        if(body.classList.contains("lightmode")){
        body.classList.remove("lightmode")
        }
       for(var a=0;a<anchor.length;a++){
        if(anchor[a].classList.contains("lightmode")){
        anchor[a].classList.remove("lightmode");
        }
       }
        
    } else{
    
        
        console.log("not checked");
         if(!body.classList.contains("lightmode")){
        body.classList.add("lightmode")
       }
        for(var a=0;a<anchor.length;a++){
        if(!anchor[a].classList.contains("lightmode")){
        anchor[a].classList.add("lightmode");
        }
       }
    }
    }
      .lightmode{
        background-color: white;
        color: black;
    }
    <body>
    <div>
            <ul>
                <li><a href="kapcsolat/kapcsolat.html?version=691">Kapcsolat</a></li>
                <li><a href="projects/projects.html?version=691">Projektek</a></li>
                <li><a class="active" href="index.html?version=692">Kezdőlap</a></li>
                <li><label class="switch"><input onclick="getValue()" id="darkModeToggle" type="checkbox" checked><span class="slider round"></span></label><script src="scripts/darkModeSwitch.js"></script>
                </li>
                <h1 class="jayden" style="float: left;"><a class="jayden" href="index.html?version=-23424893215">jayden.hu</a></h1>  
            </ul>
        </div>
        </body>

    【讨论】:

      【解决方案4】:
      <input onclick="getValue()" id="darkModeToggle" type="checkbox" checked />
      <a class="jayden" href="#" >jayden.hu</a>
      <a class="jayden" href="#" >jayden.hu</a>
      
      
      //Make sure the elements exist on page
      const body = document.body
      const anchors = document.getElementsByTagName('a');
      const darkModeToggle = document.getElementById('darkModeToggle');
          
      const getValue = () => {
        body.classList.toggle('lightmode'); // adds or removes class
        for (const anchor in anchors) {
          anchor.classList.toggle('lightmode'); // adds or removes class
        }
      };
      

      【讨论】:

        猜你喜欢
        • 2013-12-28
        • 1970-01-01
        • 1970-01-01
        • 2016-12-06
        • 2012-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-07
        相关资源
        最近更新 更多