Как избежать необходимости ctrl-click в поле множественного выбора с помощью Javascript?


Я думал, что это будет простой хак, но теперь я искал в течение нескольких часов и не вижу, чтобы найти правильный поисковый запрос. Я хочу иметь обычное поле множественного выбора (<select multiple="multiple">) за исключением того, что я не хочу, чтобы пользователь должен был удерживать клавишу управления, чтобы сделать несколько вариантов выбора.

другими словами, Я хочу щелкнуть левой кнопкой мыши, чтобы переключить <option> элементом, который находится под курсором без изменения каких-либо других. Другими словами, Я хочу что-то, что выглядит как комбо список, но ведет себя как группа флажков.

может кто-нибудь предложить простой способ сделать это в JavaScript? Спасибо.

5   51  

5 ответов:

, проверьте эту скрипку: http://jsfiddle.net/xQqbR/1022/

вам в основном нужно переопределить mousedown событие для каждого <option> и включения selected собственность есть.

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

для простоты, я дал вариант '' в качестве селектора выше. Вы можете точно настроить его, чтобы соответствовать <option>s под конкретные <select> элемент(ы). Например: $('#mymultiselect option')

пришлось решать эту проблему самостоятельно и заметил прослушиваемое поведение простой перехват mousedown и Установка атрибута будет иметь, поэтому сделал переопределение элемента select, и он работает хорошо.

jsFiddle: http://jsfiddle.net/51p7ocLw/

Примечание: этот код исправляет поведение багги, заменяя элемент select в DOM. Это немного агрессивно и сломает обработчики событий, которые вы могли бы прикрепить к стихии.

window.onmousedown = function (e) {
    var el = e.target;
    if (el.tagName.toLowerCase() == 'option' && el.parentNode.hasAttribute('multiple')) {
        e.preventDefault();

        // toggle selection
        if (el.hasAttribute('selected')) el.removeAttribute('selected');
        else el.setAttribute('selected', '');

        // hack to correct buggy behavior
        var select = el.parentNode.cloneNode(true);
        el.parentNode.parentNode.replaceChild(select, el.parentNode);
    }
}
<h4>From</h4>

<div>
    <select name="sites-list" size="7" multiple>
        <option value="site-1">SITE</option>
        <option value="site-2" selected>SITE</option>
        <option value="site-3">SITE</option>
        <option value="site-4">SITE</option>
        <option value="site-5">SITE</option>
        <option value="site-6" selected>SITE</option>
        <option value="site-7">SITE</option>
        <option value="site-8">SITE</option>
        <option value="site-9">SITE</option>
    </select>
</div>

techfoobar ответ глючит,он снимает все параметры, если вы перетащите мышь.

ответ Серхио интересен, но клонирование и удаление событий, связанных с выпадающим списком,-это не очень хорошая вещь.

попробуйте этот ответ.

Примечание: не работает на Firefox, но отлично работает на Safari/Chrome/Opera. (Я не тестировал его на IE)

У меня была такая же проблема сегодня, как правило, совет состоит в том, чтобы использовать список скрытых флажков и эмулировать поведение с помощью css, таким образом, более легко управлять, но в моем случае я не хочу изменять html.

на данный момент я тестировал этот код только с google chrome, я не знаю, работает ли он с другим браузером, но он должен:

var changed;
$('select[multiple="multiple"]').change(function(e) {
    var select = $(this);
    var list = select.data('prevstate');
    var val = select.val();
    if (list == null) {
        list = val;
    } else if (val.length == 1) {
        val = val.pop();
        var pos = list.indexOf(val);
        if (pos == -1)
            list.push(val);
        else
            list.splice(pos, 1);
    } else {
        list = val;
    }
    select.val(list);
    select.data('prevstate', list);
    changed = true;
}).find('option').click(function() {
    if (!changed){
        $(this).parent().change();
    }
    changed = false;
});

конечно, предложения приветствуются, но я не нашел другой способ

некромантии.
Выбранный ответ без jQuery.
Кроме того, он пропустил настройку фокуса при нажатии опции, потому что вы должны сделать это сами, если вы пишете e.preventDefault...
Забывание сделать фокус повлияет на CSS-стиль, например, bootstrap и т. д.

var options = [].slice.call(document.querySelectorAll("option"));

options.forEach(function (element)
{
    // console.log("element", element);
    element.addEventListener("mousedown", 
        function (e)
        {
            e.preventDefault();
            element.parentElement.focus();
            this.selected = !this.selected;
            return false;
        }
        , false
    );
});