Posso aprire un elenco a discesa utilizzando jQuery


85

Per questo elenco a discesa in HTML:

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

Vorrei aprire l'elenco (lo stesso del clic sinistro su di esso). È possibile utilizzare JavaScript (o più specificamente jQuery)?



4
Qualcuno può spiegare perché questo è così impossibile?
SpaceBeers


Risposte:


18

Puoi facilmente simulare un clic su un elemento , ma un clic su a <select>non aprirà il menu a discesa.

L'utilizzo di più selezioni può essere problematico. Forse dovresti considerare i pulsanti di opzione all'interno di un elemento contenitore che puoi espandere e contrarre secondo necessità.


70

Stavo cercando di trovare la stessa cosa e sono rimasto deluso. Ho finito per cambiare la dimensione dell'attributo per la casella di selezione in modo che sembri aprirsi

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

e poi quando hai finito

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

12
l'aggiunta di un sizeattributo al menu a discesa converte effettivamente il menu a discesa in Listbox .. quindi si espande ..
Mayank Pathak

Ottima soluzione. Devi solo fare i conti con il fatto che la casella di riepilogo occupa più spazio sulla pagina (anziché espandersi sul contenuto come un menu a discesa) e, quindi, spinge il contenuto verso il basso.
zkent

Per coloro che possono solo immaginare come appare, l'aspetto è una casella multi-selezione dopo aver utilizzato questo approccio (ma non multi-selezionabile) che personalmente ritengo sia più stabile rispetto all'apertura del menu a discesa.
Siwei

Questo tecnicamente funziona, ma 1) ora hai una brutta barra di scorrimento sul lato e 2) lo z-index è fissato alla selezione originale, quindi non si comporta nemmeno come un popup a discesa.
BoB3K

Grazie per questo ... Ho passato 2 ore a provare vari popover ecc per avvisare gli utenti che devono scegliere qualcosa. Niente funzionava bene ... questo è un promemoria sottile ma deciso. E funziona (a differenza di altre soluzioni traballanti).
11 °

15

Ho riscontrato lo stesso problema e ho una soluzione. Una funzione chiamata ExpandSelect () che emula il clic del mouse sull'elemento "seleziona", lo fa creando un altro <select>elemento che è assolutamente posizionato e ha più opzioni visibili contemporaneamente impostando l' sizeattributo. Testato in tutti i principali browser: Chrome, Opera, Firefox, Internet Explorer. Spiegazione di come funziona, insieme al codice qui:

Modifica (il collegamento è stato interrotto) .

Ho creato un progetto su Google Code, cerca il codice lì:

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

Screenshot

C'è una piccola differenza nella GUI quando si emula il clic, ma non importa, guardalo tu stesso:

Quando si fa clic con il mouse:

MouseClicking
(fonte: googlecode.com )

Durante l'emulazione del clic:

EmulatingClic
(fonte: googlecode.com )

Altri screenshot sul sito web del progetto, link sopra.


2
Puoi pubblicare un jsfiddle per questo?
Jay Sullivan

9

Questo è migliorato dalle risposte appena sopra e utilizza la lunghezza / numero di opzioni per conformarsi a quante opzioni ci sono effettivamente.

Spero che questo aiuti qualcuno a ottenere i risultati di cui ha bisogno!

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

9

Questo dovrebbe coprirlo:

 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

Questo potrebbe essere associato, ad esempio, a un evento di pressione di un tasto, quindi quando l'elemento è attivo l'utente può digitare e si espanderà automaticamente ...

--Contesto--

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

ha funzionato per me! ogni altra risposta ha suggerito che non c'è modo di attivare una selezione ma ne hai trovata una, ci sono degli svantaggi in questo approccio?
kittyminky

Sì - interferisce con gli eventi di tabulazione (credo!), Dipende dalle tue esigenze - ma ha funzionato come previsto - ma non si adattava alle nostre altre esigenze.
Stuart.Sklinar

