Могу ли я открыть раскрывающийся список с помощью jQuery


85

Для этого раскрывающегося списка в HTML:

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

Я хочу открыть список (аналогично щелчку по нему левой кнопкой мыши). Возможно ли это с помощью JavaScript (или, точнее, jQuery)?



4
Кто-нибудь может объяснить, почему это так невозможно?
SpaceBeers


Ответы:


18

Вы можете легко имитировать щелчок по элементу , но щелчок по нему <select>не открывает раскрывающийся список.

Использование множественного выбора может быть проблематичным. Возможно, вам следует рассмотреть радиокнопки внутри элемента контейнера, который вы можете расширять и сжимать по мере необходимости.


70

Я пытался найти то же самое и разочаровался. Я закончил тем, что изменил размер атрибута для поля выбора, чтобы оно открылось

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

а затем, когда вы закончите

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

12
добавление sizeатрибута в раскрывающийся список фактически преобразует раскрывающийся список в список ... таким образом, он расширяется ..
Mayank Pathak

Отличное решение. Вам просто нужно иметь дело с тем фактом, что список занимает больше места на странице (а не расширяется по содержимому, как раскрывающийся список) и, таким образом, выталкивает содержимое вниз.
zkent

Для тех, кто может только представить, как это выглядит, внешний вид представляет собой поле с множественным выбором после использования этого подхода (но не с множественным выбором), что я лично считаю более стабильным, чем раскрывающееся раскрывающееся меню.
Siwei

Технически это работает, но 1) теперь у вас есть уродливая полоса прокрутки сбоку и 2) z-index зафиксирован на исходном выборе, поэтому он не совсем действует как раскрывающееся всплывающее окно.
BoB3K

Спасибо за это ... Я потратил 2 часа, пробуя различные всплывающие окна и т. Д., Чтобы предупредить пользователей, что им нужно что-то выбрать. Ничего не получалось ... это тонкое, но твердое напоминание. И это работает (в отличие от других нестандартных решений).
11

15

Я столкнулся с той же проблемой, и у меня есть решение. Функция ExpandSelect (), которая имитирует щелчок мышью по элементу «select», она делает это, создавая другой <select>элемент, который абсолютно позиционирован и имеет сразу несколько параметров, видимых путем установки sizeатрибута. Протестировано во всех основных браузерах: Chrome, Opera, Firefox, Internet Explorer. Объяснение того, как это работает, вместе с кодом здесь:

Редактировать (ссылка не работает) .

Я создал проект в Google Code, найдите там код:

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

Скриншоты

При эмуляции щелчка есть небольшая разница в графическом интерфейсе пользователя, но это не имеет особого значения, убедитесь сами:

При щелчке мышью:

MouseClicking
(источник: googlecode.com )

При эмуляции щелчка:

Эмуляция
(источник: googlecode.com )

Больше скриншотов на сайте проекта по ссылке выше.


2
Можете ли вы опубликовать для этого jsfiddle?
Джей Салливан

9

Это сделано из ответов чуть выше и использует длину / количество вариантов, чтобы соответствовать тому, сколько вариантов на самом деле есть.

Надеюсь, это поможет кому-то получить нужные результаты!

    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

Это должно покрыть это:

 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

Это может быть связано, например, с событием нажатия клавиши, поэтому, когда элемент находится в фокусе, пользователь может ввести, и он будет автоматически расширяться ...

--Контекст--

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

у меня сработало! каждый второй ответ предполагал, что нет способа вызвать выбор, но вы его нашли, есть ли у этого подхода какие-либо недостатки?
kittyminky

Ага - это мешает событиям табуляции (я думаю!). Это зависит от ваших потребностей - но это сработало, как ожидалось - но не соответствовало нашим другим потребностям.
Stuart.Sklinar

Работал у меня. При вызове из другого обработчика событий не забудьте вывести элемент dom -$('#select_element').get(0).dispatchEvent(event);
BoB3K

это не работает для меня. работает в Chrome 56.0.2924 на OSX
ekkis

1
это не работает для меня. Хотя выглядело многообещающе.
user3335999

5

Простой легкий способ.

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
}

Теперь вы можете вызвать DropDown вот так

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

Идеально подходит для меня.

Может быть, лучше, потому что у вас нет проблем с положением других элементов на странице.

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

Измените идентификатор на фиксированное значение, я не умно, но я надеюсь, что вы понимаете идею.


4

JavaScript не может «щелкнуть» по элементу (вы можете активировать прикрепленный onclick событие, но вы не можете щелкнуть его буквально)

Чтобы просмотреть все элементы в списке, сделайте список multipleсписком и увеличьте его размер, например:

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

Добавляет полосу прокрутки после 4 элементов в IE6, 7 и 8b2 и Opera 9.62. Добавляет полосу прокрутки после 10 элементов в Safari для Windows и Google Chrome.
Грант Вагнер,

2

Нет, не можешь.

Вы можете изменить размер, чтобы сделать его больше ... похоже на идею Дреаса, но это размер, который вам нужно изменить.

<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

Я попытался использовать ответ mrperfect, и у меня было несколько сбоев. С парой небольших изменений я смог заставить его работать на меня. Я просто изменил его так, чтобы он делал это только один раз. Как только вы выйдете из раскрывающегося списка, он вернется к обычному методу раскрывающихся списков.

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

Одна вещь, на которую это не отвечает, - это то, что происходит, когда вы нажимаете на одну из опций в списке выбора после того, как вы выполнили свой size = n и установили абсолютное позиционирование.

Поскольку событие размытия делает его size = 1 и снова меняет его внешний вид, у вас должно быть что-то вроде этого

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

Кроме того, если у вас возникли проблемы с отображением списка выбора с абсолютным позиционированием за другими элементами, просто поставьте

z-index: 100;

или что-то в этом роде в стиле избранного.


2

Супер просто:

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

1
это не то же самое, что открыть его. когда список находится внизу страницы, если я его открываю, он открывается вверх. если я изменю его размер, он «откроется» вниз, ниже, где я могу щелкнуть. нехорошо
ekkis

@ekkis Объясненное поведение может отличаться на разных устройствах и в разных браузерах. Я протестировал предложенное мной решение с Firefox, Google Chrome и Opera на компьютере и Safari на мобильном устройстве, где оно работает должным образом. Скачок прокрутки можно легко исправить, сохранив / восстановив смещение прокрутки при открытии / закрытии или, возможно, используя scrollIntoViewфайл <select>.
yckart

1

Как было сказано, вы не можете программно открыть <select> помощью JavaScript.

Однако вы можете написать свое собственное <select>управление всем внешним видом и ощущениями. Что-то вроде того, что вы видите для условий поиска с автозаполнением в Google или Yahoo! или поле поиска местоположения в The Weather Network .

Я нашел для JQuery здесь . Я понятия не имею, будет ли он соответствовать вашим потребностям, но даже если он не полностью соответствует вашим потребностям, должна быть возможность изменить его, чтобы он открылся в результате какого-либо другого действия или события. Этот действительно выглядит более многообещающим.


0

я только что добавил

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

и добавить в выбор

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

чтобы иметь тот же вид, что и классический (перекрывать остальную часть html)


-1

Может быть, поздно, но я решил это так: 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');

                  }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.