Как можно программно указать HTML SELECT, чтобы он выпал (например, из-за наведения курсора мыши)?


106

Как можно программно указать HTML, selectчтобы он раскрылся (например, при наведении курсора мыши)?


6
Я бы рекомендовал не связываться с поведением по умолчанию <select>, так как люди ожидают, что он будет вести себя определенным образом, и вы не позволите людям на других платформах (например, мобильных) использовать ваш сайт.
Брайан Донован,

1
@BrianDonovan: Это не значит, что вы не можете добавить немного обработки для этого.
Морг.

@shasikanth: ваша скрипка не работает ни в Firefox 37 nr, ни в Chrome
rubo77

Хорошо, я думаю, что скрипка работала раньше. В любом случае я бы удалил свой комментарий здесь.
shasi kanth

@BrianDonovan На самом деле, мобильный - хороший пример использования этого ... программно генерирует выбор, а затем автоматически всплывает его параметры.
Майкл

Ответы:


16

Вы не можете сделать это с помощью тега выбора HTML, но вы можете сделать это с помощью JavaScript и HTML. Для этого существует множество существующих элементов управления - например, список «предложений», прикрепленный к записи SO «интересный / игнорируемый тег», или поиск адресов электронной почты в Gmail.

Есть много элементов управления JavaScript + HTML, которые предоставляют такую ​​возможность - ищите элементы управления автозаполнением для идей.

См. Эту ссылку для элемента управления автозаполнением ... http://ajaxcontroltoolkit.codeplex.com/


6
это позор - мобильные браузеры предоставляют список прокрутки для конкретной ОС, и мне нужно, чтобы он всплывал автоматически.
Майкл

120

Раньше это было возможно с HTML + Javascript, несмотря на то, что везде люди говорят, что это не так, но позже он устарел и не работает сейчас.

Однако это работало только в Chrome. Прочтите больше, если вам интересно.


Согласно рабочему проекту W3C для HTML5, раздел 3.2.5.1.7. Интерактивный контент :

Определенные элементы в HTML имеют поведение активации, что означает, что пользователь может их активировать. Это запускает последовательность событий, зависящих от механизма [...] активации, например, с помощью клавиатуры или голосового ввода, или посредством щелчков мышью .

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

<select>будучи интерактивным контентом, я полагал, что его файлы <option>s. После нескольких часов игры я обнаружил, что с помощью document.createEvent()и .dispatchEvent()работает.

Тем не менее, время демонстрации. Вот рабочий скрипт.


HTML:

<select id="dropdown">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" onclick="runThis()">Show dropdown items</button>​

Javascript:

// <select> element displays its options on mousedown, not click.
showDropdown = function (element) {
    var event;
    event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);
};

// This isn't magic.
window.runThis = function () { 
    var dropdown = document.getElementById('dropdown');
    showDropdown(dropdown);
};

Если кто-то найдет способ сделать то же самое, но не в Chrome, пожалуйста, не стесняйтесь изменять эту скрипку . Взаимодействие с другими людьми


2
Спасибо тебе за это! Мне нужно было эмулировать поведение IE ALT + DOWN ARROW именно в Chrome.
J Bryan Price

3
Хотел бы я добавить к вашей награде за это. Огромное спасибо.
Адам Таттл,

7
Не работает: IE10, FF 24. Работы по: Chrome 30, Safari 6.0.5,Opera 16
hitautodestruct

2
@AdamTuttle Он не работает и на Android 4.4.2
Мирко

42
Теперь он устарел в Chrome 53+
Вашингтон Гедес,

47

В ответе Ксавьера Хо рассказывается, как решить эту проблему в большинстве существующих браузеров. Но это хорошая практика - больше не отправлять / изменять события с помощью JavaScript . (Подобно,mousedown в этом случае)

Начиная с версии 53+, Google Chrome не будет выполнять действия по умолчанию для ненадежных событий . Такие как события, созданные или измененные сценарием или отправленные черезdispatchEvent метода. Это изменение сделано для согласования с Firefox и IE, которые, как мне кажется, уже не выполняют действие.

В целях тестирования Fiddle предоставил ответ Ксавьера не будет работать в Chrome 53+. (Я не тестирую FF и IE).

Ссылки для справки:

https://www.chromestatus.com/features/5718803933560832 https://www.chromestatus.com/features/6461137440735232

И initMouseEvent также устарел


Можно ли это сделать с помощью MouseEvents? developer.mozilla.org/en-US/docs/Web/API/MouseEvent
Шамал Перера

Я так не думаю. ты что-нибудь пробовал?
Асим К.Т.

29

Это самое близкое, что я мог найти, изменить размер элемента onmouseover и восстановить размер onmouseout:

       <select onMouseOut="this.size=1;" onMouseOver="this.size=this.length;">
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option>5</option>
      </select>


13
или <ВЫБРАТЬ onMouseOut = "this.size = 1;" onMouseOver = "this.size = this.length;"> ... </SELECT>
RealHowTo,

1
Также необходимо добавить onchange = "this.size = 1", чтобы меню сворачивалось, как только будет сделан выбор. Также необходимо настроить правила CSS элемента.
GM2008 06

Вроде работает. Ширина выбора сжимается, а затем это вызывает событие выхода мыши, сбрасывающее выделение до его исходной ширины. Это вызывает судорожный эффект. Установка фиксированной ширины, кажется, решает эту проблему. При наличии более чем нескольких элементов список расширяется за пределы представления.
1,21 гигаватт

16

У меня такая же проблема, и более простой способ решения, который я нашел, был с помощью html и css.

