classList.remove 和 .add 由于某种原因无法正常工作

Posted

技术标签:

【中文标题】classList.remove 和 .add 由于某种原因无法正常工作【英文标题】:classList.remove and .add not working for some reason 【发布时间】: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 。您应该专门找到要切换类的元素。 【参考方案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
  
;

【讨论】:

以上是关于classList.remove 和 .add 由于某种原因无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

操作类名 classList

从零开始的全栈工程师——js篇2.15

class类名的管理

ES6 - 原生js遍历DOM - document.querySelectorAll(‘.xx‘)给DOM元素添加删除类名 - dom.classList.add切换类名toggle

ES6 - 原生js遍历DOM - document.querySelectorAll(‘.xx‘)给DOM元素添加删除类名 - dom.classList.add切换类名toggle

56jQuery事件