Ha funzionato per me. Se si chiama da un gestore di eventi diverso, ricordarsi di estrarre l'elemento dom -$('#select_element').get(0).dispatchEvent(event);
BoB3K

questo non funziona per me. in esecuzione su Chrome 56.0.2924 su OSX
ekkis

1
questo non funziona per me. Sembrava promettente però.
user3335999

5

Semplice un modo facile.

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
}

Ora puoi chiamare il tuo DropDown proprio in questo modo

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

Funziona perfettamente per me.

Forse meglio, perché non hai problemi con la posizione degli altri elementi nella pagina.

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

Cambia l'ID in un valore fisso mybe non è intelligente ma spero che tu veda l'idea.


4

Non è possibile per javascript "fare clic" su un elemento (puoi attivare il file allegato onclick evento , ma non puoi letteralmente fare clic su di esso)

Per visualizzare tutti gli elementi nell'elenco, trasforma l'elenco in un multipleelenco e aumentane le dimensioni, in questo modo:

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

Aggiunge una barra di scorrimento dopo 4 elementi in IE6, 7 e 8b2 e Opera 9.62. Aggiunge una barra di scorrimento dopo 10 elementi in Safari per Windows e Google Chrome.
Grant Wagner,

2

No non puoi.

Puoi cambiare la dimensione per renderla più grande ... simile all'idea di Dreas, ma è la dimensione che devi cambiare.

<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

Ho provato a utilizzare la risposta di mrperfect e ho avuto un paio di problemi. Con un paio di piccoli cambiamenti, sono riuscito a farlo funzionare per me. L'ho appena cambiato in modo che lo facesse solo una volta. Una volta uscito dal menu a discesa, tornerà al normale metodo di menu a discesa.

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

Una cosa a cui questo non risponde è ciò che accade quando si fa clic su una delle opzioni nell'elenco di selezione dopo aver impostato size = n e posizionato in modo assoluto.

Poiché l'evento di sfocatura lo rende size = 1 e lo cambia di nuovo a come appare, dovresti avere qualcosa di simile anche a questo

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

Inoltre, se hai problemi con l'elenco di selezione posizionato in modo assoluto visualizzato dietro altri elementi, inserisci semplicemente un file

z-index: 100;

o qualcosa del genere nello stile della selezione.


2

Super semplice:

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

1
non è la stessa cosa che aprirlo. quando una casella di riepilogo è in fondo alla pagina, se la apro, si apre verso l'alto. se ne cambio le dimensioni, si "apre" verso il basso, sotto dove posso cliccare. non va bene
ekkis

@ekkis Il comportamento spiegato può variare su diversi dispositivi e browser. Ho testato la mia soluzione proposta con Firefox, Google Chrome e Opera su desktop e Safari su dispositivo mobile, dove funziona come previsto. Lo scroll-jump può essere facilmente risolto salvando / ripristinando lo scroll-offset in apertura / chiusura o magari usando scrollIntoViewsul <select>.
yckart

1

Come è stato affermato, non è possibile aprire a livello di <select>codice un JavaScript.

Tuttavia, potresti scrivere il tuo <select>gestendo l'intero aspetto e sentire te stesso. Qualcosa di simile a quello che vedi per i termini di ricerca del completamento automatico su Google o Yahoo! o la casella Cerca posizione in The Weather Network .

Ne ho trovato uno per jQuery qui . Non ho idea se soddisferà le tue esigenze, ma anche se non soddisfa completamente le tue esigenze, dovrebbe essere possibile modificarlo in modo che si apra come risultato di qualche altra azione o evento. Questo in realtà sembra più promettente.


0

ho appena aggiunto

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

e aggiungi nel file select

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

per avere lo stesso aspetto di quello classico (sovrapponi al resto dell'html)


-1

Forse tardi, ma è così che l'ho risolto: 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');

                  }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.