Javascript:无法在“节点”上执行“removeChild”:参数 1 不是“节点”类型

问题描述 投票:0回答:1

我正在尝试从其中一门课程中重新创建一些实践。它即将从一个 UL 中删除一个 li-item 并将其附加到另一个 UL。

当我按照以下方式编写代码时,一切正常

var removeMeandAppendMe = function() {
    var parentLi = this.parentNode;
    var goneElement = incompleList.removeChild(parentLi);
    compleList.appendChild(goneElement);
};

var li = incompleList.getElementsByTagName('li');

for (var i = 0; i < incompleList.children.length; i++) {
    var link = li[i];
    var liCheckArray = link.getElementsByTagName('input');
    var liCheck = liCheckArray[0];
    liCheck.onchange = removeMeandAppendMe;
}

当我将代码更改为以下内容时,出现错误“无法在‘Node’上执行‘removeChild’:参数 1 不是‘Node’类型”。

function removeMeandAppendMe(fromList, toList) {
    var parentLi = this.parentNode;
    var goneElement = fromList.removeChild(parentLi);
    toList.appendChild(goneElement);
}

var li = incompleList.getElementsByTagName('li');

for (var i = 0; i < incompleList.children.length; i++) {
    var link = li[i];
    var liCheckArray = link.getElementsByTagName('input');
    var liCheck = liCheckArray[0];
    liCheck.onchange = removeMeandAppendMe(incompleList, compleList);
}

令我困扰的是,当我的 removeMeandAppendMe 函数没有参数且无法使用参数时,代码运行良好。谁能告诉我为什么以及我的错误在哪里?谢谢。

(我知道这里讨论的模糊问题:Failed to execute 'removeChild' on 'Node'

javascript removechild
1个回答
0
投票

首先,正如 Pointy 提到的,您确实需要将对

RemoveMeandAppendMe(incompleList, compleList)
的调用包装在一个匿名函数中,这样它就不会被过早调用。

考虑到这一点,您收到此错误是因为

this
的值是每个函数调用的情况。当调用
RemoveMeandAppendMe()
时,
this
是一个 HTMLInputElement 对象,但是当调用
RemoveMeandAppendMe(incompleList, compleList)
时,
this
是 Window 对象,所以
this.parentNode
undefined
(因此“不是‘节点’类型”),这就是您看到该错误消息的原因)。

这个问题有很多微妙之处:

this
指的是什么,以及如何处理不同的“功能”声明(很多讨论here)。只是改变
RemoveMeandAppendMe(incompleList, compleList)
的声明方式也不能解决问题。

在某种程度上,您的问题归结为“为什么

this
指的是参数化函数调用的 Window 对象,而不是非参数化函数调用的 HTMLInputElement 对象?”我相信在这种情况下,这是因为,当我们将参数化函数调用的调用包装在匿名函数中时(如:
liCheck.onchange = function(){removeMeandAppendMe(incompleList, compleList);};
),
removeMeandAppendMe
没有“本地”所有者,因此该函数的所有权默认为全局对象 Window(reference)。

要解决此问题,您可以将

this
传递给
removeMeandAppendMe
的调用,其中
this
将引用复选框,然后将其用作该参数化函数中的变量。我已经把所有这些都放在你的 fiddle 中,可以通过评论/取消评论不同的东西来玩这些东西。希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.