JavaScript中无法访问元素class以修改类名的问题排查
问题描述
需要将元素的class从score -box1修改为score -box1 -active,定义常量$target获取class为score -box1的元素时代码未生效,原实现代码如下:
const $target = document.getElementByClassname('score -box1') function PlayerScore(score = 0){ if(score == 1){ $target.toggle('-active'); }else if(score == 2){ $target.toggle('-active'); }else if(score == 3){ $target.toggle('-active'); } return( /*html*/ ` <div class = "container"> <div class = "score -box1">one</div> <div class = "score -box2">two</div> <div class = "score -box3">three</div> </div> ` ) }
错误原因
代码存在5个核心问题导致运行失败:
- DOM方法拼写错误:原生通过类名获取元素的方法为
getElementsByClassName,注意Elements为复数、ClassName首字母大写,原代码的方法名不存在,会直接抛出JS运行错误。 - 返回值使用错误:
getElementsByClassName返回的是HTMLCollection元素集合,不是单个DOM节点,集合本身不存在类名操作方法,无法直接调用toggle。 - 元素获取时机错误:
$target在函数外层定义时,函数返回的HTML字符串还未被插入到DOM树中,此时页面上不存在对应节点,获取结果为空。 - 类名操作方法错误:原生DOM节点没有直接的
toggle方法,切换类名需要调用节点classList属性下的toggle方法。另外注意:class属性通过空格分隔多个类名,激活态只需要追加-active类即可,最终class为score -box1 -active,不要在class值中添加.——.是CSS选择器的语法,不属于DOM类名的组成部分。 - 冗余逻辑:三个score分支的执行逻辑完全一致,不需要重复编写三次判断。
修正方案
function PlayerScore(score = 0){ // 先定义HTML模板 const template = /*html*/` <div class = "container"> <div class = "score -box1">one</div> <div class = "score -box2">two</div> <div class = "score -box3">three</div> </div> `; // 将模板插入到页面对应挂载节点(此处以插入body为例,可替换为实际业务中的挂载容器) document.body.innerHTML = template; // 等DOM渲染完成后再获取目标元素,用querySelector直接匹配单个元素更简便 const $target = document.querySelector('.score.-box1'); // score为1/2/3时统一切换激活态 if([1,2,3].includes(score)){ $target.classList.toggle('-active'); } return template; }
如果你在React/Vue等框架环境下使用这段逻辑,不要直接手动操作DOM,应该通过组件状态绑定class的方式实现激活态切换,避免手动DOM操作和框架虚拟DOM渲染产生冲突。
内容的提问来源于stack exchange,提问作者herb
相关产品推荐
相关产品推荐

