Javascript 未能执行';removeChild';在';节点';
我用它在我的网站上突出显示代码,但有时在我的日志中会出现如下Javascript错误: 未捕获NotFoundError:未能在“节点”上执行“removeChild”:要删除的节点不再是此节点的子节点。可能是在“模糊”事件处理程序中移动的 Uncaught NotFoundError:尝试在不存在节点的上下文中引用该节点 以下是attachEvent()函数代码:Javascript 未能执行';removeChild';在';节点';,javascript,Javascript,我用它在我的网站上突出显示代码,但有时在我的日志中会出现如下Javascript错误: 未捕获NotFoundError:未能在“节点”上执行“removeChild”:要删除的节点不再是此节点的子节点。可能是在“模糊”事件处理程序中移动的 Uncaught NotFoundError:尝试在不存在节点的上下文中引用该节点 以下是attachEvent()函数代码: function attachEvent(obj, type, func, scope) { function handl
function attachEvent(obj, type, func, scope)
{
function handler(e)
{
e = e || window.event;
if (!e.target)
{
e.target = e.srcElement;
e.preventDefault = function()
{
this.returnValue = false;
};
}
func.call(scope || window, e);
};
if (obj.attachEvent)
{
obj.attachEvent('on' + type, handler);
}
else
{
obj.addEventListener(type, handler, false);
}
};
有人能帮我解决这个问题吗?我不得不处理同样的问题,答案令人困惑,而且违反直觉。嗯,它有它的逻辑,但会导致非琐碎的行为 本质上,当从DOM树中删除节点时,它会触发
blur
事件(在focusout
事件之前)
因此,当您调用removeChild
时,blur
事件将再次触发,但这次textarea
仍定义了其parentNode
,但textarea
不再属于其父节点的子节点!(是的,读两遍。或者更多。)
虽然Firefox已经有相当长的一段时间了,但现在Chrome浏览器中也出现了这种情况
作为一种解决方法,您可以删除附加的事件侦听器:
var onblur = function(e) {
detachEvent(textarea, 'blur', onblur);
textarea.parentNode.removeChild(textarea);
removeClass(highlighterDiv, 'source');
};
attachEvent(textarea, 'blur', onblur);
我假设您有一些detachEvent
函数来删除事件侦听器。根据需要调整代码
或者,您可以在侦听器函数的textarea上设置一个标志(如属性、属性或更好的范围变量),并在继续删除节点之前进行检查:
var removed = false;
attachEvent(textarea, 'blur', function(e) {
if (removed) return;
removed = true;
textarea.parentNode.removeChild(textarea);
removeClass(highlighterDiv, 'source');
});
您还可以在删除它之前检查textarea
是否确实是其parentNode
的子节点,但这样的测试非常违反直觉(至少对我来说),我不建议这样做,因为担心这种行为将来会改变
最后,您可以始终依赖于try…catch
语句,但是。。。啊
2016年更新
当然,使用jQuery这样的框架将为您节省大量的工作,将事件监听器与one
连接起来,但此功能也将用于:
而不是
textarea.parentNode.removeChild(textarea)
您可以使用textarea.parentNode.innerHTML='
或类似的东西,具体取决于您的上下文。我在这里冒险,假设您中的一些人发现了这个问题,因为您搜索了上面引用的错误:
“节点”上的“removeChild”:要删除的节点不再是子节点
这个节点的。可能是在“模糊”事件处理程序中移动的
我正在使用jQuery&DataTables 1.10.6,在更新单元格值的blur()
事件中确实出现了此错误。我的解决方案是在事件中添加如下条件:
var blur = false;
$('table').on('blur', 'td select', function() {
if (!blur) {
blur = true;
var cell = $(this).closest('td');
table.cell(cell).data('example data');
blur = false;
}
});
如果没有更好的解决方案,我会非常惊讶,但希望这能帮助一些人,并可能获得一些建设性的意见。我在一个简单的jQuery脚本上发现了相同的错误消息。 当我试图获取元素$('#element').height()的高度时,我在控制台上看到了相同的错误 元素已存在且为$('#element')。长度为1 带有console.log($('#element')的元素的日志类似于jQuery对象,但有许多重复的方法 经过大量调试后,我发现添加$(document).on('DOMContentLoaded-DOMNodeInserted')事件处理程序会使jQuery对象出现这种奇怪的情况
希望这能帮助别人,因为很难找到它。我使用时间延迟,它对我来说就是这样 // set up handler for lost focus attachEvent(textarea, 'blur', function(e) { setTimeout(function() { textarea.parentNode.removeChild(textarea); removeClass(highlighterDiv, 'source'); }, 0); }); //为失去焦点设置处理程序 attachEvent(文本区域,'blur',函数(e) { setTimeout(函数(){ textarea.parentNode.removeChild(textarea); removeClass(highlighterDiv,“源”); }, 0); });
我犯了这个错误,但上面的一切都帮不了我,最终我只得到了一个简单的答案:
if (img.parentNode) {
body.removeChild(img);
}
这对我来说非常合适。为什么不使用jquery:
$("#element_id").remove();
每次执行该方法时,您都需要检查该元素是否是给定父元素的子元素
if(box.parentElement === parentBox) {
parentBox.removeChild(box);
}
虽然这个问题的经典答案是这是JS代码中的一个bug,但是React 16有一个主要bug,这意味着任何修改DOM的浏览器/扩展机制都会破坏React 谷歌浏览器内置的翻译功能是最常见的罪魁祸首 GitHub问题: 最小大小写:(只需在Chrome中手动右键单击“Translate to”并从日语中选择,然后单击按钮) 解决方法:
尝试使用Google Chrome翻译您的站点(右键单击站点并选择“翻译为英语”。如果您在控制台中看到错误,则您知道它是由Google translate引起的 相关GitHub问题:
Dan Abramov的解决方案:
if (typeof Node === 'function' && Node.prototype) {
const originalRemoveChild = Node.prototype.removeChild;
Node.prototype.removeChild = function(child) {
if (child.parentNode !== this) {
if (console) {
console.error('Cannot remove a child from a different parent', child, this);
}
return child;
}
return originalRemoveChild.apply(this, arguments);
}
const originalInsertBefore = Node.prototype.insertBefore;
Node.prototype.insertBefore = function(newNode, referenceNode) {
if (referenceNode && referenceNode.parentNode !== this) {
if (console) {
console.error('Cannot insert before a reference node from a different parent', referenceNode, this);
}
return newNode;
}
return originalInsertBefore.apply(this, arguments);
}
}
在应用程序呈现之前运行此代码。请记住,这会对性能造成轻微影响
Shuhei Kagawa的解决方案 在
中呈现文本
// Case 1
<div>
{condition && 'Welcome'}
<span>Something</span>
</div>
// A workaround for case 1
<div>
{condition && <span>Welcome</span>}
<span>Something</span>
</div>
// Case 2
<div>
{condition && <span>Something</span>}
Welcome
</div>
// A workaround for case 2
<div>
{condition && <span>Something</span>}
<span>Welcome</span>
</div>
//案例1
{条件&“欢迎”}
某物
//案例1的解决方法
{条件&&Welcome}
某物
//案例2
{条件&&Something}
欢迎
//案例2的解决方法
{条件&&Something}
欢迎
详细说明可在此处找到:
从程序触发的事件类型可能与Dom的默认操作不同。如果您检查类型,并使用If(type=='typeYouWant')作为保护子句,则可能会跳过代码的不必要执行。控制台记录事件以检查是否存在可以隔离的'type'
formEditEl.addEventListener('blur', this._cancelEdit.bind(this));
_cancelEdit(e) {
if (e.type === "change") document.querySelector('.form__edit').remove();
};
什么是textarea html?如果可能,制作一个fiddle.textarea=document.createElement('textarea')您可以在完整的源代码中使用它。您可以尝试此演示,但错误通常不会出现。我只是在记录javascript错误的网站日志中有时会遇到错误。attachEve
if (typeof Node === 'function' && Node.prototype) {
const originalRemoveChild = Node.prototype.removeChild;
Node.prototype.removeChild = function(child) {
if (child.parentNode !== this) {
if (console) {
console.error('Cannot remove a child from a different parent', child, this);
}
return child;
}
return originalRemoveChild.apply(this, arguments);
}
const originalInsertBefore = Node.prototype.insertBefore;
Node.prototype.insertBefore = function(newNode, referenceNode) {
if (referenceNode && referenceNode.parentNode !== this) {
if (console) {
console.error('Cannot insert before a reference node from a different parent', referenceNode, this);
}
return newNode;
}
return originalInsertBefore.apply(this, arguments);
}
}
// Case 1
<div>
{condition && 'Welcome'}
<span>Something</span>
</div>
// A workaround for case 1
<div>
{condition && <span>Welcome</span>}
<span>Something</span>
</div>
// Case 2
<div>
{condition && <span>Something</span>}
Welcome
</div>
// A workaround for case 2
<div>
{condition && <span>Something</span>}
<span>Welcome</span>
</div>
formEditEl.addEventListener('blur', this._cancelEdit.bind(this));
_cancelEdit(e) {
if (e.type === "change") document.querySelector('.form__edit').remove();
};