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', () =>
我有这样的。
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 由于某种原因无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
ES6 - 原生js遍历DOM - document.querySelectorAll(‘.xx‘)给DOM元素添加删除类名 - dom.classList.add切换类名toggle
ES6 - 原生js遍历DOM - document.querySelectorAll(‘.xx‘)给DOM元素添加删除类名 - dom.classList.add切换类名toggle