it-swarm.com.de

Wie vermeide ich die Verwendung von Strg-Klick in ein Mehrfachauswahlfeld mit Javascript?

Ich dachte, das wäre ein einfacher Hack, aber ich habe jetzt stundenlang gesucht und konnte nicht den richtigen Suchbegriff finden. Ich möchte ein gewöhnliches Mehrfachauswahlfeld (<select multiple="multiple">), es sei denn, ich möchte nicht, dass der Benutzer die Steuertaste gedrückt halten muss, um eine Mehrfachauswahl zu treffen. 

Mit anderen Worten, ich möchte mit einem Linksklick das <option>-Element, das sich unter dem Cursor befindet, umschalten, ohne die anderen zu ändern. Mit anderen Worten, ich möchte etwas, das wie ein Kombinationslistenfeld aussieht, sich aber wie eine Gruppe von Kontrollkästchen verhält.

Kann jemand eine einfache Möglichkeit vorschlagen, dies in Javascript zu tun? Vielen Dank.

54
bokov

Überprüfen Sie diese Geige: http://jsfiddle.net/xQqbR/1022/

Grundsätzlich müssen Sie das mousedown-Ereignis für jeden <option> überschreiben und die selected-Eigenschaft dort umschalten.

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

Der Einfachheit halber habe ich oben eine Option als Option angegeben. Sie können ihn unter bestimmten <option>s-Elementen auf <select> abstimmen. Zum Beispiel: $('#mymultiselect option')

90
techfoobar

Um dieses Problem selbst zu lösen und aufgefallen zu sein, dass das fehlerhafte Verhalten ein einfaches Abfangen der mousedown und das Setzen des Attributs hätte, hätte sich das select-Element überschrieben und es funktioniert gut.

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

Note: Dieser Code behebt fehlerhaftes Verhalten, indem er das select-Element im DOM ersetzt. Dies ist etwas aggressiv und unterbricht Eventhandler, die Sie möglicherweise an das Element angehängt haben.

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>

18
Sergio

die Antwort von techfoobar ist fehlerhaft. Wenn Sie die Maus ziehen, wird die Auswahl aller Optionen aufgehoben.

Sergios Antwort ist interessant, aber das Klonen und Entfernen von Ereignissen, die an ein Dropdown-Fenster gebunden sind, ist keine schöne Sache.

Versuchen Sie diese Antwort .

Hinweis: Funktioniert nicht mit Firefox, funktioniert jedoch perfekt mit Safari/Chrome/Opera. (Ich habe es nicht im IE getestet)

5
evilReiko

Nekromanzierung. 
Die ausgewählte Antwort ohne jQuery. 
Außerdem wurde der Fokus nicht gesetzt, wenn eine Option angeklickt wird, da Sie dies selbst tun müssen, wenn Sie e.preventDefault schreiben. 
Wenn Sie die Fokussierung vergessen, wirkt sich dies auf das CSS-Styling aus, z. Bootstrap usw.

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
    );
});
0
Stefan Steiger

Ich hatte heute dasselbe Problem. Im Allgemeinen wird empfohlen, eine Liste ausgeblendeter Kontrollkästchen zu verwenden und das Verhalten über css zu emulieren. Auf diese Weise ist es einfacher zu verwalten, aber in meinem Fall möchte ich HTML nicht ändern.

Im Moment habe ich diesen Code nur mit Google Chrome getestet. Ich weiß nicht, ob er mit anderen Browsern funktioniert, aber er sollte:

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;
});

Natürlich sind Vorschläge willkommen, aber ich habe keinen anderen Weg gefunden

0