Kann ich mit jQuery eine Dropdown-Liste öffnen?


84

Für diese Dropdown-Liste in HTML:

<select id="countries">
<option value="1">Country</option>
</select>

Ich möchte die Liste öffnen (genauso wie wenn ich mit der linken Maustaste darauf klicke). Ist dies mit JavaScript (oder genauer jQuery) möglich?



4
Kann jemand erklären, warum das so unmöglich ist?
SpaceBeers


Antworten:


16

Sie können leicht einen Klick auf ein Element simulieren , aber ein Klick auf ein <select>öffnet das Dropdown-Menü nicht.

Die Verwendung von Mehrfachauswahl kann problematisch sein. Vielleicht sollten Sie Optionsfelder in einem Containerelement berücksichtigen, die Sie nach Bedarf erweitern und verkleinern können.


68

Ich habe versucht, das Gleiche zu finden und wurde enttäuscht. Am Ende habe ich die Attributgröße für das Auswahlfeld so geändert, dass es sich zu öffnen scheint

$('#countries').attr('size',6);

und dann, wenn du fertig bist

$('#countries').attr('size',1);

12
Das Hinzufügen eines sizeAttributs zum Dropdown konvertiert das Dropdown-Menü tatsächlich in Listbox. Dadurch wird es erweitert.
Mayank Pathak

Tolle Lösung. Sie müssen sich nur mit der Tatsache auseinandersetzen, dass das Listenfeld mehr Platz auf der Seite einnimmt (anstatt wie ein Dropdown über den Inhalt zu expandieren) und somit den Inhalt nach unten drückt.
zkent

Für diejenigen, die sich nur vorstellen können, wie es aussieht, ist das Erscheinungsbild nach Verwendung dieses Ansatzes (aber nicht mehrfach auswählbar) ein Mehrfachauswahlfeld, das meiner Meinung nach stabiler ist, als das Dropdown-Menü zu öffnen.
Siwei

Dies funktioniert technisch, aber 1) Sie haben jetzt eine hässliche Bildlaufleiste an der Seite und 2) der Z-Index ist auf die ursprüngliche Auswahl festgelegt, sodass er sich auch nicht wie ein Popup-Pulldown verhält.
BoB3K

Vielen Dank dafür ... Ich habe 2 Stunden damit verbracht, verschiedene Popover usw. auszuprobieren, um Benutzer darauf aufmerksam zu machen, dass sie etwas auswählen müssen. Nichts hat gut funktioniert ... dies ist eine subtile, aber feste Erinnerung. Und es funktioniert (im Gegensatz zu schuppigen anderen Lösungen).
11.

15

Ich bin auf dasselbe Problem gestoßen und habe eine Lösung. Eine Funktion namens ExpandSelect (), die das Klicken mit der Maus auf das Element "select" emuliert. Dazu wird ein anderes <select>Element erstellt, das absolut positioniert ist und durch Festlegen des sizeAttributs mehrere Optionen gleichzeitig sichtbar macht . Getestet in allen gängigen Browsern: Chrome, Opera, Firefox, Internet Explorer. Erklärung, wie es funktioniert, zusammen mit dem Code hier:

Bearbeiten (Link war defekt) .

Ich habe ein Projekt bei Google Code erstellt. Suchen Sie dort den Code:

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

Screenshots

Es gibt einen kleinen Unterschied in der GUI beim Emulieren von Klicks, aber es spielt keine Rolle, überzeugen Sie sich selbst:

Beim Mausklick:

Mausklick
(Quelle: googlecode.com )

Beim Emulieren klicken Sie auf:

EmulierenKlicken
(Quelle: googlecode.com )

Weitere Screenshots auf der Website des Projekts finden Sie oben.


2
Kannst du eine jsfiddle dafür posten?
Jay Sullivan

10

Dies sollte es abdecken:

 var event;
 event = document.createEvent('MouseEvents');
 event.initMouseEvent('mousedown', true, true, window);
 countries.dispatchEvent(event); //we use countries as it's referred to by ID - but this could be any JS element var

Dies kann beispielsweise an ein Tastendruckereignis gebunden sein. Wenn das Element den Fokus hat, kann der Benutzer eingeben und es wird automatisch erweitert ...

--Kontext--

  modal.find("select").not("[readonly]").on("keypress", function(e) {

     if (e.keyCode == 13) {
         e.preventDefault();
         return false;
     }
     var event;
     event = document.createEvent('MouseEvents');
     event.initMouseEvent('mousedown', true, true, window);
     this.dispatchEvent(event);
 });

hat für mich gearbeitet! Jede andere Antwort deutete darauf hin, dass es noch keine Möglichkeit gibt, eine Auswahl auszulösen. Haben Sie eine gefunden? Gibt es Nachteile bei diesem Ansatz?
Kittyminky

