暗黑模式功能正常但控制台报Cannot set properties of null错误的解决方法
错误分析与修复方案
错误原因
控制台抛出的Uncaught TypeError: Cannot set properties of null (setting 'src'),本质是代码尝试给一个不存在的DOM元素设置src属性。
当执行clickDarkMode或clickLightMode函数时,document.getElementById("custom-logo")返回了null,可能的场景:
- 当前页面中根本没有id为
custom-logo的元素(比如网站的404页、分类页等); - 元素是通过JS动态生成的,
DOMContentLoaded触发时还未完成插入。
修复方案
方案1:添加元素存在性检查(最通用)
在修改src属性前,先判断元素是否存在,避免对null操作。修改后的代码如下:
const userTheme = localStorage.getItem('theme') let status = false // Dark and Light Mode on Switch Click document.addEventListener("DOMContentLoaded", () => { const darkSwitch = document.getElementById("switch"); darkSwitch.addEventListener("click", () => { if (status === false) { clickDarkMode() } else if (status === true) { clickLightMode() } }); if (userTheme === 'dark') { clickDarkMode() } else if (userTheme === 'light') { clickLightMode() } // 封装logo更新逻辑,避免重复代码 function updateLogo(theme) { const customLogo = document.getElementById("custom-logo"); if (!customLogo) return; // 元素不存在则直接返回 customLogo.src = theme === 'dark' ? '/wp-content/uploads/2023/01/white-logo.png' : '/wp-content/uploads/2023/01/color-logo.png'; } function clickDarkMode() { localStorage.setItem("theme", "dark") document.documentElement.setAttribute('data-theme', 'dark') document.documentElement.classList.add("darkmode") document.body.classList.add("darkmode") updateLogo('dark') status = true } function clickLightMode() { localStorage.setItem("theme", "light") document.documentElement.setAttribute('data-theme', 'light') document.documentElement.classList.remove("darkmode") document.body.classList.remove("darkmode") updateLogo('light') status = false } });
方案2:适配动态生成的元素
如果custom-logo是通过JS动态插入到页面的(比如WordPress插件动态渲染的logo),DOMContentLoaded触发时元素可能还不存在,此时可以用MutationObserver监听元素的出现:
const userTheme = localStorage.getItem('theme') let status = false document.addEventListener("DOMContentLoaded", () => { const darkSwitch = document.getElementById("switch"); darkSwitch.addEventListener("click", () => { if (status === false) { clickDarkMode() } else if (status === true) { clickLightMode() } }); // 监听custom-logo元素的出现 const observer = new MutationObserver((mutations) => { const customLogo = document.getElementById("custom-logo"); if (customLogo) { // 元素出现后根据当前主题设置logo customLogo.src = userTheme === 'dark' ? '/wp-content/uploads/2023/01/white-logo.png' : '/wp-content/uploads/2023/01/color-logo.png'; observer.disconnect(); // 找到元素后停止监听,避免性能消耗 } }); // 监听body下所有子元素的变化 observer.observe(document.body, { childList: true, subtree: true }); if (userTheme === 'dark') { clickDarkMode() } else if (userTheme === 'light') { clickLightMode() } function updateLogo(theme) { const customLogo = document.getElementById("custom-logo"); if (!customLogo) return; customLogo.src = theme === 'dark' ? '/wp-content/uploads/2023/01/white-logo.png' : '/wp-content/uploads/2023/01/color-logo.png'; } function clickDarkMode() { localStorage.setItem("theme", "dark") document.documentElement.setAttribute('data-theme', 'dark') document.documentElement.classList.add("darkmode") document.body.classList.add("darkmode") updateLogo('dark') status = true } function clickLightMode() { localStorage.setItem("theme", "light") document.documentElement.setAttribute('data-theme', 'light') document.documentElement.classList.remove("darkmode") document.body.classList.remove("darkmode") updateLogo('light') status = false } });
内容的提问来源于stack exchange,提问作者곽이브
相关产品推荐
相关产品推荐

