[英]Detect property changes on elements via their attributes - JavaScript
I was wondering if it was possible to detect property changes made to elements via their attributes. 我想知道是否有可能通过其属性检测对元素所做的属性更改。
For example, we can add inheritable properties and methods to elements by working with the HTMLElement.prototype
object and its inherited prototypes eg: 例如,我们可以通过使用
HTMLElement.prototype
对象及其继承的原型向元素添加可继承的属性和方法,例如:
// Add our global property
HTMLElement.prototype.sandwich = 'double-decker variety';
// Get the <body> element
let body = document.body;
body.sandwich // => 'double-decker variety'
So, is there a way to extend this to element attributes? 那么,有没有办法将其扩展到元素属性?
Or should I be working on the Attr.prototype
object instead? 或者我应该使用
Attr.prototype
对象吗?
// Add our global property
Object.defineProperty(HTMLElement.prototype, 'burger', {
...,
set: function changeBurger(newValue) {
// Our response
console.log(`Response: You changed our '${oldValue}' burger to a '${newValue}'`)
}
});
// Get the <body> element
let body = document.body;
// Response: You changed our 'king-sized' burger to a 'family pack'
body.burger = 'family pack';
// Response: You changed our 'family pack' burger to a 'kids delight'
body.setAttribute('burger', 'kids delight');
The example above should also be applicable to elements that are not in the DOM or current document ie: Objects intialized from the HTMLElement
constructor. 上面的示例也应该适用于不在DOM或当前文档中的元素,即:从
HTMLElement
构造函数初始化的对象。
Sorry if the question seems a bit vague and I do hope the examples I've given out are able to clarify the question topic. 对不起,如果问题看起来有点模糊,我希望我给出的例子能够澄清问题主题。
Thanks to anyone willing to take the time to answer. 感谢愿意花时间回答的人。
The right way to extend HTMLElement is using CustomElements , There is a lifecycle callback named attributeChangedCallback
. 扩展HTMLElement 的正确方法是使用CustomElements ,有一个名为
attributeChangedCallback
的生命周期回调。
Then, when setting an attribute using objectName.setAttribute('attrName','attrValue') this function is invoked. 然后,当使用objectName.setAttribute('attrName','attrValue')设置属性时,将调用此函数。
You can also use MutationObserver with config={attributes:true}
(be careful using it, a wrong implementation will severely damage performance). 您也可以将 MutationObserver与
config={attributes:true}
一起使用(小心使用它,错误的实现会严重损害性能)。
Another way of achieving this, is to write a function which read all attribute and convert them to setter/getters... something like this 实现这一目标的另一种方法是编写一个函数来读取所有属性并将它们转换为setter / getters ......就像这样
class WatchableObject{ constructor(){ this.handler = ()=>{}; } watch(handler){ if(!this.beingWatched()) { delete this.handler; let properties = Object.getOwnPropertyNames(this); properties.forEach((prop) => { if (this.hasOwnProperty(prop)) { Object.defineProperty(this, prop, { set: (newValue) => { let oldValue = this["_" + prop]; this["_" + prop] = newValue; this.handler.call(this,oldValue,newValue); }, get: () => { return this["_" + prop]; } }); } }); } this.handler = handler; } unwatch(){ this.watch(()=>{}); } beingWatched(){ return (this.handler.toString() != "()=>{}"); } } let a = new WatchableObject(); ab = "hello"; ac = "daniel"; a.watch(()=>{alert("a change has been made.")}); ab = "bye"; a.unwatch(); ab = "hello again";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.