mousedown event on options in select is not workin

2020-04-30 12:13发布

问题:

This following code snippet is to avoid the need for ctrl-click in a multi-select box

but it does not work in IE 8 .

Is there any work around to achive the same in IE and other IE version?

$('option').mousedown(function(e) {
  e.preventDefault();
  $(this).prop('selected', !$(this).prop('selected'));
  return false;
});

回答1:

I don't believe there's any way to get the mousedown or click event on an option element in IE8.

If you really want the behavior you describe, I suggest that you use a different control, rather than a multiple select box. Changing the behavior of standard UI components is usually not a good idea, as users are used to them behaving a certain way and get confused when they behave differently in some apps/pages than they do in others. If you want a list with simple click-on, click-off behavior, much better to do something completely your own.

You can do this with a multiple select, but the user experience is really ugly:

var selected = {};
$('#yourSelectBox').click(function(e) {
    var $this = $(this),
        options = this.options,
        option,
        value,
        n;

    // Find out what option was just added
    value = $this.val();

    // Re-apply the selections
    for (n = 0; n < options.length; ++n) {
        option = options[n];
        if (option.value == value) {
            // The one being updated
            selected[value] = !selected[value];
        }

        // One of the others
        option.selected = !!selected[option.value];
    }

    return false;
});

Live Example | Source

Again, though, that's a really ugly user experience.


Here's an example of a pseudo-select instead: Live Example | Source

CSS:

.pseudo-select {
    border: 1px solid black;
    width: 200px;
}
.pseudo-option {
    cursor: pointer;
    border: 1px solid #eee;
}
.pseudo-option.selected {
    background-color: #33c;
    color: white;
}

HTML:

<div class="pseudo-select">
    <div class="pseudo-option" data-value="1">One</div>
    <div class="pseudo-option" data-value="2">Two</div>
    <div class="pseudo-option" data-value="3">Three</div>
    <div class="pseudo-option" data-value="4">Four</div>
    <div class="pseudo-option" data-value="5">Five</div>
    <div class="pseudo-option" data-value="6">Six</div>
    <div class="pseudo-option" data-value="7">Seven</div>
    <div class="pseudo-option" data-value="8">Eight</div>
    <div class="pseudo-option" data-value="9">Nine</div>
</div>

JavaScript using jQuery:

$(".pseudo-option").click(function() {
    $(this).toggleClass("selected");
});

That's just something I dashed off in a couple of minutes, obviously plenty of room for improvement, but you get the idea.

Note: If you use something like this, you'll want to detect mobile browsers and browsers using assisstive technologies (screen readers, etc.) and use a normal select instead (as the browser will do a better job of working with the user in those situations.).



回答2:

I found one major issue with jQuery answer above. The .val() of the $(select) won't update.

Here is working solution:

$select.mousedown(function (e) {
    e.preventDefault();
    const select = this;
    const { scrollTop } = select;
    e.target.selected = !e.target.selected;
    setTimeout(function () {
        select.scrollTop = scrollTop;
    }, 0);
}).mousemove(function (e) { e.preventDefault(); });