【问题标题】:Object.defineProperty behaves in safariObject.defineProperty 在 safari 中的行为
【发布时间】:2017-01-01 17:29:15
【问题描述】:

我想劫持(挂钩)Element.prototypeNode.prototypeinnerHTMLnodeValue 属性,以便我可以在设置之前做一些事情并采取行动

innerHTML案例:

var ep = Element.prototype;

// {enumerable: true, configurable: true, set , get} // Ch/FF/Op
// {enumerable: true, configurable: false, get: undefined, set: undefined} // Safari
var epDescriptor = Object.getOwnPropertyDescriptor(ep, 'innerHTML');

var epOlderSetter = epDescriptor.set;

/*
  Safari throw:
  TypeError: Attempting to change the getter of an unconfigurable property.
*/
Object.defineProperty(ep, 'innerHTML', {

   set: function(html){

     alert('I want to do something befroe ...');

     epOlderSetter.call(this, html);

   }
 })

是的。我知道原因。因为 safari 中的 configurablefalse 所以 safari 抛出错误。

nodeValue 案例:

var np = Node.prototype;

// {enumerable: true, configurable: true ,get , set} // Ch/FF/Op
// {enumerable: true, configurable: true ,undefined , undefined} // Safari
var npDescriptor = Object.getOwnPropertyDescriptor(np, 'nodeValue');

var npOlderSetter = npDescriptor.set; // undefined 


Object.defineProperty(np, 'nodeValue', {

   set: function(text){

     alert('I want to do something befroe ...');

     // because npOlderSetter is undefined , so i can't do this.
     // but how can i set the nodeValue to the node ?
     // npOlderSetter.call(this, text);

   }
 })

我想知道是否有解决方法或黑魔法来实现我的两个(或一个)目标?

感谢您的建议

【问题讨论】:

    标签: javascript html safari cross-browser frontend


    【解决方案1】:

    所以问题是:

    1. 您不能在 Safari 上劫持 innerHTML,因为 Safari 已将其设为不可配置属性(对他们有好处!),并且

    2. 您不能在 Safari 上劫持 nodeValue,因为当您使用 getOwnPropertyDescriptor 时它不会向您报告访问器函数,因此您不能将它们藏起来并从覆盖的版本中使用它们

    鉴于这些限制:不,您无法在 Safari 上的 Element.prototype 级别执行任何操作来接管这两个属性。

    我会强烈敦促您不要这样做,即使是在允许您使用的主机(如 Chrome)上,至少不要出于在受控环境中调试以外的任何目的。大多数人会告诉你,甚至不要扩充主机提供的对象的原型,更不用说尝试接管它们现有的属性了。

    【讨论】:

    • 谢谢。但是MVVM 框架如何实现属性监视(两种数据绑定方式)?是的,我们可以劫持本机对象的属性并监听主机对象的事件,而不是劫持主机对象的属性,但是如果我通过 javascript 代码而不是用户事件更改主机(dom)对象的属性,我怎么能知道数据更改?
    • @pod4g:我使用的 MVVM 框架与您描述的完全一样:它们使用主机事件系统。如果将模型绑定到 DOM 元素,然后使用 JavaScript 直接修改 DOM 元素的值,他们将看不到更改。 Example using KOexample using Angular 1。一些框架会进行脏检查(保留旧值,然后与元素的当前值进行比较)。根据您要监控的内容,您可能还可以使用 MutationObserver(但不能用于输入的值)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2023-03-26
    相关资源
    最近更新 更多