onchange事件内部是否监听元素访问器的setter?

时间:2015-06-20 19:56:37

标签: javascript polymer web-component x-tag

我知道,要注册我们自己的elementTypes, 我们用

Object.defineProperties(ElementPrototype,{
 get: function(){

 },
 set: function(newVal) {

 }
});

现在它适用于value属性,只要我没有附加onchange监听器,但是如果我这样做,这个setter永远不会被调用,我能想到的一个原因是这个onchange内部覆盖了我的setter并放置了自己的setter ,这导致我的二传手永远不会被召唤。这样做

elem.value = "newvalue";

不会触发我的setter功能。所以

首先,我的结论是正确的吗?

2什么是解决方法?

编辑: - 假设ElementType是我自己的元素副本,我不是要修改现有的标签元素,

2 个答案:

答案 0 :(得分:1)

主机对象只需要对ECMAScript功能提供最低限度的支持。请参阅ECMAScript §4:“ ...主机对象,其描述和行为超出了本规范的范围,除非表明它们可能提供可访问的某些属性以及可从ECMAScript程序调用的某些功能”。

例如,浏览器不需要支持DOM对象的原型继承(尽管大多数都支持)。在ECMA-262的各个部分如何对宿主物体进行特殊处理也很明显,例如:对于typeof operator

底线是主机对象不需要支持ECMAScript的所有功能,您应该只期望它们支持它们通过已发布的文档提供的功能。

更一般地说,有一个原则是你不应该混淆你不拥有的物体。也就是说,除非您具有明确的权限,否则不要向宿主,内置或其他脚本对象添加属性和行为。主要原因是:

  1. 主机对象可以在不同的主机中以不同的方式实现,因此在一个主机中“工作”的东西可能不会(或抛出错误)在另一个主机中。

  2. 脚本添加的功能可能会添加到主机环境的更高版本中,从而导致无法轻松解决的冲突(例如,在ECMAScript ed 3中引入的jQuery的每个方法)规范,具有不同的名称,并采用与ES5 forEach 方法不同的顺序参数,稍后介绍)

  3. 如果通过第三方脚本修改主机或内置对象变为 de rigor ,则功能测试将变得非常困难。测试一个特征很容易,但不容易分辨出你正在处理的特定功能的哪个实现(例如顺序和参数数量),这进一步增加了复杂性。

  4. 修改其他本机对象有时可以,例如如果你有一个插件,它可能有一个你可以修改的设置或参数对象,但你不应该替换整个方法。

    如果要扩展主机对象的行为,请创建一个代理并使用它。

答案 1 :(得分:0)

我可能错了,但是您想要做的就是在更改value属性时触发自定义元素上的更改事件。这就是你如何做到的。

定义组件

xtag.register('my-element', {
    accessors: {
        value: {
            attribute: {},
            get: function () {
                return this._value;
            },
            set: function (v) {
                if (v === this._value) return; // unchanged

                var change = { from: this._value, to: v }; // optional

                this._value = v; // set new value

                xtag.fireEvent(this, 'change', { // event
                    detail: change,
                    bubbles: true,
                    cancelable: true
                });
            }
        }
    }
});

HTML

<my-element value="2"></my-element>

试一试

var el = document.querySelector('my-element');

// add event listener

el.addEventListener('change', function (e) {
    console.log('value changed from %s to %s', e.detail.from, e.detail.to);
});

// change the value

el.value = 4; 

// this will cause the 'change' event to fire
// the listener will output this to the console:

// "value changed from 2 to 4"

因为我们已将change事件的bubbles选项设置为true,我们也可以使用事件委派。

xtag.addEvent(document.body, 'change:delegate(my-element)', function (e) {
    console.log('Value of <my-element> somewhere in <body> changed');
});