Ja - es stört Tabbing-Ereignisse (ich denke!). Es hängt von Ihren Bedürfnissen ab - aber es hat wie erwartet funktioniert - aber es hat nicht zu unseren anderen Bedürfnissen gepasst.
Stuart.Sklinar

Hat für mich gearbeitet. Wenn Sie von einem anderen Event-Handler anrufen, denken Sie daran, das dom-Element herauszuholen -$('#select_element').get(0).dispatchEvent(event);
BoB3K

das funktioniert bei mir nicht läuft auf Chrome 56.0.2924 unter OSX
ekkis

9

Dies ergibt sich aus den obigen Antworten und verwendet die Länge / Anzahl der Optionen, um der Anzahl der tatsächlich verfügbaren Optionen zu entsprechen.

Hoffe, das hilft jemandem, die Ergebnisse zu erzielen, die er braucht!

    function openDropdown(elementId) {
        function down() {
            var pos = $(this).offset(); // remember position
            var len = $(this).find("option").length;
                if(len > 20) {
                    len = 20;
                }

            $(this).css("position", "absolute");
            $(this).css("zIndex", 9999);
            $(this).offset(pos);   // reset position
            $(this).attr("size", len); // open dropdown
            $(this).unbind("focus", down);
            $(this).focus();
        }
        function up() {
            $(this).css("position", "static");
            $(this).attr("size", "1");  // close dropdown
            $(this).unbind("change", up);
            $(this).focus();
        }
        $("#" + elementId).focus(down).blur(up).focus();
    }

5

Einfach und leicht.

function down(what) {
  pos = $(what).offset();  // remember position
  $(what).css("position","absolute");
  $(what).offset(pos);   // reset position
  $(what).attr("size","10"); // open dropdown
}

function up(what) {
$(what).css("position","static");
$(what).attr("size","1");  // close dropdown
}

Jetzt können Sie Ihren DropDown einfach so aufrufen

<select onfocus="down(this)" onblur="up(this)">

Funktioniert perfekt für mich.

Vielleicht besser, weil Sie keine Probleme mit der Position der anderen Elemente auf der Seite haben.

function down(was) {
a = $(was).clone().attr('id','down_man').attr('disabled',true).insertAfter(was);
$(was).css("position","absolute").attr("size","10");
}

function up(was) {
$('#down_man').remove();
$(was).css("position","static");
$(was).attr("size","1");
}

Ändern Sie die ID in einen festen Wert, der vielleicht nicht klug ist, aber ich hoffe, Sie sehen die Idee.


4

Es ist nicht möglich, dass Javascript auf ein Element "klickt" (Sie können das angehängte Element auslösen onclick Ereignis , aber Sie können nicht buchstäblich darauf klicken).

Um alle Elemente in der Liste anzuzeigen, machen Sie die Liste zu einer multipleListe und vergrößern Sie sie wie folgt:

<select id="countries" multiple="multiple" size="10">
<option value="1">Country</option>
</select>

Fügt nach 4 Elementen in IE6, 7 & 8b2 und Opera 9.62 eine Bildlaufleiste hinzu. Fügt nach 10 Elementen in Safari für Windows und Google Chrome eine Bildlaufleiste hinzu.
Grant Wagner

2

Nein, kannst du nicht.

Sie können die Größe ändern, um sie zu vergrößern ... ähnlich wie bei Dreas, aber es ist die Größe, die Sie ändern müssen.

<select id="countries" size="6">
  <option value="1">Country 1</option>
  <option value="2">Country 2</option>
  <option value="3">Country 3</option>
  <option value="4">Country 4</option>
  <option value="5">Country 5</option>
  <option value="6">Country 6</option>
</select>

2

Ich habe versucht, die Antwort von mrperfect zu verwenden, und ich hatte ein paar Pannen. Mit ein paar kleinen Änderungen konnte ich es für mich zum Laufen bringen. Ich habe es nur so geändert, dass es nur einmal funktioniert. Sobald Sie Dropdown beenden, wird zur normalen Dropdown-Methode zurückgekehrt.

function down() {
    var pos = $(this).offset(); // remember position
    $(this).css("position", "absolute");
    $(this).offset(pos);   // reset position
    $(this).attr("size", "15"); // open dropdown
    $(this).unbind("focus", down);
}
function up() {
    $(this).css("position", "static");
    $(this).attr("size", "1");  // close dropdown
    $(this).unbind("change", up);
}
function openDropdown(elementId) {
    $('#' + elementId).focus(down).blur(up).focus();
}

2

