使用JavaScript修改CSS的:hover::before伪元素属性时报错如何解决?
问题根因
- 第一,CSS伪元素(包括
:hover伪类、::before伪元素)不属于真实DOM节点,无法通过document.querySelectorAll直接获取,你添加了:hover::before后缀的选择器匹配不到任何有效DOM元素,最终遍历的是空集合或者无效对象,调用style.setProperty自然会报错。 - 第二,
forEach回调的指向/参数错误:用普通function作为回调时,内部this默认指向全局对象(严格模式下为undefined),并不会指向当前遍历的DOM元素;你后续写的箭头函数参数mega-menu-link不符合JS变量命名规范,中划线会被识别为减号运算符,实际拿到的是undefined。 - 第三,CSS变量本身支持继承,完全不需要针对伪元素单独设置,只要给伪元素的宿主DOM节点设置对应变量,伪元素就能继承到对应值。
修复方案
最简方案(推荐)
直接给菜单根容器设置CSS变量,所有子元素的伪元素会自动继承该值,不需要遍历每个菜单项,性能更高:
// 只需要获取菜单根容器 const menuWrap = document.querySelector('#mega-menu-wrap-primary'); // 滚动逻辑里直接修改根容器的变量 const bgColor = currentScrollPos > 0 ? 'green' : 'white'; menuWrap.style.setProperty('--mega-menu-link-background-color', bgColor);
兼容原有写法的方案
如果你确实需要给每个a标签单独设置变量,修改选择器和遍历逻辑即可:
// 去掉选择器里的:hover::before,只匹配真实存在的a标签 const menuSlideColor = document.querySelectorAll('#mega-menu-wrap-primary #mega-menu-primary li.mega-menu-item > ul.mega-sub-menu a.mega-menu-link'); const bgColor = currentScrollPos > 0 ? 'green' : 'white'; // 遍历的时候用参数接收当前元素,不要用this,变量名不要用中划线 menuSlideColor.forEach(link => { link.style.setProperty('--mega-menu-link-background-color', bgColor); });
内容的提问来源于stack exchange,提问作者Nikolai Mikkelsen
相关产品推荐
相关产品推荐

