Wie können Sie einem HTML SELECT programmgesteuert mitteilen, dass es herunterfallen soll (z. B. aufgrund von Mouseover)?

104

Wie können Sie einem HTML- selectCode programmgesteuert mitteilen , dass er herunterfallen soll (z. B. aufgrund von Mouseover)?

Corey Trager
quelle
6
Ich würde empfehlen, nicht mit dem Verhalten der Standardeinstellung zu schrauben <select>, da die Leute erwarten, dass es sich auf eine bestimmte Weise verhält, und Sie verhindern, dass Leute auf anderen Plattformen (wie Mobilgeräten) Ihre Site verwenden.
Brian Donovan
1
@BrianDonovan Es ist nicht so, dass Sie dafür keine Behandlung hinzufügen können.
Morg.
@shasikanth: Ihre Geige funktioniert auch nicht in Firefox 37 nr in Chrome
rubo77
Ok, ich denke, die Geige hat früher funktioniert. Auf jeden Fall würde ich meinen Kommentar hier löschen.
Shasi Kanth
@BrianDonovan Eigentlich ist Mobile ein guter Anwendungsfall dafür ... programmgesteuert eine Auswahl generieren und dann automatisch die Optionen anzeigen lassen.
Michael

Antworten:

15

Sie können dies nicht mit einem HTML-Auswahl-Tag tun, aber Sie können es mit JavaScript und HTML tun . Hierfür gibt es eine Vielzahl vorhandener Steuerelemente, z. B. die Liste "Vorschlagen", die dem SO-Eintrag "Interessantes / Ignoriertes Tag" beigefügt ist, oder die Suche von Google Mail nach E-Mail-Adressen.

Es gibt viele JavaScript + HTML-Steuerelemente, die diese Funktion bieten. Suchen Sie nach Steuerelementen für die automatische Vervollständigung, um Ideen zu erhalten.

Siehe diesen Link für die Autocomplete-Steuerung ... http://ajaxcontroltoolkit.codeplex.com/

rp.
quelle
6
Das ist eine Schande - mobile Browser bieten eine betriebssystemspezifische Bildlaufliste, und diese muss automatisch angezeigt werden.
Michael
119

Früher war dies mit HTML + Javascript tatsächlich möglich, obwohl überall gesagt wird, dass dies nicht der Fall ist, aber es wurde später veraltet und funktioniert jetzt nicht mehr.

Dies funktionierte jedoch nur in Chrome. Lesen Sie mehr, wenn Sie interessiert sind.


Gemäß W3C Working Draft für HTML5, Abschnitt 3.2.5.1.7. Interaktiver Inhalt :

Bestimmte Elemente in HTML weisen ein Aktivierungsverhalten auf, was bedeutet, dass der Benutzer sie aktivieren kann. Dies löst eine Folge von Ereignissen aus, die vom [...] Aktivierungsmechanismus abhängen, beispielsweise über Tastatur- oder Spracheingabe oder durch Mausklicks .

Wenn der Benutzer ein Element mit einem definierten Aktivierungsverhalten auf eine andere Weise als durch Klicken auslöst, muss die Standardaktion des Interaktionsereignisses darin bestehen, synthetische Klickaktivierungsschritte für das Element auszuführen .

<select>Als interaktiver Inhalt glaubte ich, dass es möglich ist, seine <option>s programmatisch anzuzeigen . Nach ein paar Stunden Herumspielen entdeckte ich, dass es funktioniert document.createEvent()und .dispatchEvent()funktioniert.

Das heißt, Demo-Zeit. Hier ist eine funktionierende Geige.


HTML:

<select id="dropdown">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" onclick="runThis()">Show dropdown items</button>​

Javascript:

// <select> element displays its options on mousedown, not click.
showDropdown = function (element) {
    var event;
    event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);
};

// This isn't magic.
window.runThis = function () { 
    var dropdown = document.getElementById('dropdown');
    showDropdown(dropdown);
};

Wenn jemand einen Weg findet, dasselbe zu tun, aber nicht in Chrome, können Sie diese Geige jederzeit ändern . .

Xavier Ho
quelle
2
Danke dafür! Ich musste das ALT + DOWN ARROW-Verhalten des IE genau in Chrome emulieren.
J Bryan Price
3
Ich wünschte, ich könnte Ihr Kopfgeld dafür erhöhen. Ich danke dir sehr.
Adam Tuttle
7
Nicht arbeiten an: IE10, FF 24. Works on: Chrome 30, Safari 6.0.5,Opera 16
hitautodestruct
2
@ AdamTuttle Es funktioniert auch nicht auf Android 4.4.2
Mirko
42
Es ist jetzt auf Chrome 53+
Washington Guedes
47

In der Antwort von Xavier Ho wird erläutert, wie das Problem in den meisten derzeit verfügbaren Browsern gelöst werden kann. Es wird jedoch empfohlen, Ereignisse nicht mehr per JavaScript zu versenden / zu ändern . (Wie mousedownin diesem Fall)

