无法在'Node'上执行'removeChild' [英] Failed to execute 'removeChild' on 'Node'

查看:304
本文介绍了无法在'Node'上执行'removeChild'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 http://alexgorbatchev.com/SyntaxHighlighter/ 突出显示我网站上的代码,但有时会在我的日志中得到这样的Javascript错误:

I'm using http://alexgorbatchev.com/SyntaxHighlighter/ to highlight code on my website but sometimes in my log im getting Javascript errors like this :


未捕获NotFoundError:无法在'Node'上执行'removeChild':要删除的节点不再这个节点的孩子。也许它被移动到'blur'事件处理程序中?

Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is no longer a child of this node. Perhaps it was moved in a 'blur' event handler?

Uncaught NotFoundError:尝试在不存在的上下文中引用Node。

Uncaught NotFoundError: An attempt was made to reference a Node in a context where it does not exist.



// set up handler for lost focus
attachEvent(textarea, 'blur', function(e)
{
   textarea.parentNode.removeChild(textarea);
   removeClass(highlighterDiv, 'source');
});

这是attachEvent()函数代码:

Here is the attachEvent() function code :

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);
    }
};

任何人都可以帮忙解决这个问题吗?

Can anyone help getting this fixed ?

推荐答案

我不得不处理同样的问题,答案是混乱和反直觉。好吧,它有它的逻辑,但会导致非平凡的行为。

I had to deal with the same issue, and the answer is confusing and counter intuitive. Well, it has its logic, but leads to non-trivial behaviours.

基本上,当从DOM树中删除一个节点时,它会触发一个模糊事件(以及焦点事件之前)。

Essentially, when a node is removed from the DOM tree, it fires a blur event (and before a focusout event too).

所以,当你打电话给 removeChild blur 事件再次被解雇,但这次 textarea 仍然定义了 parentNode ,但 textarea 不再是其父母的孩子了! (是的,请阅读两次。或者更多。)

So, when you call removeChild, the blur event is fired again, but this time textarea still has its parentNode defined, but textarea isn't among its parent's children anymore! (Yes, read this twice. Or more.)

目前在Chrome中会发生这种情况,尽管Firefox已经计划在相当长的时间内做同样的事情

This happens in Chrome for now, although Firefox has planned to do the same for quite some time.

作为解决方法,你可以删除你附加的事件监听器:

As a workaround, you can remove the event listener you attached:

var onblur = function(e) {
    detachEvent(textarea, 'blur', onblur);
    textarea.parentNode.removeChild(textarea);
    removeClass(highlighterDiv, 'source');
};
attachEvent(textarea, 'blur', onblur);

我假设你有一些 detachEvent 删除事件侦听器的函数。根据需要调整代码。

I'm assuming that you have some detachEvent function to remove event listeners. Adjust the code to your needs.

或者,您可以在侦听器的textarea上设置标志(如属性,属性或更好的范围变量)函数,并在继续删除节点之前检查它:

Alternatively, you can set a flag (like a property, or an attribute, or better a scoped variable) on the textarea in the listener function, and check for it before proceeding with the node removal:

var removed = false;
attachEvent(textarea, 'blur', function(e) {
    if (removed) return;
    removed = true;
    textarea.parentNode.removeChild(textarea);
    removeClass(highlighterDiv, 'source');
});

您还可以检查 textarea 是否实际在删除它之前,它的 parentNode 的子节点,但是这样的测试是非常反直觉的(至少对我而言)我不建议这样做,因为担心这个行为将来会改变。

You can also check if textarea if actually a child node of its parentNode before removing it, but such test is so counter-intuitive (at least to me) that I wouldn't recommend doing that, in fear that this behaviour will be changed in the future.

最后,你总是可以依赖 try ... catch 声明,但是......呃。

Finally, you can always rely on a try...catch statement, but... ugh.

当然,使用像jQuery这样的框架可以节省你的费用很多工作用一个附加事件监听器,但是这个功能将来到标准 addEventListener

Naturally, using a framework like jQuery would save you a lot of work attaching event listeners with one, but this functionality will come to standard addEventListener too:

textarea.addEventListener('blur', handler, { once: true });

这篇关于无法在'Node'上执行'removeChild'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