Eine Sache, die dies nicht beantwortet, ist, was passiert, wenn Sie auf eine der Optionen in der Auswahlliste klicken, nachdem Sie Ihre Größe = n festgelegt und die absolute Positionierung vorgenommen haben.

Da das Unschärfeereignis die Größe = 1 ergibt und es wieder so ändert, wie es aussieht, sollten Sie auch so etwas haben

$("option").click(function(){
    $(this).parent().blur();
});

Wenn Sie Probleme mit der absolut positionierten Auswahlliste haben, die hinter anderen Elementen angezeigt wird, geben Sie einfach ein

z-index: 100;

oder so ähnlich im Stil der Auswahl.


2

Super einfach:

var state = false;
$("a").click(function () {
    state = !state;
    $("select").prop("size", state ? $("option").length : 1);
});

1
Das ist nicht dasselbe wie das Öffnen. Wenn sich ein Listenfeld am Ende der Seite befindet und ich es öffne, wird es nach oben geöffnet. Wenn ich die Größe ändere, "öffnet" es sich nach unten, wo ich klicken kann. nicht gut
ekkis

@ekkis Das erläuterte Verhalten kann auf verschiedenen Geräten und Browsern variieren. Ich habe meine vorgeschlagene Lösung mit Firefox, Google Chrome und Opera auf dem Desktop und Safari auf dem Handy getestet, wo sie wie erwartet funktioniert. Das Scroll-Sprung könnte durch Speichern / Wiederherstellen der Scroll-Offset auf Öffnen / Schließen oder vielleicht durch die Verwendung leicht behoben scrollIntoViewauf der <select>.
Yckart

1

Wie bereits erwähnt, können Sie ein Programm nicht programmgesteuert <select>mit JavaScript öffnen .

Sie können jedoch selbst schreiben <select>und das gesamte Erscheinungsbild selbst verwalten. So etwas wie das, was Sie für die Suchbegriffe zur automatischen Vervollständigung bei Google oder Yahoo! oder das Feld Nach Standort suchen bei The Weather Network .

Ich habe hier eine für jQuery gefunden . Ich habe keine Ahnung, ob es Ihren Anforderungen entspricht, aber selbst wenn es Ihren Anforderungen nicht vollständig entspricht, sollte es möglich sein, es so zu ändern, dass es sich als Ergebnis einer anderen Aktion oder eines anderen Ereignisses öffnet. Dieser sieht tatsächlich vielversprechender aus.


0

Ich habe gerade hinzugefügt

select = $('#' + id);
length = $('#' + id + ' > option').length;
if (length > 20)
    length = 20;
select.attr('size', length);
select.css('position', 'absolute');
select.focus();

und in die Auswahl hinzufügen

onchange="$(this).removeAttr('size');"
onblur="$(this).removeAttr('size');"

um das gleiche Aussehen wie das klassische zu machen (überlappen Sie den Rest von HTML)


-1

Vielleicht zu spät, aber so habe ich es gelöst: http://jsfiddle.net/KqsK2/18/

$(document).ready(function() {
  fixSelect(document.getElementsByTagName("select"));
                      });                       

   function fixSelect(selectList)
            {
            for (var i = 0; i != selectList.length; i++)
              {

                 setActions(selectList[i]);
              }
            }


   function setActions(select)
            {
               $(select).click(function() {
                   if (select.getElementsByTagName("option").length == 1)
                        {
                          active(select);
                        }
                      });
                $(select).focus(function() {
                       active(select);
                       });
                $(select).blur(function() {
                       inaktiv(select);
                       });
                $(select).keypress(function(e) {
                      if (e.which == 13) {

                      inaktiv(select);
                          }
                       });
                  var optionList = select.getElementsByTagName("option");

                  for (var i = 0; i != optionList.length; i++)
                           {
                                setActionOnOption(optionList[i], select);
                           }
      }

  function setActionOnOption(option, select)
      {
                    $(option).click(function() {
                                inaktiv(select);
                        });
      }

  function active(select)
      {
          var temp = $('<select/>');
              $('<option />', {value: 1,text:$(select).find(':selected').text()}).appendTo(temp);
               $(temp).insertBefore($(select));

              $(select).attr('size', select.getElementsByTagName('option').length);
              $(select).css('position', 'absolute');
              $(select).css('margin-top', '-6px');
              $(select).css({boxShadow: '2px 3px 4px #888888'});



                        }

        function inaktiv(select)
                   {
                 if($(select).parent().children('select').length!=1)
                     {
                                             select.parentNode.removeChild($(select).parent().children('select').get(0));
                                }
                $(select).attr('size', 1);
                $(select).css('position', 'static');
                $(select).css({boxShadow: ''});
                $(select).css('margin-top', '0px');

                  }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.