JavaScript onclick切换两个Div显示状态报错问题求解
问题根因
报错和功能异常来自4个明确的代码问题:
- 动态创建的
mainDiv从未被插入到页面真实DOM树中,两个带displayTable、displayGraph类名的div只存在于内存里,document.querySelector查找时直接返回null,访问null的style属性就会触发你看到的类型错误。 - 点击事件绑定逻辑写在
formatData内部,每次调用formatData(比如多次触发接口请求)都会给viewTable按钮新增一个点击回调,会导致切换逻辑重复执行。 - else分支里给表格设置隐藏状态时错用了比较运算符
===,没有实际执行赋值操作,点击切换时表格不会被隐藏。 - 初始显示状态是通过CSS类规则生效的,不是写在元素内联style上,初始读取
element.style.display会拿到空字符串,直接和"none"做判断会出现逻辑误判。
修复方案
原有CSS代码不需要改动,JS部分按如下逻辑调整即可:
// 提前缓存固定DOM元素,事件只绑定一次,避免重复绑定 // 注意替换成你页面上实际的选择器,确保代码执行时这些元素已经存在于DOM中 const viewTable = document.querySelector('#viewTable'); const mountNode = document.querySelector('#render-container'); // 用来挂载表格、图表内容的页面已有容器 const formatData = (response) => { const mainDiv = document.createElement("div"); const div1= document.createElement("div"); div1.classList.add("displayTable"); div1.appendChild(formatTable(response)); mainDiv.appendChild(div1) const div2 = document.createElement("div"); div2.classList.add("displayGraph"); div2.appendChild(formatGraph(response)); mainDiv.appendChild(div2) // 核心修复1:把渲染完成的内容插入页面真实DOM,否则querySelector无法找到对应元素 mountNode.innerHTML = ''; // 清空旧的渲染结果避免内容堆叠 mountNode.appendChild(mainDiv); }; // 核心修复2:点击事件挪到formatData外部,只绑定一次 viewTable.addEventListener("click", function() { const tableEl = document.querySelector('.displayTable'); const graphEl = document.querySelector('.displayGraph'); // 增加元素存在性校验,避免内容未渲染时点击报错 if(!tableEl || !graphEl) return; // 通过计算后的实际样式判断显示状态,规避初始内联style为空的判断误差 const isTableHidden = window.getComputedStyle(tableEl).display === 'none'; if(isTableHidden) { graphEl.style.display = 'none'; tableEl.style.display = 'block'; } else { // 核心修复3:用赋值运算符=设置样式,不要用比较运算符=== tableEl.style.display = 'none'; graphEl.style.display = 'block'; } }) // 原有fetch逻辑保持不变,正常调用formatData即可 // fetch(yourApiAddress).then(res => res.json()).then(data => formatData(data))
可选优化
如果后续功能迭代更复杂,建议把显示/隐藏的样式规则封装成独立CSS类,切换时直接增删类名即可,不需要反复修改内联style,代码可维护性更高。
内容的提问来源于stack exchange,提问作者eme
相关产品推荐
相关产品推荐

