Как избежать необходимости ctrl-щелчка в окне с несколькими вариантами выбора, используя Javascript? - PullRequest
56 голосов
/ 27 декабря 2011

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

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

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

Ответы [ 5 ]

95 голосов
/ 27 декабря 2011

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

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

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

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

18 голосов
/ 20 декабря 2014

Пришлось решить эту проблему самому и заметил, что в поведении произошел простой перехват 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>
5 голосов
/ 27 мая 2015

Ответ techfoobar содержит ошибки, он отменяет выбор всех параметров, если вы перетаскиваете мышь.

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

Примечание. Не работает в Firefox, но отлично работает в Safari / Chrome / Opera.(Я не проверял это на IE)

1 голос
/ 18 мая 2018

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

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
    );
});
1 голос
/ 01 октября 2014

У меня была та же проблема сегодня, обычно совет состоит в том, чтобы использовать список скрытых флажков и эмулировать поведение с помощью 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;
});

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...