【问题标题】:Failed to execute 'insertBefore' on 'Node': parameter 1 is not of type 'Node'无法在“节点”上执行“插入之前”:参数 1 不是“节点”类型
【发布时间】:2023-04-01 12:17:02
【问题描述】:

如何解决此错误?我做错了什么可能导致这种情况?

在 Chrome 控制台中,我无法在“节点”上执行“插入之前”:参数 1 不是“节点”类型。对于这行代码

rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);

可以在最后找到。我不知道如何解决这个错误或这个错误是什么。

console.log("CONNECTED");
var n = 1;
tester(n);

function tester(n){
var switchcount = 0;
var  table = document.getElementById("myTable2");
var monthsArray= ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];//0-11    

var switching = true;
// Set the sorting direction to ascending:
var dir = "asc";
// Check the status of each data cell in a table. 
while(switching){
    switching = false;
    var rows = table.rows;      
    var shouldSwitch;

    for (var i = 1; i < (rows.length-1); i++) { 
        var cellsX = rows[i].getElementsByTagName("TD")[n];
        var cellsY = rows[i + 1].getElementsByTagName("TD")[n];
        var dateX = cellsX.textContent.split(" ");
        var dateY = cellsY.textContent.split(" ");
        var mnthX = dateX[0];
        var mnthY = dateY[0];
        var yearX = dateX[1];
        var yearY = dateY[1];
        var totalX = parseInt(monthsArray.indexOf(mnthX)) + parseInt(yearX);
        var totalY = parseInt(monthsArray.indexOf(mnthY)) + parseInt(yearY);

        if(dir === "asc"){
            if(totalX < totalY) {
                //if so, mark as a switch and break the loop:
                shouldSwitch = true;
                break;
            }
        }else if(dir === "desc"){
            if(totalX > totalY){
                shouldSwitch = true;
                break;
            }
        }
    }
    if(shouldSwitch){
        rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
        switching = true;
        switchcount++;
    }else{
        if (switchcount === 0 && dir === "asc") {
            dir = "desc";
            switching = true;
        }

    }
}

}

我按月和年排序的表格。

<table id ="myTable2">
    <thead>
        <tr>
            <th>Client</th>
            <th>Due Date</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Smith</td>
            <td>Apr 18</td>
        </tr>
        <tr>
            <td>Kelly</td>
            <td>Jan 18</td>
        </tr>
        <tr>
            <td>Park</td>
            <td>Nov 18</td>
        </tr>
        <tr>
            <td>Mark</td>
            <td>July 19</td>
        </tr>
    </tbody>
</table>

【问题讨论】:

  • var rows = table.rows; 这给了你什么?
  • @jmargolisvt 他的只读 HTMLTableElement 属性行返回表中所有行的实时 HTMLCollection,包括包含在任何 、 和 元素中的行。虽然属性本身是只读的,但返回的对象是活动的并且允许修改其内容。 developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement/rows
  • 有一个 jQuery 解决方案可以让您适应您的问题:stackoverflow.com/questions/1569889/…
  • 只需注释掉rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); 并运行。你会看到你的 while 循环是 ifinite。
  • @JamesParker 回复:尝试先学习 vanilla JS……我完全明白,绝对。但是 vanilla JS 的概念存在两个问题:一个是 JavaScript 可以在不同的浏览器/引擎之间以不同的方式工作。另一个是 DOM 可以在不同的浏览器中以不同的方式组织...... JQuery 实际上会为您处理其中的一些,这是学习它的一个很好的理由。

标签: javascript error-handling split tablesorter


【解决方案1】:

修改后的答案:

当您i 是行的最后一个元素的索引时,没有rows[i+1]。您的问题是,在代码的上述部分中,iifor 循环之后的值,这是循环测试 i &lt; (rows.length-1) 失败的第一个值。因此,在代码的这一点上,您应该始终拥有i === (rows.length-1),这不是您想要的。

避免在循环外使用循环变量(这很少是目标并且总是难以阅读/理解/调试等)的一种方法是使用let 而不是var 编写循环,如果您不介意不支持旧版浏览器:

for (let i = 1; i < (rows.length-1); i++) {

这样,i 将不会在循环之外定义,并且如果您碰巧尝试在代码下方进一步使用 i,则会有一个易于理解的错误告诉您一个没有任何意义的地方。


但是代码中还有其他错误。特别是,您永远不会真正摆脱while 循环。希望您现在可以自己解决这个问题,因为您知道如何解决您遇到的错误。但如果我必须使用纯 JavaScript 对表格进行排序,我可能会:

  • 获取我的表中所有行的列表,
  • 使用 the build-in sort function 和精心挑选的比较函数对这些内容进行排序,
  • 使用remove从DOM中删除所有行,
  • 使用appendChild 在已排序数组上的for 循环中以正确的顺序添加它们。

这样会更容易阅读和调试。编写自己的排序函数是一个很好的练习,但如果您的目标是 Web 功能而不是练习算法,请不要这样做。

【讨论】:

  • 我认为使用 rows.length-1 会跳过表头
  • @JamesParker 等等,你是对的。我以某种方式误读了...我认为导致问题的行在for循环内,但事实并非如此。让我更新我的答案。
  • 我在索引 0 处添加了一个空白数组项,我的错误消失了。所以我在想当 Jan = 0 但第 0 行是标题时。所以就坏了???我认为
猜你喜欢
相关资源
最近更新 更多
热门标签