Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Firefox react differently from Webkit and IE to "click" event on "select" tag?

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:

First click

Second 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.

like image 320
K Z Avatar asked Apr 12 '12 08:04

K Z


3 Answers

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.

like image 78
Juzer Ali Avatar answered Dec 21 '22 04:12

Juzer Ali


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.

like image 40
K Z Avatar answered Dec 21 '22 03:12

K Z


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 :-(

like image 35
CWSpear Avatar answered Dec 21 '22 04:12

CWSpear