我知道,要注册我们自己的elementTypes, 我们用
Object.defineProperties(ElementPrototype,{
get: function(){
},
set: function(newVal) {
}
});
现在它适用于value属性,只要我没有附加onchange监听器,但是如果我这样做,这个setter永远不会被调用,我能想到的一个原因是这个onchange内部覆盖了我的setter并放置了自己的setter ,这导致我的二传手永远不会被召唤。这样做
elem.value = "newvalue";
不会触发我的setter功能。所以
首先,我的结论是正确的吗?
2什么是解决方法?
编辑: - 假设ElementType是我自己的元素副本,我不是要修改现有的标签元素,
答案 0 :(得分:1)
主机对象只需要对ECMAScript功能提供最低限度的支持。请参阅ECMAScript §4:“ ...主机对象,其描述和行为超出了本规范的范围,除非表明它们可能提供可访问的某些属性以及可从ECMAScript程序调用的某些功能”。
例如,浏览器不需要支持DOM对象的原型继承(尽管大多数都支持)。在ECMA-262的各个部分如何对宿主物体进行特殊处理也很明显,例如:对于typeof operator。
底线是主机对象不需要支持ECMAScript的所有功能,您应该只期望它们支持它们通过已发布的文档提供的功能。
更一般地说,有一个原则是你不应该混淆你不拥有的物体。也就是说,除非您具有明确的权限,否则不要向宿主,内置或其他脚本对象添加属性和行为。主要原因是:
主机对象可以在不同的主机中以不同的方式实现,因此在一个主机中“工作”的东西可能不会(或抛出错误)在另一个主机中。
脚本添加的功能可能会添加到主机环境的更高版本中,从而导致无法轻松解决的冲突(例如,在ECMAScript ed 3中引入的jQuery的每个方法)规范,具有不同的名称,并采用与ES5 forEach 方法不同的顺序参数,稍后介绍)
如果通过第三方脚本修改主机或内置对象变为 de rigor ,则功能测试将变得非常困难。测试一个特征很容易,但不容易分辨出你正在处理的特定功能的哪个实现(例如顺序和参数数量),这进一步增加了复杂性。
修改其他本机对象有时可以,例如如果你有一个插件,它可能有一个你可以修改的设置或参数对象,但你不应该替换整个方法。
如果要扩展主机对象的行为,请创建一个代理并使用它。
答案 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');
});