在JavaScript中访问__defineGetter __ / __ defineSetter__隐藏的属性

时间:2011-05-23 22:40:10

标签: javascript dom prototypejs innerhtml getter-setter

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

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

此代码段填充调用堆栈,因为赋值会递归调用setter。 Apparenly 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,但看起来对构造函数的支持并不常见,所以我想知道是否有其他选择。

1 个答案:

答案 0 :(得分:1)

您需要的只是一个单独的数据存储区属性来存储实际值,就像使用其他使用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的{​​{1}}属性。我希望input能在同一条船上。