HTML表格中点击图片切换显示/隐藏详情行异常问题排查
问题:点击表格单元格内图片显示详情表格,为何设置display:none的div包裹的行仍显示?
需求是点击HTML表格单元格内的图片,展示查询生成的详情表格,但下面的示例代码中,用display:none的div包裹的第二行<tr>仍然显示,这是为什么?
原代码示例:
<html> <head> <title>Show/Hide Test</title> <script> function showDeta() { var x = document.getElementById("details"); if (x.style.display === "none" || x.style.display === "") { x.style.display = "block"; } else { x.style.display = "none"; } } </script> </head> <body> <table border="1"> <tr> <td>Blah <image id="x" src="details.png" onClick="showDeta(this)" /></td> </tr> <div id="details" style="display:none;"> <tr> <td>Details of Blah</td> </tr> </div> </table> </body> </html>
原因及解决方案
核心原因
HTML表格有严格的结构规范:<table>的直接子元素只能是<thead>、<tbody>、<tr>、<tfoot>这类表格专属标签,不能直接嵌套<div>。浏览器在解析不符合规范的代码时,会自动修正DOM结构——把<div>内部的<tr>直接提取出来,放到<table>下,脱离了div的包裹,导致display:none对这个<tr>完全失效,所以它会直接显示出来。
另外还有两个小问题:
- 原代码里的
<image>标签是错误写法,标准图片标签是<img> showDeta(this)里的this参数在函数中没有被使用,可以直接去掉
解决方案
方案1:用<tbody>包裹详情行(推荐,符合表格规范)
把详情行放到<tbody>中,通过控制<tbody>的显示隐藏来实现需求,因为<tbody>是表格的合法子元素:
<html> <head> <title>Show/Hide Test</title> <script> function showDeta() { var x = document.getElementById("details"); // 注意tbody的display属性值是table-row-group if (x.style.display === "none" || x.style.display === "") { x.style.display = "table-row-group"; } else { x.style.display = "none"; } } </script> </head> <body> <table border="1"> <tr> <td>Blah <img id="x" src="details.png" onClick="showDeta()" /></td> </tr> <tbody id="details" style="display:none;"> <tr> <td>Details of Blah</td> </tr> </tbody> </table> </body> </html>
方案2:将div放到<td>内部
如果一定要用div,可以把div嵌套在表格的单元格<td>里,确保符合HTML结构规范:
<html> <head> <title>Show/Hide Test</title> <script> function showDeta() { var x = document.getElementById("details"); if (x.style.display === "none" || x.style.display === "") { x.style.display = "block"; } else { x.style.display = "none"; } } </script> </head> <body> <table border="1"> <tr> <td>Blah <img id="x" src="details.png" onClick="showDeta()" /></td> </tr> <tr> <td> <div id="details" style="display:none;"> <table border="1"> <tr> <td>Details of Blah</td> </tr> </table> </div> </td> </tr> </table> </body> </html>
内容的提问来源于stack exchange,提问作者epipko
相关产品推荐
相关产品推荐

