¿Puedo abrir una lista desplegable usando jQuery?

85

Para esta lista desplegable en HTML:

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

Me gustaría abrir la lista (lo mismo que hacer clic izquierdo en ella). ¿Es esto posible usando JavaScript (o más específicamente jQuery)?

Jon Tackabury
fuente

Respuestas:

18

Puede simular fácilmente un clic en un elemento , pero un clic en un <select>no abrirá el menú desplegable.

El uso de selecciones múltiples puede resultar problemático. Quizás debería considerar los botones de radio dentro de un elemento contenedor que puede expandir y contraer según sea necesario.

ieure
fuente
70

Estaba tratando de encontrar lo mismo y me decepcioné. Terminé cambiando el tamaño del atributo para el cuadro de selección para que parezca que se abre

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

y luego cuando hayas terminado

$('#countries').attr('size',1);
CommentLuv
fuente
12
agregar un sizeatributo al menú desplegable en realidad convierte el menú desplegable en Listbox ... así se expande ..
Mayank Pathak
Gran solucion Solo tiene que lidiar con el hecho de que el cuadro de lista ocupa más espacio en la página (en lugar de expandirse sobre el contenido como un menú desplegable) y, por lo tanto, empuja el contenido hacia abajo.
zkent
Para aquellos que solo pueden imaginar cómo se ve, la apariencia es un cuadro de selección múltiple después de usar este enfoque (pero no de selección múltiple) que personalmente creo que es más estable que abrir el menú desplegable.
Siwei
Esto técnicamente funciona, pero 1) ahora tiene una barra de desplazamiento fea en el costado, y 2) el índice z está fijo en la selección original, por lo que tampoco actúa como un menú desplegable emergente.
BoB3K
Gracias por esto ... He pasado 2 horas probando varios popovers, etc. para alertar a los usuarios de que deben elegir algo. Nada funcionaba bien ... este es un recordatorio sutil pero firme. Y funciona (a diferencia de otras soluciones escamosas).
11 de
15

Me he encontrado con el mismo problema y tengo una solución. Una función llamada ExpandSelect () que emula el clic del mouse en el elemento "seleccionar", lo hace creando otro <select>elemento que está absolutamente posicionado y tiene múltiples opciones visibles a la vez configurando el sizeatributo. Probado en los principales navegadores: Chrome, Opera, Firefox, Internet Explorer. Explicación de cómo funciona, junto con el código aquí:

Editar (el enlace estaba roto) .

He creado un proyecto en Google Code, busque el código allí:

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

Capturas de pantalla

Hay una pequeña diferencia en la GUI al emular un clic, pero realmente no importa, véalo usted mismo:

Al hacer clic con el mouse:

RatónHacer clic
(fuente: googlecode.com )

Al emular, haga clic en:

EmulandoHaciendo clic
(fuente: googlecode.com )

Más capturas de pantalla en el sitio web del proyecto, enlace arriba.

Czarek Tomczak
fuente
2
¿Puedes publicar un jsfiddle para esto?
Jay Sullivan
9

Esto se arregla a partir de las respuestas anteriores y usa la longitud / número de opciones para ajustarse a la cantidad de opciones que realmente hay.

¡Espero que esto ayude a alguien a obtener los resultados que necesita!

    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();
    }
Chris K
fuente
9

Esto debería cubrirlo:

 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

Esto podría estar vinculado, por ejemplo, a un evento de pulsación de tecla, por lo que cuando el elemento tiene el foco, el usuario puede escribir y se expandirá automáticamente ...

--Contexto--

  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);
 });
Stuart.Sklinar
fuente
¡trabajó para mi! Todas las demás respuestas sugirieron que no hay forma de activar una selección, pero encontró una, ¿hay algún inconveniente en este enfoque?
kittyminky
Sí, interfiere con los eventos de tabulación (¡creo!), Depende de sus necesidades, pero funcionó como se esperaba, pero no se ajustaba a nuestras otras necesidades.
Stuart.Sklinar
Trabajó para mi. Si llama desde un controlador de eventos diferente, recuerde sacar el elemento dom -$('#select_element').get(0).dispatchEvent(event);
BoB3K
esto no funciona para mí. ejecutándose en Chrome 56.0.2924 en OSX
ekkis
1
esto no funciona para mí. Aunque parecía prometedor.
user3335999 hace
5

