我有一个输入表单,它允许我从多个选项中进行选择,并在用户更改选择时执行一些操作。例如,
<select onChange="javascript:doSomething();">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
现在,doSomething()只在选择改变时被触发。
我想在用户选择任何选项时触发doSomething(),可能是相同的选项。
我已经尝试使用“onClick”处理程序,但在用户开始选择过程之前被触发。
那么,是否有一种方法在用户每次选择时触发一个函数?
更新:
Darryl提出的答案似乎有效,但并不总是有效。有时,当用户单击下拉菜单时,甚至在用户完成选择过程之前,事件就会被触发!
这可能不能直接回答你的问题,但这个问题可以通过简单的设计调整来解决。我知道这可能不是100%适用于所有用例,但我强烈建议您重新考虑您的应用程序的用户流程,以及以下设计建议是否可以实现。
我决定做一些简单的事情,而不是黑客onChange()使用其他事件的替代方案,这并不是真正意义上的目的(模糊,点击等)。
我的解决方法是:
只需预先挂起一个没有任何值的占位符选项标记,如select。
所以,不要只使用下面的结构,这需要一些hack-y替代方案:
<select>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
考虑使用这个:
<select>
<option selected="selected">Select...</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
因此,通过这种方式,您的代码更加简化,并且每当用户决定选择默认值以外的内容时,onChange将按预期工作。如果您不希望他们再次选择第一个选项,甚至可以将disabled属性添加到第一个选项,并强制他们从选项中选择一些内容,从而触发onChange()触发。
At the time of this answer, I'm writing a complex Vue application and I found that this design choice has simplified my code a lot. I spent hours on this problem before I settled down with this solution and I didn't have to re-write a lot of my code. However, if I went with the hacky alternatives, I would have needed to account for the edge cases, to prevent double firing of ajax requests, etc. This also doesn't mess up the default browser behaviour as a nice bonus (tested on mobile browsers as well).
有时候,你只需要退一步,从大局出发,寻找最简单的解决方案。
这是我的解,和这里的解完全不同。它使用鼠标位置来确定是否单击了某个选项,而不是单击选择框打开下拉菜单。它利用事件。屏幕y位置,因为这是唯一可靠的跨浏览器变量。必须首先附加悬停事件,以便在单击事件之前计算出控件相对于屏幕的位置。
var select = $("select");
var screenDif = 0;
select.bind("hover", function (e) {
screenDif = e.screenY - e.clientY;
});
select.bind("click", function (e) {
var element = $(e.target);
var eventHorizon = screenDif + element.offset().top + element.height() - $(window).scrollTop();
if (e.screenY > eventHorizon)
alert("option clicked");
});
这是我的jsFiddle
http://jsfiddle.net/sU7EV/4/
为了在用户每次选择某个东西(甚至是相同的选项)时正确地触发一个事件,您只需要欺骗选择框。
如其他人所说,在focus上指定一个负selectedIndex来强制更改事件。虽然这确实允许你欺骗选择框,但只要它仍然有焦点,它就不会起作用。简单的解决方法是强制选择框模糊,如下所示。
JS / HTML标准:
<select onchange="myCallback();" onfocus="this.selectedIndex=-1;this.blur();">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
jQuery插件:
<select>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<script type="text/javascript">
$.fn.alwaysChange = function(callback) {
return this.each(function(){
var elem = this;
var $this = $(this);
$this.change(function(){
if(callback) callback($this.val());
}).focus(function(){
elem.selectedIndex = -1;
elem.blur();
});
});
}
$('select').alwaysChange(function(val){
// Optional change event callback,
// shorthand for $('select').alwaysChange().change(function(){});
});
</script>
你可以在这里看到一个工作演示。