admin管理员组文章数量:1296908
I'd like to subscribe for all changes of value
property in all inputs using custom setter:
Object.defineProperty(HTMLInputElement.prototype, 'value', {
set: function(newValue) {
// do some logic here
// WHAT PUT HERE to call "super setter"?
}
});
If I use this.value = newValue;
I'm getting Maximum call stack size exceeded
which is quite right but...
Nevermind. What should I call to change value
in correct way? Here is
JSFIDDLE with more detailed explanation.
I'd like to subscribe for all changes of value
property in all inputs using custom setter:
Object.defineProperty(HTMLInputElement.prototype, 'value', {
set: function(newValue) {
// do some logic here
// WHAT PUT HERE to call "super setter"?
}
});
If I use this.value = newValue;
I'm getting Maximum call stack size exceeded
which is quite right but...
Nevermind. What should I call to change value
in correct way? Here is
JSFIDDLE with more detailed explanation.
- My answer to this question (which is currently the accepted answer) was incorrect. I suggest changing the accepted answer to this one. If you do, please ping me so I can delete my answer. Happy coding! – T.J. Crowder Commented Nov 8, 2022 at 8:15
5 Answers
Reset to default 8Yes, this can be achieved using JavaScript:
(function (realHTMLInputElement) {
Object.defineProperty(HTMLInputElement.prototype, 'value', {
set: function (value) {
// Do some logic here
return realHTMLInputElement.set.call(this, value);
},
});
}(Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')));
We use a IIFE to pass in the original definition for value
and then call the original set function from within our new definition.
If you bine that with a capture input
event handler on document
,¹ you get notified of all changes, whether via code (through the above) or by the user.
function yourCustomLogic(input, value) {
console.log(`${input.id ? "Input #" + input.id : "An input"} set to "${value}"`);
}
// Catch programmatic changes
(function (realHTMLInputElement) {
Object.defineProperty(HTMLInputElement.prototype, "value", {
set: function (value) {
// Do some logic here
yourCustomLogic(this, value);
return realHTMLInputElement.set.call(this, value);
},
});
})(Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value"));
// Catch end-user changes
document.addEventListener(
"input",
(event) => {
if (event.target.tagName === "INPUT") {
yourCustomLogic(event.target, event.target.value);
}
},
true // Capture handler
);
document.getElementById("example").value = "Updated by code.";
<input type="text" id="example">
The reason for using a capture phase handler (rather than bubbling phase) is twofold:
Officially,
input
doesn't bubble, although most (all?) current browsers bubble it despite what the spec saysIt prevents event handlers that stop propagation from stopping the event before it gets to
document
This worked for me. Define the value property for specific instance of HTMLInputElement, so you can use parent's value property.
// A specific instance of HTMLInputElement
var txt = document.getElementById('txtInputTagId');
// define value property for your input instance
Object.defineProperty(txt, 'value', {
set: function(newValue) {
var valueProp = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
valueProp.set.call(txt, newValue);
// Do some logic here
console.log('setted');
}
});
This answer was incorrect. Please see my update to this answer, which captures changes both via code and via user input.
cristian.d solution worked, but it needs also getter to be set:
function logOnInputChange(obj) {
var valueProp = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
// define value property for your input instance
Object.defineProperty(obj, 'value', {
set: function(newValue) {
console.debug(this,'value',this.value,'=>',newValue);
console.trace();
valueProp.set.call(this, newValue);
},
get : valueProp.get,
});
}
this is to show how it is used:
<input id=i1 value="init value" type=text />
and onload handler:
var inp;
window.onload = function () {
inp = document.getElementById('i1');
inp.value = "init value set by onload";
console.log('input value:',inp.value);
logOnInputChange(inp);
inp.value = "hello!";
console.log('input value:',inp.value);
};
just added following code
return this.defaultValue = newValue;
https://developer.mozilla/en-US/docs/Web/API/HTMLInputElement
本文标签: javascriptSetter for HTMLInputElementvalueStack Overflow
版权声明:本文标题:javascript - Setter for HTMLInputElement.value - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741600118a2387649.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论