Hope you are all doing well! I Have a small question that maybe a lot of you have already thought about... Is there any solution to listen for native HTMLElement properties (not attributes) updates? I explain:
<input type="text" value="hello" />
I would like to be notified when something in the codebase does this:
myInput.value = 'world';
I can know that the attribute itself has been updated with MutationObserver or attributeChangedCallback function but not when the codebase assign the value through the property directly...
I have tried to do something like this:
Object.defineProperty(myInput, 'value', {
set : (newValue) => {
console.log('value property updated');
// I can't do something like this.value = newValue
// cause it will trigger an infinite loop...
}
});
The issue with that is that now the default behavior of the myInput.value = 'world'; does not work anymore and the value is not actually changed inside the field...
I would like to apply this concept to others properties as well like "min", "max", "placeholder", etc...
In summary, I just want to observe some properties without changing any of their default behaviors...
Any idea?
Thanks in advance guys!
Cheers!
You need to get native property descriptor first. You can get one from element's prototype.
const nativeValueDesc = Object.getOwnPropertyDescriptor(input.constructor.prototype, 'value');
Then you can use it in your setter and getter to reflect native behavior
Object.defineProperty(input,'value',{
set(val){
console.log('value property updated', val);
// Continue with native behavior
return nativeValueDesc.set.call(this, val);
}
/* ... */
});
Live example at http://jsbin.com/juqili/6/edit?html,js,console,output
To be able to observe already observed element, or just an element with already provided own descriptor, you can do
const nativeValueDesc = Object.getOwnPropertyDescriptor(input, 'value') || Object.getOwnPropertyDescriptor(input.constructor.prototype, 'value');