访问 JavaScript 中 __defineGetter__/__defineSetter__ 隐藏的属性

发布于 2024-11-09 11:08:42 字数 959 浏览 5 评论 0原文

我正在尝试为 innerHTML 属性定义一个自定义设置器。不幸的是,在定义 setter 函数后,我无法访问底层属性:

$('body')[0].__defineSetter__("innerHTML",
  function (val) {
    alert("Setting to: " + val);
    this.innerHTML = val;
});

此代码片段填充了调用堆栈,因为赋值会递归调用 setter。 显然 innerHTML 已经是 IE8 中的重载属性,您可以简单地保存旧的 get/set 对并在新的属性描述符中使用它。摘自 MSDN:

var innerHTMLdescriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
Object.defineProperty(Element.prototype, 'innerHTML',
  { set: function(htmlVal) {
      var safeHTML = toStaticHTML(htmlVal);
      innerHTMLdescriptor.set.call(this, safeHTML);
    }
});

然而,Chrome 似乎并非如此,其中 getOwnPropertyDescriptor 返回 innerHTML 的未定义。在这种情况下,我如何访问底层属性?

附加问题:如何确保将来创建的所有对象都具有这种特殊的 innerHTML 行为?是否可以使用 DOM 原型来实现此目的?看来重载函数不是我这里所需要的。也许可以重载 DOM 构造函数并添加调用 __defineGetter__/defineProperty 但看起来对构造函数的支持并不常见,所以我想知道是否有任何替代方案。

I am trying to define a custom setter for the innerHTML property. Unfortunately, i am unable to access the underlying property after i define the setter function:

$('body')[0].__defineSetter__("innerHTML",
  function (val) {
    alert("Setting to: " + val);
    this.innerHTML = val;
});

This snippet fills the call stack because the assignment calls the setter recursively.
Apparenly innerHTML is already an overloaded property in IE8 and you can simply save the older get/set pair and use it inside the new property descriptor. Taken from MSDN:

var innerHTMLdescriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
Object.defineProperty(Element.prototype, 'innerHTML',
  { set: function(htmlVal) {
      var safeHTML = toStaticHTML(htmlVal);
      innerHTMLdescriptor.set.call(this, safeHTML);
    }
});

However, this seems to be not the case for Chrome, where getOwnPropertyDescriptor returns undefined for innerHTML. In this case, how do I access the underlying property?

Bonus question: how do I ensure that all objects created in the future have this special innerHTML behaviour? Is it possible to use DOM prototypes for this? It seems that overloading a function is not what i need here. Perhaps it is possible to overload the DOM constructor and add a call __defineGetter__/defineProperty but it looks like support for constructors is not common so I'd like to know if there is any alternative.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梅窗月明清似水 2024-11-16 11:08:42

您所需要的只是一个单独的数据存储属性来存储实际值,就像使用 getter 和 setter 的其他语言一样。您可以使用闭包来隐藏它们。

var _innerHTML = "";

this.__defineSetter__( "innerHTML",
    function (val) {
        alert("Setting to: " + val);
        _innerHTML = val;
    } );

this.__defineGetter__( "innerHTML",
    function () {
        return _innerHTML;
    } );

但是,我发现在现有 DOM 属性上使用 getter 和 setter 通常不起作用,因为这些属性在内部进行了特殊处理。例如,它不适用于文本输入的 value 属性。我希望 innerHTML 也会有同样的情况。

All you need is a separate datastore property to store the actual value, much like with other languages that use getters and setters. You can use closures to make them hidden.

var _innerHTML = "";

this.__defineSetter__( "innerHTML",
    function (val) {
        alert("Setting to: " + val);
        _innerHTML = val;
    } );

this.__defineGetter__( "innerHTML",
    function () {
        return _innerHTML;
    } );

However, I've found that using getters and setters on existing DOM properties often simply won't work, due to the special handling of these properties internally. For example, it won't work with the value property of a text input. I'd expect innerHTML to be in the same boat.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文