Sencillo y sencillo.

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
}

Ahora puedes llamar a tu DropDown así

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

Funciona perfecto para mi.

Quizás mejor, porque no tiene problemas con la posición de los otros elementos en la página.

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

Cambie la ID a un valor fijo que no sea inteligente, pero espero que vea la idea.

Señor perfecto
fuente
4

No es posible que JavaScript haga "clic" en un elemento (puede activar el onclickevento adjunto , pero no puede literalmente hacer clic en él)

Para ver todos los elementos de la lista, convierta la lista en una multiplelista y aumente su tamaño, así:

<select id="countries" multiple="multiple" size="10">
<option value="1">Country</option>
</select>
Andreas Grech
fuente
Agrega una barra de desplazamiento después de 4 elementos en IE6, 7 y 8b2 y Opera 9.62. Agrega una barra de desplazamiento después de 10 elementos en Safari para Windows y Google Chrome.
Grant Wagner
2

No, no puedes.

Puede cambiar el tamaño para hacerlo más grande ... similar a la idea de Dreas, pero es el tamaño que necesita cambiar.

<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>
scunliffe
fuente
2

Intenté usar la respuesta de mrperfect y tuve un par de fallas. Con un par de pequeños cambios, pude hacer que funcionara para mí. Lo cambié para que solo lo hiciera una vez. Una vez que salga del menú desplegable, volverá al método habitual de menús desplegables.

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

Una cosa que esto no responde es lo que sucede cuando hace clic en una de las opciones en la lista de selección después de haber hecho su tamaño = n y haberlo hecho de posicionamiento absoluto.

Debido a que el evento de desenfoque hace que sea de tamaño = 1 y lo vuelve a cambiar a su apariencia, también debería tener algo como esto

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

Además, si tiene problemas con la lista de selección de posición absoluta que se muestra detrás de otros elementos, simplemente coloque un

z-index: 100;

o algo así al estilo del selecto.

vipergtsrz
fuente
2

Súper simple:

var state = false;
$("a").click(function () {
    state = !state;
    $("select").prop("size", state ? $("option").length : 1);
});
yckart
fuente
1
eso no es lo mismo que abrirlo. cuando un cuadro de lista está en la parte inferior de la página, si lo abro, se abre hacia arriba. si cambio su tamaño, se "abre" hacia abajo, debajo de donde puedo hacer clic. no es bueno
ekkis
@ekkis El comportamiento explicado puede variar en diferentes dispositivos y navegadores. He probado mi solución propuesta con Firefox, Google Chrome y Opera en el escritorio y Safari en el móvil, donde funciona como se esperaba. El salto de desplazamiento se puede arreglar fácilmente guardando / restaurando el desplazamiento de desplazamiento en abrir / cerrar o tal vez usando scrollIntoViewen <select>.
yckart
1

Como se ha dicho, no se puede abrir <select>mediante programación usando JavaScript.

Sin embargo, puede escribir su propio <select>diseño y administrar todo el aspecto y la sensación. Algo parecido a lo que ve para los términos de búsqueda de autocompletar en Google o Yahoo! o el cuadro Buscar ubicación en The Weather Network .

Encontré uno para jQuery aquí . No tengo idea de si satisfaría sus necesidades, pero incluso si no satisface completamente sus necesidades, debería ser posible modificarlo para que se abra como resultado de alguna otra acción o evento. Este en realidad parece más prometedor.

Grant Wagner
fuente
0

acabo de agregar

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

y agregar en la selección

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

para hacer la misma apariencia que el clásico (superponer el resto de html)

Emmanuel
fuente
-1

Quizás tarde, pero así es como lo resolví: 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');

                  }
Johan Nordli
fuente