Ab Version 53 führt Google Chrome keine Standardaktion für nicht vertrauenswürdige Ereignisse aus . Zum Beispiel Ereignisse, die per Skript erstellt oder geändert oder über eine dispatchEventMethode ausgelöst werden . Diese Änderung dient der Ausrichtung auf Firefox und IE, von denen ich denke, dass sie die Aktion bereits nicht ausführen.

Zu Testzwecken hat Fiddle angegeben, dass Xaviers Antwort in Chrome 53+ nicht funktioniert. (Ich teste es nicht FF und IE).

Links als Referenz:

https://www.chromestatus.com/features/5718803933560832 https://www.chromestatus.com/features/6461137440735232

Und initMouseEvent ist ebenfalls veraltet

Asim KT
quelle
Kann es mit MouseEvents gemacht werden? developer.mozilla.org/en-US/docs/Web/API/MouseEvent
Shamal Perera
Das glaube ich nicht. Hast du etwas versucht?
Asim KT
28

Dies ist der nächstgelegene Wert, den ich erreichen kann, um die Größe des Elements onmouseover zu ändern und die Größe onmouseout wiederherzustellen:

       <select onMouseOut="this.size=1;" onMouseOver="this.size=this.length;">
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option>5</option>
      </select>

CMS
quelle
13
oder <SELECT onMouseOut = "this.size = 1;" onMouseOver = "this.size = this.length;"> ... </ SELECT>
RealHowTo
1
Außerdem muss onchange = "this.size = 1" hinzugefügt werden, damit das Menü ausgeblendet wird, sobald die Auswahl getroffen wird. Die CSS-Regeln des Elements müssen ebenfalls konfiguriert werden.
GM2008
Es scheint zu funktionieren. Die Auswahlbreite wird kleiner und dies führt dazu, dass ein Mouse-Out-Ereignis die Auswahl auf die ursprüngliche Breite zurücksetzt. Dies verursacht einen Anfallseffekt. Das Einstellen einer festen Breite scheint dies zu beheben. Mit mehr als ein paar Elementen wird die Liste über die Ansicht hinaus erweitert.
1,21 Gigawatt
16

Ich habe das gleiche Problem und der einfachere Weg, dies zu lösen, war mit HTML und CSS.

select{
  opacity: 0;
  position: absolute;
}
<select>
  <option>option 1</option>
  <option>option 2</option>
  <option>option 3</option>
</select>
<button>click</button>

Rafael Umbelino
quelle
2
Es ist lange her, dass ich diesen Ansatz gesehen habe, und es ist die Referenz, die ich zu finden hoffte. Besser mit zusätzlichem CSS, um die Größe der ausgeblendeten Auswahl für den Trigger anzupassen (Schaltfläche, Bild, Div usw.) ... 1) Stellt sicher, dass der auslösbare Klick den auslösbaren Bereich ausfüllt. 2) Das Menü wird direkt unter dem Trigger geöffnet. Hinweis: Möglicherweise muss auch ein Z-Index hinzugefügt werden, um sicherzustellen, dass der anklickbare Bereich in einigen Layouts das oberste Element ist.
Mavelo
Wenn der Benutzer jedoch die Seite nach unten scrollt, bewegt sich die Schaltfläche entsprechend, aber die Auswahl bleibt an derselben Position. nicht wirklich wie erwartet. eine Lösung dafür?
David Portabella
Perfekte Lösung. Aber besser vielleicht Wrap Button und wählen Sie auf div wie <div style='position:relative'><select> <option>option 1</option> <option>option 2</option> <option>option 3</option> </select> <button>click</button></div>folgt @DavidPortabella
Muhammet Can TONBUL
8

Ich denke, dass dies in Chrome nicht mehr möglich ist.

Es scheint, dass Version 53 von Chrome diese Funktionalität deaktiviert, wie von Asim K T angegeben.

Gemäß der Spezifikation http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events

Vertrauenswürdige Ereignisse sollten die Standardaktion nicht auslösen (außer Klickereignis).

Sie haben es jedoch in der Webansicht aktiviert, aber ich habe dies nicht getestet.

Wir haben festgestellt, dass einige Webviews einen Schnellklick in ihnen verwenden. Aufgrund der Gefahr eines Bruchs werden wir die Auswahl von Mausauswahlen auch dann zulassen, wenn sie nicht vertrauenswürdig sind.

Und in dieser Diskussion wird die Idee, Entwickler ein Dropdown-Programm programmgesteuert öffnen zu lassen, aufgegeben.

Understatic
quelle
7

Wenn jemand noch danach sucht:

<select id="dropdown">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" >Show dropdown items</button>

Javascript:

var is_visible=false; 

$(document).ready(function(){

    $('#fire').click(function (e) { 
    var element = document.getElementById('dropdown');


    if(is_visible){is_visible=false; return;}
    is_visible = true;

    var event;
    event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);

    /* can be added for i.e. compatiblity.
      optionsSelect.focus();
       var WshShell = new ActiveXObject("WScript.Shell");
       WshShell.SendKeys("%{DOWN}");
    */
    e.stopPropagation();
    return false;
});


$(document).click(function(){is_visible=false; });
});

Aktualisieren:

