Is there a standard way of catching all changes to the value of an HTML input element, despite whether it's changed by user input or changed programmatically?
Considering the following code (which is purely for example purposes and not written with good coding practices, you may consider it as some pseudo-code that happens to be able to run inside some web browsers :P )
<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
<script>
window.onload = () => {
var test = document.getElementById("test");
test.onchange = () => {
console.log("OnChange Called");
console.log(test.value);
} // Called when the input element loses focus and its value changed
test.oninput = () => {
console.log("OnInput Called");
console.log(test.value);
} // Called whenever the input value changes
test.onkeyup = () => {
console.log("OnKeyUp Called");
console.log(test.value);
} // some pre-HTML5 way of getting real-time input value changes
}
</script>
</head>
<body>
<input type="text" name="test" id="test">
</body>
</html>
However none of those events will fire when the value of the input element is changed programmatically, like someone doing a
document.getElementById("test").value = "Hello there!!";
To catch the value that's changed programmatically, usually one of two things can be done in the old days:
1) Tell the coders to fire the onchange event manually each time they change the input value programmatically, something like
document.getElementById("test").value = "Hello there!!";
document.getElementById("test").onchange();
However for this project at hand the client won't accept this kind of solution since they have many contractors/sub-contractors that come and go and I guess they just don't trust their contractors to follow this kind of rules strictly, and more importantly, they have a working solution from one of their previous contracts which is the second old way of doing things
2) set a timer that checks the input element value periodically and calls a function whenever it's changed, something like this
var pre_value = test.value;
setInterval(() => {
if (test.value !== pre_value) {
console.log("Value changed");
console.log(test.value);
pre_value = test.value;
}
}, 200); // checks the value every 200ms and see if it's changed
This looks like some dinosaur from way back the jQuery v1.6 era, which is quite bad for all sorts of reasons IMHO, but somehow works for the client's requirements.
Now we are in 2019 and I'm wondering if there are some modern way to replace the above kind of code? The JavaScript setter/getter seems promising, but when I tried the following code, it just breaks the HTML input element
Object.defineProperty(test, "value", {
set: v => {
this.value = v;
console.log("Setter called");
console.log(test.value);
},
get: ()=> {
console.log("Getter called");
return this.value;
}
});
The setter function will be called when the test.value is programmatically assigned, but the input element on the HTML page will somehow be broken.
So any idea on how to catch all changes to the value of an HTML input element and call the handler function other than the ancient "use a polling timer" method?
NOTICE: Take note that all the code here are just for example purposes and should not be used in real systems, where it's better to use the addEventListener/attachEvent/dispatchEvent/fireEvent etc. methods