如何附加在以编程方式更改值时触发的 JavaScript 事件处理程序
How to attach a JavaScript event handler that gets triggered when the value is changed programmatically
我有 'Title' 下拉菜单,选择 "Dr" 会触发 'Gender' 下拉菜单出现。在页面准备就绪时,我将事件处理程序附加到更改事件,但是页面上有某种机制(我无法控制)以编程方式更改下拉列表中的值但不会触发 change()
事件。
Manually invoking .change()
设置值后不是一个选项。
如何附加一个 JavaScript 事件处理程序,它在值以编程方式更改时触发,而不是仅在通过 select
的 UI 更改时触发?
如果您无法控制的代码更改了 select
框中的 selected 值,您将无法收到事件通知。您只剩下通过 setInterval
或一系列 setTimeout
.
进行轮询的令人不快的选择
我检查了一下,即使是 MutationObserver
也没有帮助——这并不奇怪,因为更改 selected 项目不会改变 DOM,但我无论如何希望。
每 50 毫秒左右轮询一次应该不会对性能产生任何重大影响。
这里以轮询为例,适当修改间隔:
(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>
将您的评论转给 Amit:
knockout.js does it with observables somehow
不,它不是,它依赖于您仅通过 select 框(触发事件)或通过 KO:
修改 select 的值
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>
这是@T.JCrowder 对答案的修改,适用于那些需要在第一次下拉选项更改时触发 .change()
然后自行关闭的版本的人。
(function () {
var selector = "[id='Title']";
var lastValue = $(selector).val();
var timer = setInterval(function () {
var value = $(selector).val();
if (value !== lastValue) {
lastValue = value;
$(selector).change();
clearInterval(timer);
}
}, 500);
})();
我有 'Title' 下拉菜单,选择 "Dr" 会触发 'Gender' 下拉菜单出现。在页面准备就绪时,我将事件处理程序附加到更改事件,但是页面上有某种机制(我无法控制)以编程方式更改下拉列表中的值但不会触发 change()
事件。
Manually invoking .change()
设置值后不是一个选项。
如何附加一个 JavaScript 事件处理程序,它在值以编程方式更改时触发,而不是仅在通过 select
的 UI 更改时触发?
如果您无法控制的代码更改了 select
框中的 selected 值,您将无法收到事件通知。您只剩下通过 setInterval
或一系列 setTimeout
.
我检查了一下,即使是 MutationObserver
也没有帮助——这并不奇怪,因为更改 selected 项目不会改变 DOM,但我无论如何希望。
每 50 毫秒左右轮询一次应该不会对性能产生任何重大影响。
这里以轮询为例,适当修改间隔:
(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>
将您的评论转给 Amit:
knockout.js does it with observables somehow
不,它不是,它依赖于您仅通过 select 框(触发事件)或通过 KO:
修改 select 的值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>
这是@T.JCrowder 对答案的修改,适用于那些需要在第一次下拉选项更改时触发 .change()
然后自行关闭的版本的人。
(function () {
var selector = "[id='Title']";
var lastValue = $(selector).val();
var timer = setInterval(function () {
var value = $(selector).val();
if (value !== lastValue) {
lastValue = value;
$(selector).change();
clearInterval(timer);
}
}, 500);
})();