覆盖innerHTML属性访问

时间:2015-02-02 15:28:26

标签: javascript dom

我正在寻找一种在DOM元素上启用setter方法的方法。所以基本上我想拦截对这个特定属性的所有调用。我试过在特定的DOM元素上定义get / set属性,但它没有多大帮助:

(function(object, property) {
    var __value;
    Object.defineProperty(object, property, {
        // Create a new getter for the property
        get: function () {
            console.log('access gettter');
            return __value;
        },
        // Create a new setter for the property
        set: function (val) {
            __value = val;
        }
    })
})(document.body, 'innerHTML');

这样做的结果是:

document.body.innerHTML = 'testValue';

是:

document.body.innerHTML
 access gettter
"testValue"

但是这对页面没有任何影响,我的意思是页面的主体没有改变,只返回闭包内的私有变量的值。有没有办法在JavaScript中实现这个功能?

1 个答案:

答案 0 :(得分:4)

是的,这可以做到。以下是工作形式的代码:

(function(object, property) {
    var ownObjectProto = Object.getPrototypeOf(object);
    // exit if bad property
    if (!object[property]) {
        console.error(property + " is not a property of " + object.toString());
        return;
    }

    while (!Object.getOwnPropertyDescriptor(ownObjectProto, property)) {
        ownObjectProto = Object.getPrototypeOf(ownObjectProto);
    }

    var ownProperty = Object.getOwnPropertyDescriptor(ownObjectProto, property);
    Object.defineProperty(object, property, {
        // Create a new getter for the property
        get: function () {
            console.log('access gettter');
            return ownProperty.get.call(this);
        },
        // Create a new setter for the property
        set: function (val) {
            return ownProperty.set.call(this, val);
        }
    })
})(document.body, 'innerHTML');

你实际上并没有在这里替换集合和获取函数,但是你可以扩充它们。但是说真的,你不应该使用它,除非你非常特别需要它,你真的知道你在做什么。如果使用不当,您可能会破坏页面上插件的功能或任何其他意外后果。

我在这里也有一个操场小提琴:jsfiddle