I realized Firefox treats click event on <select>
tag differently from Webkit/IE, and I couldn't figure out why or how to resolve this difference.
Specifically, Webkit/IE regards each click event on <select>
as a combination of both clicking on "select", and the clicking of one of the drop-down <option>
, shown in graphs below:
First Click:
Second Click:
In Webkit/IE, click event will be fired only after both clicks have been done.
However, in Firefox, the first click on the <select>
tag is regarded as a click event, the second click to select <option>
is regarded as another click event. Therefore, two click events have been fired in Firefox comparing to one in Webkit/IE for the same operation.
Now to demonstrate it in code example, assuming we have: (JSfiddle link)
<select id="sel">
<option>one</option>
<option>two</option>
<option>three</option>
</select>
<script>
function select() {
$("#sel").one("click", function(event) {
console.log('mouse down!');
$("#sel").one('click', function() {
console.log('mouse down again!');
$("#sel").off();
select();
});
});
}
$(document).ready(function() {
select();
});
</script>
In Webkit/IE, performing the set of operations shown above in the graph (for the first time) will give output:
mouse down!
In Firefox, it will give:
mouse down!
mouse down again!
Why is it so and how do I fix it?
Edit: I tried with pure JavaScript without jQuery, the result remains the same.
Edit 2: A little more context, I originally answered this question: onclick on option tag not working on IE and chrome and won a bounty for my answer. However, as the op later pointed out, my solution did not work on Firefox. I decided to dig deeper to resolve this problem, and hence this question was asked and I am rewarding that 50 bounty I got from that solution. Essentially, the problem is to create a select menu that will trigger an event whenever a selection is made, even when it is the same. This has proven to be harder than expected, if possible at all due to different browser implementations.
Edit 3: I am fully aware of onchange
, but the question here is not about onchange
if you read carefully. I need to have each selection trigger an event even if they are the same selection (which will not trigger onchange
.
Why not work with onchange
event?
$("#sel").change(function(){
$('body').append("<br/> Option changed");
});
Here is the fiddle
But it won't fire an even when selection is the same. Work around is to use a plugin like Chosen as suggested in another answer.
EDIT: Philosophically speaking select
element is not meant for such functionality. change
event suffices for most use cases related to select
tags. The functionality that you desire, that is to know if a user has made a selection over the element (even if it hasn't change), doesn't fit the functional model of the select
tag. Logically nobody would want to click on a select
element if he/she doesn't want to change the selection.
To fit your requirement, you can give a Go button
besides your select tag and call the same function onclick
that you would normally do with the onchange
event of select
element. Otherwise give a hovercard/hover-menu instead of select
.
After many experiments and searching, I am starting to get convinced that this particular different behaviour in different browsers is hard to resolve, if possible at all.
I realized, however, I could solve the problem from the other side, by using jQuery UI select menu or Chosen to create a select menu instead of using <select>
tag. This way click
event will be fired on <ul>
or <li>
tag which is consistent in all browsers I tested.
Essentially, the problem is to create a select menu that will trigger an event whenever a selection is made, even when it is the same.
This technically does (sorta) that, but in FF it triggers when you click to open and when you click to close (which you can actually do in one click, which produces the exact same thing in Safari AND Firefox). But it is the same event. (A click trigger fire on $('#sel')
);
$("#sel").click(function(event) {
if($(event.target).is('option')) {
$(this).closest('select').click();
return true;
}
console.log(event.target);
});
The reason I say that it "sorta" does that, is it doesn't handle if you select the dropdown from tabbing over and using the arrow keys. I think that if you are needing the event to be triggered even if the event same item is selected, you need to go about this differently. For me as a developer, if this was my project, it'd be unacceptable that if I tab to a select box and choose an item without touching the mouse, it won't work (meaning if a user comes to my site and interacts with a select box without a mouse and it doesn't do something he doesn't even know it's supposed to do, possibly making the whole thing not work, etc).
We can play around all day with getting .click()
to work, but it's not really the solution, even if we achieved the original goal. (Oh, and I could never get anything to fire in Chrome).
Like I said in my comment, I think it has to do with how they handle interactions with the select. It almost feels as though Safari's select isn't actually on the page... that it sort creates this pretty element that acts and looks like a list of <option>
elements when you click on it, but it isn't. Probably why it doesn't fire when you first click it either. Webkit doesn't treat it as a "real" element when you click on it, and just fires click on the select when you close it, never having interacted with the "real" options.
Changing the HTML may be the only way to go (like Chosen does). Ironically, some of the Chosen elements (the ones that look like dropdowns) can't be selected by tabbing over... at least not on their demo page (see the "Standard Select"). But that at least forces me to click on it, so it triggers mouse-related events.
Anyway, I hate unsolved problems, but it looks like there's no real solution for getting .click()
to work on a <select>
in all browsers and we should start focusing on alternative solutions. Sorry :-(
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With