引入Codepen示例JavaScript后表格无数据行显示求助
问题原因分析
我帮你排查了下问题,根源出在脚本执行时机上:你的JavaScript代码写在<head>标签内,浏览器会优先解析<head>里的内容,这时候<body>中的表格元素还没有被创建出来,所以document.querySelector("table")会获取到null。后续尝试从null上获取thead和tbody的操作都会失败,最终导致负责生成表格行的createTable函数根本没法正常运行,自然看不到数据行啦。
解决办法
有两种简单的修复方式,选一种就行:
方法一:把脚本移到<body>末尾
把<script>标签放到</body>标签的前面,这样浏览器会先渲染完所有DOM元素,再执行脚本,就能正确获取到表格元素了。
修改后的完整代码示例:
<html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="styles.css" rel="stylesheet" type="text/css" /> <link href="new.css" rel="stylesheet" type="text/css" /> </head> <body> <div> <table> <thead> <tr> <th class='prop__name' data-prop-name='firstName'>First Name</th> <th class='prop__name' data-prop-name='lastName'>Last Name</th> <th class='prop__name' data-prop-name='birth'>Birth</th> </tr> </thead> <tbody></tbody> </table> </div> <script> var table = document.querySelector("table"), table_meta_container = table.querySelector("thead"), table_data_container = table.querySelector("tbody"), data = [ { firstName: "Scooby", lastName: "Doo", birth: 1969 }, { firstName: "Yogi", lastName: "Bear", birth: 1958 }, { firstName: "Tom", lastName: "Cat", birth: 1940 }, { firstName: "Jerry", lastName: "Mouse", birth: 1940 }, { firstName: "Fred", lastName: "Flintstone", birth: 1960 } ], n = data.length; var createTable = function (src) { var frag = document.createDocumentFragment(), curr_item, curr_p; for (var i = 0; i < n; i++) { curr_item = document.createElement("tr"); curr_item.classList.add(i % 2 === 0 ? "odd" : "even"); data[i].el = curr_item; for (var p in data[i]) { if (p !== "el") { curr_p = document.createElement("td"); curr_p.classList.add("prop__value"); curr_p.dataset.propName = p; curr_p.textContent = data[i][p]; curr_item.appendChild(curr_p); } } frag.appendChild(curr_item); } table_data_container.appendChild(frag); }; var sortTable = function (entries, type, dir) { entries.sort(function (a, b) { if (a[type] < b[type]) return -dir; if (a[type] > b[type]) return dir; return 0; }); table.dataset.sortBy = type; for (var i = 0; i < n; i++) { entries[i].el.style.order = i + 1; if ( (i % 2 === 0 && entries[i].el.classList.contains("even")) || (i % 2 !== 0 && entries[i].el.classList.contains("odd")) ) { entries[i].el.classList.toggle("odd"); entries[i].el.classList.toggle("even"); } } }; createTable(data); table_meta_container.addEventListener( "click", function (e) { var t = e.target; if (t.classList.contains("prop__name")) { if (!t.dataset.dir) { t.dataset.dir = 1; } else { t.dataset.dir *= -1; } sortTable(data, t.dataset.propName, t.dataset.dir); } }, false ); </script> </body> </html>
方法二:监听DOMContentLoaded事件
如果不想移动脚本位置,可以把所有DOM操作相关的代码包裹在DOMContentLoaded事件监听里,确保只有当整个DOM加载完成后才执行这些代码。
修改后的脚本部分:
document.addEventListener('DOMContentLoaded', function() { var table = document.querySelector("table"), table_meta_container = table.querySelector("thead"), table_data_container = table.querySelector("tbody"), data = [ { firstName: "Scooby", lastName: "Doo", birth: 1969 }, { firstName: "Yogi", lastName: "Bear", birth: 1958 }, { firstName: "Tom", lastName: "Cat", birth: 1940 }, { firstName: "Jerry", lastName: "Mouse", birth: 1940 }, { firstName: "Fred", lastName: "Flintstone", birth: 1960 } ], n = data.length; var createTable = function (src) { var frag = document.createDocumentFragment(), curr_item, curr_p; for (var i = 0; i < n; i++) { curr_item = document.createElement("tr"); curr_item.classList.add(i % 2 === 0 ? "odd" : "even"); data[i].el = curr_item; for (var p in data[i]) { if (p !== "el") { curr_p = document.createElement("td"); curr_p.classList.add("prop__value"); curr_p.dataset.propName = p; curr_p.textContent = data[i][p]; curr_item.appendChild(curr_p); } } frag.appendChild(curr_item); } table_data_container.appendChild(frag); }; var sortTable = function (entries, type, dir) { entries.sort(function (a, b) { if (a[type] < b[type]) return -dir; if (a[type] > b[type]) return dir; return 0; }); table.dataset.sortBy = type; for (var i = 0; i < n; i++) { entries[i].el.style.order = i + 1; if ( (i % 2 === 0 && entries[i].el.classList.contains("even")) || (i % 2 !== 0 && entries[i].el.classList.contains("odd")) ) { entries[i].el.classList.toggle("odd"); entries[i].el.classList.toggle("even"); } } }; createTable(data); table_meta_container.addEventListener( "click", function (e) { var t = e.target; if (t.classList.contains("prop__name")) { if (!t.dataset.dir) { t.dataset.dir = 1; } else { t.dataset.dir *= -1; } sortTable(data, t.dataset.propName, t.dataset.dir); } }, false ); });
验证效果
不管用哪种方法,修改后重新运行代码,表格应该就能正常显示数据行,并且点击表头也能实现排序功能啦。
内容的提问来源于stack exchange,提问作者rimi
相关产品推荐
相关产品推荐

