【问题标题】:Can I replace s standard DOM functions like removeChild?我可以替换像 removeChild 这样的标准 DOM 函数吗?
【发布时间】:2013-04-22 22:26:57
【问题描述】:

我可以替换像 removeChild 这样的标准 DOM 函数,以在从父节点删除某些节点之前显示警报吗?类似的东西,但我的例子有错误

var original = node.removeChild;
node.removeChild = function(node, original){
    alert('message');
    original(node);
}

【问题讨论】:

  • 你可以,但你不应该。
  • @kan 为什么不呢?在不了解上下文的情况下,你不能说“你不应该”。
  • @alex23 请不要对问题/答案代码进行如此重大的更改。 new 关键字的(不)存在意义重大。它只会让作者感到困惑(他们不会学到任何东西,因为你只是更改了代码而没有评论)
  • 如果您想将其应用于整个文档而不是单个节点,您可能需要更改 Node.prototype.removeChild

标签: javascript


【解决方案1】:

如果你想在整个文档中应用这个

var original = Node.prototype.removeChild;
Node.prototype.removeChild = function(node) {
    //custom logic
    original.apply(this, arguments);
}

如果您只想将更改应用到选定的节点,那么

var original = node.removeChild;
node.removeChild = function(node){
    //custom logic
    original.apply(this, arguments);
}

【讨论】:

  • 我更喜欢你第二种方式,但我有一个奇怪的错误:原始未定义
  • 函数签名中的原始参数是不必要的
  • @Nawa 是复制粘贴错误
  • 我想你忘记返回原始函数调用的值了。
【解决方案2】:

首先,new关键字的使用是完全错误的。这将严重改变行为。 functionFunction 的一个实例,它是所有 JavaScript 函数的“母舰”。

当使用new 关键字时,该函数将立即执行,其行为与您所期望的非常不同。有关如何创建函数对象的更多详细信息,请参阅 ECMA 语言规范第 13 节。阅读here,第 98 页。

其次,强烈建议不要更改任何本机对象prototype。它导致了人类历史上最乏味和最痛苦的错误。任何在您之后编辑代码的人都会花很长时间才能弄清楚警报的来源。

将这两个动作分开,它们完全不相关。将它们包装在 prototype 函数中是非常糟糕的设计,因为上述原因还有很多,例如:

  1. 使用for in 循环。如果您忘记使用 hasOwnProperty,您将遍历更多应该使用的属性。
  2. 您自己和其他开发人员将很难弄清楚为什么发生基本 DOM 节点删除操作时会发生随机事件。(您会忘记,每个人都会发生)。

【讨论】:

  • 这些原因实际上是令人鼓舞的,for in 循环是荒谬的。我不会去for..in 除了普通对象之外的任何东西,如果我去的话,它也不会是 DOM 节点。第二个原因是假设有一个庞大的企业程序员团队。这两个原因适用于极少数人,所以这就是你鼓励这样做的原因:D
【解决方案3】:

我会变得激进,只是说不。虽然它在技术上可以在您关心的浏览器上运行并且是prototype.js 的基础,但您永远不应该像这样修改DOM 对象或其原​​型。

关于该主题有一篇很长的帖子:http://perfectionkills.com/whats-wrong-with-extending-the-dom/ 但 TL;DR 是这些是“托管对象”,并且不能保证对其行为进行修改。它今天可能在浏览器 x 上工作,但不能保证明天浏览器 y 甚至 x 。

【讨论】:

    【解决方案4】:

    您的实现看起来不错,只是您不需要将original 作为参数传递。

    var original = node.removeChild;
    node.removeChild = function(node) {
        alert('message');
        original(node);
    }
    

    【讨论】:

    • 这可能会导致问题,因为当您调用 original(node); 时会丢失原始方法上下文,请参阅我的答案
    • 在 FF 我有错误:值没有实现接口节点。原始(节点);在 chrome 中我有:非法调用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-27
    相关资源
    最近更新 更多