可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have an input form that lets me select from multiple options, and do something when the user changes the selection. Eg,
<select onChange=\"javascript:doSomething();\">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Now, doSomething()
only gets triggered when the selection changes.
I want to trigger doSomething()
when the user selects any option, possibly the same one again.
I have tried using an \"onClick\" handler, but that gets triggered before the user starts the selection process.
So, is there a way to trigger a function on every select by the user?
Update:
The answer suggested by Darryl seemed to work, but it doesn\'t work consistently. Sometimes the event gets triggered as soon as user clicks the drop-down menu, even before the user has finished the selection process!
回答1:
Here is the simplest way:
<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>
Works both with mouse selection and keyboard Up/Down keys whes select is focused.
回答2:
I needed something exactly the same. This is what worked for me:
<select onchange=\"doSomething();\" onfocus=\"this.selectedIndex = -1;\">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Supports this:
when the user selects any option, possibly the same one again
回答3:
I had the same problem when I was creating a design a few months back. The solution I found was to use .live(\"change\", function())
in combination with .blur()
on the element you are using.
If you wish to have it do something when the user simply clicks, instead of changing, just replace change
with click
.
I assigned my dropdown an ID, selected
, and used the following:
$(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();
});
});
I saw this one didn\'t have a selected answer, so I figured I\'d give my input. This worked excellently for me, so hopefully someone else can use this code when they get stuck.
http://api.jquery.com/live/
Edit: Use the on
selector as opposed to .live
. See jQuery .on()
回答4:
Just an idea, but is it possible to put an onclick on each of the <option>
elements?
<select>
<option onclick=\"doSomething(this);\">A</option>
<option onclick=\"doSomething(this);\">B</option>
<option onclick=\"doSomething(this);\">C</option>
</select>
Another option could be to use onblur on the select. This will fire anytime the user clicks away from the select. At this point you could determine what option was selected. To have this even trigger at the correct time, the onclick of the option\'s could blur the field (make something else active or just .blur() in jQuery).
回答5:
The onclick approach is not entirely bad but as said, it will not be triggered when the value isn\'t changed by a mouse-click.
It is however possible to trigger the onclick event in the onchange event.
<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>
回答6:
Going to expand on jitbit\'s answer. I found it weird when you clicked the drop down and then clicked off the drop down without selecting anything. Ended up with something along the lines of:
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>
This makes a little more sense for the user and allows JavaScript to run every time they select any option including an earlier option.
The downside to this approach is that it breaks the ability to tab onto a drop down and use the arrow keys to select the value. This was acceptable for me since all the users click everything all the time until the end of eternity.
回答7:
If you really need this to work like this, I would do this (to ensure it works by keyboard and mouse)
- Add an onfocus event handler to the select to set the \"current\" value
- Add an onclick event handler to the select to handle mouse changes
- Add an onkeypress event handler to the select to handle keyboard changes
Unfortunately the onclick will run multiple times (e.g. on onpening the select... and on selection/close) and the onkeypress may fire when nothing changes...
<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>
回答8:
To properly fire an event every time the user selects something(even the same option), you just need to trick the select box.
Like others have said, specify a negative selectedIndex
on focus to force the change event. While this does allow you to trick the select box, it won\'t work after that as long as it still has focus. The simple fix is to force the select box to blur, shown below.
Standard JS/HTML:
<select onchange=\"myCallback();\" onfocus=\"this.selectedIndex=-1;this.blur();\">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
jQuery Plugin:
<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>
You can see a working demo here.
回答9:
Actually, the onclick events will NOT fire when the user uses the keyboard to change the selection in the select control. You might have to use a combination of onChange and onClick to get the behavior you\'re looking for.
回答10:
What I did when faced with a similar Problem is I added an \'onFocus\' to the select box which appends a new generic option (\'select an option\'or something similar) and default it as the selected option.
回答11:
So my goal was to be able to select the same value multiple times which essentially overwrites the the onchange() function and turn it into a useful onclick() method.
Based on the suggestions above I came up with this which works for me.
<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>
http://jsfiddle.net/dR9tH/19/
回答12:
Here\'s my solution, completely different to any else on here. It uses the mouse position to figure out if an option was clicked as oppose to clicking on the select box to open the dropdown. It makes use of the event.screenY position as this is the only reliable cross browser variable. A hover event has to be attached first so it can figure out the controls position relative to the screen before the click event.
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\");
});
Here is my jsFiddle
http://jsfiddle.net/sU7EV/4/
回答13:
you should try using option:selected
$(\"select option:selected\").click(doSomething);
回答14:
What works for me:
<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>
In that way, onchange calls \'doSomething()\' when the option changes, and
onclick calls \'doSomething()\' when onchange event is false, in other words, when you select the same option
回答15:
Try this (event triggered exactly when you select option, without option changing):
$(\"select\").mouseup(function() {
var open = $(this).data(\"isopen\");
if(open) {
alert(\'selected\');
}
$(this).data(\"isopen\", !open);
});
http://jsbin.com/dowoloka/4
回答16:
<script>
function abc(selectedguy) {
alert(selectedguy);
}
</script>
<select onchange=\"abc(this.selectedIndex);\">
<option>option one</option>
<option>option two</option>
</select>
Here you have the index returned, and in the js code you can use this return with one switch or anything you want.
回答17:
first of all u use onChange as an event handler and then use flag variable to make it do the function u want every time u make a change
<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>
回答18:
The wonderful thing about the select tag (in this scenario) is that it will grab its value from the option tags.
Try:
<select onChange=\"javascript:doSomething(this.value);\">
<option value=\"A\">A</option>
<option value=\"B\">B</option>
<option value=\"Foo\">C</option>
</select>
Worked decent for me.
回答19:
use jquery:
<select class=\"target\">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<script>
$(\'.target\').change(function() { doSomething(); });
</script>
回答20:
Try this:
<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>
回答21:
A long while ago now but in reply to the original question, would this help ?
Just put onClick
into the SELECT
line.
Then put what you want each OPTION
to do in the OPTION
lines.
ie:
<SELECT name=\"your name\" onClick>
<option value =\"Kilometres\" onClick=\"YourFunction()\">Kilometres
-------
-------
</SELECT>
回答22:
<select name=\"test[]\"
onchange=\"if(this.selectedIndex < 1){this.options[this.selectedIndex].selected = !1}\">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
回答23:
I had faced a similar need and ended up writing a angularjs directive for the same -
guthub link - angular select
Used element[0].blur();
to remove the focus off the select tag. Logic is to trigger this blur on second click of the dropdown.
as-select
gets triggered even when user selects the same value in the dropdown.
DEMO - link
回答24:
The one True answer is to not use the select field (if you need to do something when you re-select same answer.)
Create a dropdown menu with conventional div, button, show/hide menu. Link: https://www.w3schools.com/howto/howto_js_dropdown.asp
Could have been avoided had one been able to add event listeners to options. If there had been an onSelect listener for select element. And if clicking on the select field didn\'t aggravatingly fire off mousedown, mouseup, and click all at the same time on mousedown.
回答25:
This may not directly answer your question, but this problem could be solved by simple design level adjustments. I understand this may not be 100% applicable to all use-cases, but I strongly urge you to consider re-thinking your user flow of your application and if the following design suggestion can be implemented.
I decided to do something simple than hacking alternatives for onChange()
using other events that were not really meant for this purpose (blur
, click
, etc.)
The way I solved it:
Simply pre-pend a placeholder option tag such as select that has no value to it.
So, instead of just using the following structure, which requires hack-y alternatives:
<select>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Consider using this:
<select>
<option selected=\"selected\">Select...</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
So, this way, your code is a LOT more simplified and the onChange
will work as expected, every time the user decides to select something other than the default value. You could even add the disabled
attribute to the first option if you don\'t want them to select it again and force them to select something from the options, thus triggering an onChange()
fire.
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).
Sometimes, you just need to take a step back and think about the big picture for the simplest solution.
回答26:
You can use onChange: http://www.w3schools.com/TAGS/tag_Select.asp
Copied from http://www.faqs.org/docs/htmltut/forms/_SELECT_onChange.html
onChange designates a JavaScript to run when the user chooses one of the options. This means that an action is initiated immediately when the user chooses an item, not when a \"submit\" button is pressed.
回答27:
Kindly note that Event Handlers are not supported for the OPTION tag on IE, with a quick thinking..I came up with this solution, try it and give me your feedback:
<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>
What I\'m doing here actually is resetting the select index so that the onchange event will be triggered always, true that you we lose the selected item when you click and it maybe annoying if your list is long, but it may help you in someway..
回答28:
what about changing the value of the select when the element gains focus, e.g (with 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(\'\');
}
});
回答29:
I found out this solution .
set the selectedIndex of select element to 0 initially
//set selected Index to 0
doSomethingOnChange(){
blah ..blah ..
set selected Index to 0
}
call this method onChange event