You can't get an event notification if code you don't control changes the selected value in the select
box. You're left with the unpalatable option of polling via setInterval
or a chained series of setTimeout
.
I checked, and even a MutationObserver
doesn't help — which isn't surprising as changing the selected item isn't mutating the DOM, but I was hoping anyway.
Polling it every 50ms or so shouldn't have any significant performance implications.
Here's a polling example, modify the interval as appropriate:
(function() {
var s = $("#s"),
lastValue = s.val();
setInterval(function() {
var value = s.val();
if (value !== lastValue) {
lastValue = value;
snippet.log("The value changed to: " + value);
}
}, 50);
})();
snippet.log("Changing the value in a second...");
setTimeout(function() {
snippet.log("Changing value now");
$("#s").val("2");
snippet.log("Done changing value");
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id="s">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Re your comment to Amit:
knockout.js does it with observables somehow
No, it doesn't, it relies on your only modifying the select's value via the select box (which fires an event) or via KO:
var vm = {
sval: ko.observable('one')
};
vm.sval.subscribe(function(newValue) {
snippet.log("New value: " + newValue);
});
ko.applyBindings(vm, document.body);
snippet.log("sval is " + vm.sval() + ", changing value in select in one second");
setTimeout(function() {
document.getElementById("s").selectedIndex = 1;
snippet.log("Changed select, but sval is still " + vm.sval());
}, 1000);
<select id="s" data-bind="value: sval, options: ['one', 'two', 'three']"></select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>