![](/img/trans.png)
[英]Html addEventListener select - onchange or onselect
[英]Is there an onSelect event or equivalent for HTML <select>?
我有一个输入表单,可让我从多个选项中进行选择,并在用户更改选择时执行某些操作。 例如,
<select onChange="javascript:doSomething();">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
现在, doSomething()
仅在选择更改时触发。
我想在用户选择任何选项时触发doSomething()
,可能再次选择相同的选项。
我曾尝试使用“onClick”处理程序,但它在用户开始选择过程之前被触发。
那么,有没有办法在用户每次选择时触发一个功能?
更新:
Darryl 提出的答案似乎有效,但并不能始终如一地工作。 有时,一旦用户单击下拉菜单,甚至在用户完成选择过程之前,事件就会被触发!
这是最简单的方法:
<select name="ab" onchange="if (this.selectedIndex) doSomething();">
<option value="-1">--</option>
<option value="1">option 1</option>
<option value="2">option 2</option>
<option value="3">option 3</option>
</select>
在选择集中时,可与鼠标选择和键盘上/下键一起使用。
我需要完全相同的东西。 这对我有用:
<select onchange="doSomething();" onfocus="this.selectedIndex = -1;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
支持这个:
当用户选择任何选项时,可能再次选择相同的选项
几个月前我在创建设计时遇到了同样的问题。 我找到的解决方案是在您正在使用的元素上结合使用.live("change", function())
和.blur()
。
如果您希望在用户单击而不是更改时让它执行某些操作,只需将change
替换为click
。
我为下拉列表分配了一个 ID、 selected
并使用了以下内容:
$(function () {
$("#selected").live("change", function () {
// do whatever you need to do
// you want the element to lose focus immediately
// this is key to get this working.
$('#selected').blur();
});
});
我看到这个没有选定的答案,所以我想我会给出我的意见。 这对我来说效果很好,所以希望其他人在遇到困难时可以使用此代码。
编辑:使用on
选择器而不是.live
。 参见jQuery .on()
只是一个想法,但是否可以在每个<option>
元素上放置一个 onclick?
<select>
<option onclick="doSomething(this);">A</option>
<option onclick="doSomething(this);">B</option>
<option onclick="doSomething(this);">C</option>
</select>
另一种选择可能是在选择上使用 onblur。 这将在用户点击离开选择的任何时候触发。 此时,您可以确定选择了哪个选项。 为了在正确的时间触发此事件,选项的 onclick 可能会模糊该字段(使其他内容处于活动状态或只是 jQuery 中的 .blur())。
onclick 方法并不完全糟糕,但如前所述,当鼠标单击未更改值时,它不会被触发。
然而,可以在 onchange 事件中触发 onclick 事件。
<select onchange="{doSomething(...);if(this.options[this.selectedIndex].onclick != null){this.options[this.selectedIndex].onclick(this);}}">
<option onclick="doSomethingElse(...);" value="A">A</option>
<option onclick="doSomethingElse(..);" value="B">B</option>
<option onclick="doSomethingElse(..);" value="Foo">C</option>
</select>
如果你真的需要它像这样工作,我会这样做(以确保它可以通过键盘和鼠标工作)
不幸的是,onclick 将运行多次(例如在打开选择时...和在选择/关闭时)并且当没有任何变化时可能会触发 onkeypress...
<script>
function setInitial(obj){
obj._initValue = obj.value;
}
function doSomething(obj){
//if you want to verify a change took place...
if(obj._initValue == obj.value){
//do nothing, no actual change occurred...
//or in your case if you want to make a minor update
doMinorUpdate();
} else {
//change happened
getNewData(obj.value);
}
}
</script>
<select onfocus="setInitial(this);" onclick="doSomething();" onkeypress="doSomething();">
...
</select>
要在每次用户选择某些东西(即使是相同的选项)时正确触发事件,您只需要欺骗选择框。
就像其他人所说的那样,在焦点上指定一个负的selectedIndex
以强制更改事件。 虽然这确实允许您欺骗选择框,但只要它仍然具有焦点,它就不会工作。 简单的解决方法是强制选择框模糊,如下所示。
<select onchange="myCallback();" onfocus="this.selectedIndex=-1;this.blur();">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<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>
你可以在这里看到一个工作演示。
将扩展 jitbit 的答案。 当您单击下拉菜单然后单击下拉菜单而不选择任何内容时,我发现这很奇怪。 最终得到了一些类似的东西:
var lastSelectedOption = null; DDChange = function(Dd) { //Blur after change so that clicking again without //losing focus re-triggers onfocus. Dd.blur(); //The rest is whatever you want in the change. var tcs = $("span.on_change_times"); tcs.html(+tcs.html() + 1); $("span.selected_index").html(Dd.prop("selectedIndex")); return false; }; DDFocus = function(Dd) { lastSelectedOption = Dd.prop("selectedIndex"); Dd.prop("selectedIndex", -1); $("span.selected_index").html(Dd.prop("selectedIndex")); return false; }; //On blur, set it back to the value before they clicked //away without selecting an option. // //This is what is typically weird for the user since they //might click on the dropdown to look at other options, //realize they didn't what to change anything, and //click off the dropdown. DDBlur = function(Dd) { if (Dd.prop("selectedIndex") === -1) Dd.prop("selectedIndex", lastSelectedOption); $("span.selected_index").html(Dd.prop("selectedIndex")); return false; };
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <select id="Dd" onchange="DDChange($(this));" onfocus="DDFocus($(this));" onblur="DDBlur($(this));"> <option>1</option> <option>2</option> </select> <br/> <br/>Selected index: <span class="selected_index"></span> <br/>Times onchange triggered: <span class="on_change_times">0</span>
这对用户来说更有意义,并允许 JavaScript 在他们每次选择任何选项(包括较早的选项)时运行。
这种方法的缺点是它破坏了选项卡到下拉列表并使用箭头键选择值的能力。 这对我来说是可以接受的,因为所有用户一直点击所有内容,直到永恒结束。
我知道这个问题现在已经很老了,但是对于仍然遇到这个问题的任何人,我通过在我的选项标签中添加一个 onInput 事件,然后在那个被调用的函数中检索该选项输入的值,在我自己的网站上实现了这一点。
<select id='dropdown' onInput='myFunction()'> <option value='1'>1</option> <option value='2'>2</option> </select> <p>Output: </p> <span id='output'></span> <script type='text/javascript'> function myFunction() { var optionValue = document.getElementById("dropdown").value; document.getElementById("output").innerHTML = optionValue; } </script>
这可能无法直接回答您的问题,但可以通过简单的设计级别调整来解决此问题。 我知道这可能不是 100% 适用于所有用例,但我强烈建议您考虑重新考虑您的应用程序的用户流程,以及是否可以实施以下设计建议。
我决定做一些简单的事情,而不是使用其他并非真正用于此目的的事件( blur
, click
等)来破解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()
触发。
在给出这个答案的时候,我正在编写一个复杂的 Vue 应用程序,我发现这种设计选择大大简化了我的代码。 在解决这个问题之前,我花了几个小时解决这个问题,而且我不必重新编写很多代码。 但是,如果我使用 hacky 替代方案,我将需要考虑边缘情况,以防止 ajax 请求的双重触发等。这也不会破坏默认浏览器行为作为一个不错的奖励(在移动设备上测试浏览器也是如此)。
有时,您只需要退后一步,从大局考虑最简单的解决方案。
首先,您使用 onChange 作为事件处理程序,然后使用标志变量使其执行您每次进行更改时想要的功能
<select
var list = document.getElementById("list"); var flag = true ; list.onchange = function () { if(flag){ document.bgColor ="red"; flag = false; }else{ document.bgColor ="green"; flag = true; } }
<select id="list"> <option>op1</option> <option>op2</option> <option>op3</option> </select>
Add an extra option as the first, like the header of a column, which will be the default value of the dropdown button before click it and reset at the end of doSomething()
, so when choose A/B/C, the onchange event always trigs, when the selection is State
, do nothing and return. 正如许多人之前提到的, onclick
非常不稳定。 因此,我们需要做的就是制作一个与您的真实选项不同的初始按钮标签,这样 onchange 将适用于任何选项。
<select id="btnState" onchange="doSomething(this)">
<option value="State" selected="selected">State</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
function doSomething(obj)
{
var btnValue = obj.options[obj.selectedIndex].value;
if (btnValue == "State")
{
//do nothing
return;
}
// Do your thing here
// reset
obj.selectedIndex = 0;
}
选择标签(在这种情况下)的美妙之处在于它会从选项标签中获取它的值。
尝试:
<select onChange="javascript:doSomething(this.value);">
<option value="A">A</option>
<option value="B">B</option>
<option value="Foo">C</option>
</select>
为我工作得体。
实际上,当用户使用键盘更改选择控件中的选择时,onclick 事件不会触发。 您可能必须结合使用 onChange 和 onClick 来获得您正在寻找的行为。
当遇到类似问题时,我所做的是我在选择框中添加了一个“onFocus”,它附加了一个新的通用选项(“选择一个选项”或类似的东西)并将其默认为选定的选项。
所以我的目标是能够多次选择相同的值,这实际上会覆盖 onchange() 函数并将其变成有用的 onclick() 方法。
根据上面的建议,我想出了这个对我有用的方法。
<select name="ab" id="hi" onchange="if (typeof(this.selectedIndex) != undefined) {alert($('#hi').val()); this.blur();}" onfocus="this.selectedIndex = -1;">
<option value="-1">--</option>
<option value="1">option 1</option>
<option value="2">option 2</option>
<option value="3">option 3</option>
</select>
这是我的解决方案,与这里的任何其他解决方案完全不同。 它使用鼠标位置来确定是否单击了选项,而不是单击选择框以打开下拉列表。 它利用 event.screenY 位置,因为这是唯一可靠的跨浏览器变量。 必须首先附加悬停事件,以便在单击事件之前确定控件相对于屏幕的位置。
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/
你应该尝试使用option:selected
$("select option:selected").click(doSomething);
什么对我有用:
<select id='myID' onchange='doSomething();'>
<option value='0' selected> Select Option </option>
<option value='1' onclick='if (!document.getElementById("myID").onchange()) doSomething();' > A </option>
<option value='2' onclick='if (!document.getElementById("myID").onchange()) doSomething();' > B </option>
</select>
这样,onchange 会在选项更改时调用“doSomething()”,而当 onchange 事件为 false 时,onclick 会调用“doSomething()”,换句话说,当您选择相同的选项时
试试这个(当你选择选项时触发事件,不改变选项):
$("select").mouseup(function() {
var open = $(this).data("isopen");
if(open) {
alert('selected');
}
$(this).data("isopen", !open);
});
一个真正的答案是不使用选择字段(如果您在重新选择相同的答案时需要做某事。)
使用常规 div、按钮、显示/隐藏菜单创建一个下拉菜单。 链接: https ://www.w3schools.com/howto/howto_js_dropdown.asp
如果能够将事件侦听器添加到选项,则可以避免。 如果选择元素有一个 onSelect 侦听器。 如果单击选择字段并没有严重触发 mousedown、mouseup 并在 mousedown 上同时单击所有内容。
<script>
function abc(selectedguy) {
alert(selectedguy);
}
</script>
<select onchange="abc(this.selectedIndex);">
<option>option one</option>
<option>option two</option>
</select>
在这里,您返回了索引,并且在 js 代码中,您可以将此返回与一个开关或任何您想要的东西一起使用。
使用jQuery:
<select class="target">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<script>
$('.target').change(function() { doSomething(); });
</script>
尝试这个:
<select id="nameSelect" onfocus="javascript:document.getElementById('nameSelect').selectedIndex=-1;" onchange="doSomething(this);">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
请注意,IE 上的 OPTION 标签不支持事件处理程序,快速思考..我想出了这个解决方案,尝试一下并给我您的反馈:
<script>
var flag = true;
function resetIndex(selObj) {
if(flag) selObj.selectedIndex = -1;
flag = true;
}
function doSomething(selObj) {
alert(selObj.value)
flag = false;
}
</script>
<select onchange="doSomething(this)" onclick="resetIndex(this)">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
我在这里所做的实际上是重置选择索引,以便始终触发 onchange 事件,确实,当您单击时我们会丢失所选项目,如果您的列表很长可能会很烦人,但它可能会以某种方式帮助您..
很久以前,但在回答最初的问题时,这有帮助吗? 只需将onClick
放入SELECT
行。 然后将您希望每个OPTION
执行的操作放在OPTION
行中。 IE:
<SELECT name="your name" onClick>
<option value ="Kilometres" onClick="YourFunction()">Kilometres
-------
-------
</SELECT>
<select name="test[]"
onchange="if(this.selectedIndex < 1){this.options[this.selectedIndex].selected = !1}">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
我也遇到过类似的需求,最终为此编写了一个 angularjs 指令——
使用element[0].blur();
将焦点从选择标签上移开。 逻辑是在第二次点击下拉菜单时触发这种模糊。
即使用户在下拉列表中选择相同的值,也会触发as-select
。
演示 -链接
您需要在此处执行一些操作,以确保它记住旧值并触发 onchange 事件,即使再次选择了相同的选项也是如此。
你想要的第一件事是一个常规的 onChange 事件:
$("#selectbox").on("change", function(){
console.log($(this).val());
doSomething();
});
要在再次选择相同选项时触发 onChange 事件,您可以在下拉列表获得焦点时取消设置选定选项,方法是将其设置为无效值。 但是您还希望存储先前选择的值以在用户未选择任何新选项的情况下恢复它:
prev_select_option = ""; //some kind of global var
$("#selectbox").on("focus", function(){
prev_select_option = $(this).val(); //store currently selected value
$(this).val("unknown"); //set to an invalid value
});
即使选择了相同的值,上面的代码也将允许您触发 onchange。 但是,如果用户在选择框外单击,您希望恢复以前的值。 我们在 onBlur 上做:
$("#selectbox").on("blur", function(){
if ($(this).val() == null) {
//because we previously set an invalid value
//and user did not select any option
$(this).val(prev_select_option);
}
});
另一种解决方案是使用 onMouseUp 事件。 OnMouseUp 也适用于重新选择和更改选项的相同选项。
唯一的缺点。 当下拉框打开时调用代码,第二次选择时调用。 对于 AJAX 请求,请记住这一点。 如果这不会损害您的逻辑,您可以将其用作简单的内联黑客。
<select id="bla" onmouseup="console.log( document.getElementById('bla').options[document.getElementById('bla').selectedIndex].value );">
<option value="0">A</option>
<option value="1">B</option>
</select>
我发现的最佳解决方案是在您的选择元素中添加一个禁用选项作为第一个元素,以便所有其他项目都可用于响应 onchange 事件中的单击。
<select onchange="doSomething()">
<option disabled selected value> -- select an option -- </option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
当元素获得焦点时如何更改选择的值,例如(使用 jquery):
$("#locationtype").focus(function() {
$("#locationtype").val('');
});
$("#locationtype").change(function() {
if($("#locationtype").val() == 1) {
$(".bd #mapphp").addClass('show');
$("#invoerform").addClass('hide');
}
if($("#locationtype").val() == 2) {
$(".lat").val('');
$(".lon").val('');
}
});
唯一对我有用的解决方案是在“onFocus”事件上完全重置 SELECT。 这样,SELECT 总是在“onChange”事件上“改变”:
$('select').on('focus', function(ev) {
var $select = $(this);
var options = $select.html();
$select.empty();
$select.append(options);
});
$('select').on('change', function(ev) {
// Now the select element ALWAYS fires onChange
});
您可以使用 onChange: http ://www.w3schools.com/TAGS/tag_Select.asp
复制自http://www.faqs.org/docs/htmltut/forms/_SELECT_onChange.html onChange 指定当用户选择其中一个选项时运行的 JavaScript。 这意味着当用户选择一个项目时会立即启动一个操作,而不是在按下“提交”按钮时。
我发现了这个解决方案。
最初将选择元素的 selectedIndex 设置为 0
//set selected Index to 0
doSomethingOnChange(){
blah ..blah ..
set selected Index to 0
}
调用此方法 onChange 事件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.