select{
  opacity: 0;
  position: absolute;
}
<select>
  <option>option 1</option>
  <option>option 2</option>
  <option>option 3</option>
</select>
<button>click</button>


2
Я давно не видел этот подход, и это ссылка, которую я надеялся найти. Лучше с дополнительным CSS, чтобы соответствовать размеру скрытого выбора для запуска (кнопка, img, div и т. Д.) ... 1) Обеспечивает триггер заполнения интерактивной области 2) Меню открывается непосредственно под триггером. Примечание. Также может потребоваться добавить z-index, чтобы интерактивная область была самым верхним элементом в некоторых макетах.
Mavelo

однако, если пользователь прокручивает страницу вниз, кнопка перемещается соответствующим образом, но выбор остается в том же положении; не совсем так, как ожидалось. любое решение для этого?
Дэвид

Идеальное решение. Но лучше, может быть, оберните кнопку и выберите в div вот так <div style='position:relative'><select> <option>option 1</option> <option>option 2</option> <option>option 3</option> </select> <button>click</button></div>@DavidPortabella
Muhammet Can TONBUL

8

Я думаю, что в Chrome это больше невозможно.

Похоже, что версия 53 Chrome отключает эту функцию, как заявил Асим К. Т.

Согласно спецификации http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events

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

Однако они включили его в веб-просмотре, но я не тестировал это.

Мы обнаружили, что некоторые веб-просмотры используют внутри себя fastclick, и из-за риска поломки мы собираемся разрешить mousedown для выбранных элементов, даже если они не являются доверенными.

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


7

Если кто-то все еще ищет это:

<select id="dropdown">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" >Show dropdown items</button>

Javascript:

var is_visible=false; 

$(document).ready(function(){

    $('#fire').click(function (e) { 
    var element = document.getElementById('dropdown');


    if(is_visible){is_visible=false; return;}
    is_visible = true;

    var event;
    event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);

    /* can be added for i.e. compatiblity.
      optionsSelect.focus();
       var WshShell = new ActiveXObject("WScript.Shell");
       WshShell.SendKeys("%{DOWN}");
    */
    e.stopPropagation();
    return false;
});


$(document).click(function(){is_visible=false; });
});

Обновить:

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

https://github.com/HemantNegi/jquery.sumoselect

Наконец, закончилось маскирование настраиваемого div (или любого другого элемента) прозрачным элементом выбора, чтобы он мог напрямую взаимодействовать с пользователем.


1
Плагины, такие как github.com/HemantNegi/jquery.sumoselect, - единственное кроссбраузерное решение, которое на самом деле выглядит лучше, чем элемент управления по умолчанию.
Джастин

iniMouseEventвроде работает, но почему $(select).trigger('mousedown')не работает?
coding_idiot 09

3

Вот лучший способ, который я нашел. ПРИМЕЧАНИЕ. Он работает только с IE в Windows, и ваш Интернет, вероятно, должен находиться в безопасной зоне, потому что мы получаем доступ к оболочке. Хитрость в том, что ALT-стрелка вниз - это сочетание клавиш для открытия выпадающего списка.

<button id="optionsButton" style="position:absolute;top:10px;left:10px;height:22px;width:100px;z-index:10" onclick="doClick()">OPTIONS</button>
<select id="optionsSelect" style="position:absolute;top:10px;left:10px;height:20px;width:100px;z-index:9">
    <option>ABC</option>
    <option>DEF</option>
    <option>GHI</option>
    <option>JKL</option>
</select>
<script type="text/javascript">
   function doClick() {
       optionsSelect.focus();
       var WshShell = new ActiveXObject("WScript.Shell");
       WshShell.SendKeys("%{DOWN}");
   }
</script>

3
Это не сработает, если вы этого не сделаете .
Knu

1
@Knu Internet Explorer автоматически добавляет идентификаторы элементов в качестве ссылок на элемент в глобальную область видимости.
user2428118

@KlasMellbourn наверное. Сейчас они пытаются сделать свои браузеры более совместимыми. Используйте указанное решение "размера".
sproketboy 05

2

Перестаньте думать, что одно невозможно, что невозможно сделать, когда вы этого хотите.

Используйте эту расширенную функцию JS, созданную парнем.

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

Включите этот JS и просто вызовите его, передав параметр в качестве выбранного идентификатора, например:

ExpandSelect(MySelect)

2
Чтобы было ясно, что JS не вызывает <SELECT>выпадение. В нем прямо говорится: «Браузеры не позволяют расширять <select> в чистом javascript, этот элемент управления можно расширить, только щелкнув по нему напрямую с помощью мыши». Так что это «невозможно»! Вместо этого JS заявляет: «Мы имитируем расширенный элемент управления <select>, создавая другой элемент select с несколькими отображаемыми одновременно ...» Что совсем другое, и может или не может быть приемлемым для вашего случая использования ....
JonBrave

1

Я могу ошибаться, но я не верю, что это возможно с полем выбора по умолчанию. Вы могли бы сделать что-то с JS и CSS, которое достигнет желаемого результата, но не (насколько мне известно) ванильный SELECT.


0

Открыть «HTML-выбор» можно с помощью некоторых обходных путей, упомянутых в этом вопросе и подобных. Однако более простой способ сделать это - добавить в проект выбранную библиотеку, например «select2» или «selected». Например, программно открыть select2 так же просто:

$('#target-select').select2('open');

-2

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

$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();

Не уверен, почему вас проголосовали против, поскольку это не «худший» способ сделать это. Я бы избегал этого просто потому, что это меняет расположение окружающих элементов. Хотя я думаю, что решение от @CMS легче понять с помощью событий focus / blur в элементе управления.
Mavelo
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.