Чи можу я відкрити випадаючий список за допомогою 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-індекс закріплений за початковим виділенням, тому він не зовсім діє як спливаюче меню.
BoB3K

Дякую за це ... Я витратив 2 години на те, щоб поповернути і т.д., щоб попередити користувачів, що вони повинні щось вибрати. Нічого не працювало добре ... це тонке, але тверде нагадування. І це працює (на відміну від інших нестійких рішень).
11

15

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

Редагувати (посилання було порушено) .

Я створив проект у Google Code, перейдіть за кодом там:

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

Знімки екрана

Існує невелика різниця в графічному інтерфейсі під час емуляції клацання, але це насправді не має значення, переконайтеся самі:

При натисканні миші:

Клацання мишею
(джерело: 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

Так - це заважає подіям із вкладками (я думаю!), Це залежить від ваших потреб - але це спрацювало, як очікувалось - але не відповідало нашим іншим потребам.
Стюарт Склінар,

Працював у мене. Якщо телефонує інший обробник подій, не забудьте витягнути елемент 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");
}

Змініть ідентифікатор на фіксоване значення mybe не розумно, але я сподіваюся, ви бачите idee.


4

Javascript не може "клацнути" по елементу (u може викликати вкладену 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

Ні, ти не можеш.

Ви можете змінити розмір, щоб збільшити його ... схоже на ідею Dreas, але саме цей розмір вам потрібно змінити.

<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

Це одне, на що це не відповідає, - це те, що відбувається, коли ви натискаєте один із параметрів у списку вибору після того, як ви зробили розмір = n і зробили це абсолютним позиціонуванням.

Оскільки подія розмиття призводить до розміру = 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
це не те саме, що відкрити його. коли вікно списку знаходиться внизу сторінки, якщо я його відкриваю, він відкривається вгору. якщо я змінив його розмір, він "відкриється" вниз, нижче, де я можу клацнути. no good
ekkis

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

1

Як уже зазначалося, ви не можете програмно відкрити <select>JavaScript за допомогою 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.