Eins, bis es keine perfekte Lösung für dieses Problem gibt, aber Sie können versuchen, dieses Szenario zu vermeiden. Warum willst du das tun? Ich habe mich vor einigen Monaten nach einer Lösung gefragt, um ein ausgewähltes Plugin für mobile Geräte zu erstellen

https://github.com/HemantNegi/jquery.sumoselect

Schließlich wurde das benutzerdefinierte div (oder ein anderes Element) mit einem transparenten Auswahlelement maskiert, damit es direkt mit dem Benutzer interagieren kann.

Hemant_Negi
quelle
1
Plugins wie github.com/HemantNegi/jquery.sumoselect sind die einzige browserübergreifende Lösung, die tatsächlich besser aussieht als das Standardsteuerelement.
Justin
iniMouseEventscheint zu funktionieren, aber warum funktioniert $(select).trigger('mousedown')es nicht?
Coding_idiot
3

Hier ist der beste Weg, den ich gefunden habe. HINWEIS Es funktioniert nur mit IE unter Windows und Ihr Web muss sich wahrscheinlich in einer sicheren Zone befinden - da wir auf die Shell zugreifen. Der Trick ist, dass der ALT-Abwärtspfeil eine Tastenkombination zum Öffnen eines ausgewählten Dropdowns ist.

<button id="optionsButton" style="position:absolute;top:10px;left:10px;height:22px;width:100px;z-index:10" onclick="doClick()">OPTIONS</button>
<select id="optionsSelect" style="position:absolute;top:10px;left:10px;height:20px;width:100px;z-index:9">
    <option>ABC</option>
    <option>DEF</option>
    <option>GHI</option>
    <option>JKL</option>
</select>
<script type="text/javascript">
   function doClick() {
       optionsSelect.focus();
       var WshShell = new ActiveXObject("WScript.Shell");
       WshShell.SendKeys("%{DOWN}");
   }
</script>
Sproketboy
quelle
3
Es wird nicht funktionieren , es sei denn , Sie tun dies .
Knu
1
@Knu Internet Explorer fügt die IDs von Elementen automatisch als Verweise auf das Element zum globalen Bereich hinzu.
user2428118
@KlasMellbourn wahrscheinlich. Sie versuchen jetzt, ihre Browser kompatibler zu machen. Verwenden Sie die angegebene "Größen" -Lösung.
Sproketboy
2

Hör auf zu denken, dass eine Sache unmöglich ist, nichts ist unmöglich zu tun, wenn du tun willst.

Verwenden Sie diese von einem Mann erstellte JS-Erweiterungsfunktion.

http://code.google.com/p/expandselect/

Fügen Sie dieses JS ein und rufen Sie einfach das Übergeben des Parameters als Ihre ausgewählte ID auf:

ExpandSelect(MySelect)
Paulo Roberto Rosa
quelle
1
Um klar zu sein, dass JS nicht dazu führt <SELECT>, dass a herunterfällt. Da ausdrücklich angegeben ist, dass "Browser das Erweitern von <select> in reinem Javascript nicht zulassen, kann dieses Steuerelement nur durch direktes Klicken mit der Maus erweitert werden". Es ist also "unmöglich"! Stattdessen heißt es in der JS: "Wir ahmen die erweiterte <select> -Steuerung nach, indem wir eine weitere Auswahl erstellen, bei der mehrere Optionen gleichzeitig angezeigt werden ..." Dies ist ganz anders und kann für Ihren Anwendungsfall akzeptabel sein oder auch nicht ...
JonBrave
1

Ich kann mich irren, aber ich glaube nicht, dass dies mit dem Standardauswahlfeld möglich ist. Sie könnten mit JS & CSS etwas tun, das das gewünschte Ergebnis erzielt, aber meines Wissens nicht mit Vanille SELECT.

Futter
quelle
0

Das Öffnen einer "HTML-Auswahl" ist durch einige in dieser Frage erwähnte und ähnliche Problemumgehungen möglich. Eine sauberere Möglichkeit besteht darin, Ihrem Projekt eine ausgewählte Bibliothek wie "select2" oder "selected" hinzuzufügen. Zum Beispiel wäre das programmgesteuerte Öffnen einer select2 so einfach wie:

$('#target-select').select2('open');
Kasra Ebrahimi
quelle
-2

Dies ist nicht genau das, wonach Sie gefragt haben, aber ich mag diese Lösung wegen ihrer Einfachheit. In den meisten Fällen, in denen ich ein Dropdown-Menü initiieren möchte, habe ich überprüft, ob der Benutzer tatsächlich eine Auswahl getroffen hat. Ich ändere die Größe des Dropdowns und fokussiere es, wodurch deutlich wird, was sie übersprungen haben:

$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();
Rob3C
quelle
Ich bin mir nicht sicher, warum du herabgestimmt wurdest, da dies nicht der "schlechteste" Weg ist. Ich würde dies einfach vermeiden, weil es das Layout der umgebenden Elemente verschiebt. Obwohl ich denke, dass die Lösung von @CMS mit den Fokus- / Unschärfeereignissen an der Steuerung leichter zu verstehen ist.
Mavelo