Jak programowo możesz nakazać select
rozwijaniu kodu HTML (na przykład po najechaniu myszą)?
Jak programowo możesz nakazać select
rozwijaniu kodu HTML (na przykład po najechaniu myszą)?
Odpowiedzi:
Nie możesz tego zrobić za pomocą tagu wyboru HTML, ale możesz to zrobić za pomocą JavaScript i HTML. Istnieje wiele różnych formantów, które to robią - na przykład lista „sugestii” dołączona do wpisu SO „interesujący / ignorowany tag” lub wyszukiwanie adresów e-mail w Gmailu.
Istnieje wiele kontrolek JavaScript + HTML, które zapewniają tę możliwość - poszukaj opcji autouzupełniania dla pomysłów.
Zobacz ten link do kontroli autouzupełniania ... http://ajaxcontroltoolkit.codeplex.com/
Kiedyś było to faktycznie możliwe w przypadku HTML + Javascript, mimo że ludzie mówią, że tak nie jest, ale zostało to później wycofane i teraz nie działa.
Jednak działało to tylko w Chrome. Przeczytaj więcej, jeśli jesteś zainteresowany.
Zgodnie z projektem roboczym W3C dla HTML5, sekcja 3.2.5.1.7. Zawartość interaktywna :
Niektóre elementy w HTML mają zachowanie aktywacyjne, co oznacza, że użytkownik może je aktywować. Powoduje to wyzwolenie sekwencji zdarzeń zależnych od mechanizmu [...] aktywacji, na przykład za pomocą klawiatury, poleceń głosowych lub kliknięć myszą .
Gdy użytkownik wyzwala element ze zdefiniowanym zachowaniem aktywacyjnym w sposób inny niż kliknięcie go, domyślną akcją zdarzenia interakcji musi być uruchomienie syntetycznych kroków aktywacji kliknięcia na elemencie.
<select>
będąc treścią interaktywną wierzyłem, że możliwe jest programowe wyświetlanie jej <option>
s. Po kilku godzinach zabawy odkryłem, że używanie document.createEvent()
i .dispatchEvent()
działa.
To powiedziawszy, czas na demo. Oto działające Fiddle.
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);
};
Jeśli ktoś znajdzie sposób na zrobienie tego samego, ale nie w Chrome, możesz zmodyfikować to skrzypce . Wcześniejsze
IE10
, FF 24
. Działa na: Chrome 30
, Safari 6.0.5
,Opera 16
Odpowiedź Xaviera Ho obejmuje sposoby rozwiązania problemu w większości obecnie dostępnych przeglądarek. Jednak dobrą praktyką jest „nie wysyłanie / modyfikowanie” zdarzeń przez JavaScript . (Jak mousedown
w tym przypadku)
Od wersji 53 i nowszych przeglądarka Google Chrome nie będzie wykonywać domyślnych czynności w przypadku niezaufanych zdarzeń . Takich jak zdarzenia utworzone lub zmodyfikowane przez skrypt lub wysłane za pomocą dispatchEvent
metody. Ta zmiana dotyczy dostosowania do przeglądarek Firefox i IE, które, jak sądzę, już nie wykonują akcji.
Do celów testowych Fiddle podał, że odpowiedź Xaviera nie będzie działać w Chrome 53+. (Nie testuję tego FF i IE).
Linki w celach informacyjnych:
https://www.chromestatus.com/features/5718803933560832 https://www.chromestatus.com/features/6461137440735232
InitMouseEvent również jest przestarzałe
To jest najbliższy, jaki mogłem uzyskać, zmienić rozmiar elementu onmouseover i przywrócić rozmiar 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>
Mam ten sam problem, a łatwiejszy sposób na jego rozwiązanie to HTML i CSS.
select{
opacity: 0;
position: absolute;
}
<select>
<option>option 1</option>
<option>option 2</option>
<option>option 3</option>
</select>
<button>click</button>
<div style='position:relative'><select> <option>option 1</option> <option>option 2</option> <option>option 3</option> </select> <button>click</button></div>
@DavidPortabella
Myślę, że w Chrome nie jest to już możliwe.
Wygląda na to, że wersja 53 Chrome wyłącza tę funkcjonalność, jak stwierdził Asim K.
Zgodnie ze specyfikacją http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events
Zaufane zdarzenia nie powinny uruchamiać domyślnej akcji (z wyjątkiem zdarzenia kliknięcia).
Jednak włączyli to w przeglądarce internetowej, ale nie testowałem tego.
Odkryliśmy, że niektóre wyświetlenia internetowe używają w nich funkcji szybkiego kliknięcia, a ze względu na ryzyko złamania zamierzamy zezwolić na przesuwanie myszy na wybranych elementach, nawet jeśli nie są zaufane.
W tej dyskusji pomysł, aby umożliwić programistom otwieranie listy rozwijanej programowo, zostaje porzucony.
Jeśli ktoś nadal tego szuka:
<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; });
});
Aktualizacja:
Jeden, dopóki nie ma idealnego rozwiązania tego problemu, ale możesz spróbować uniknąć tego scenariusza. Dlaczego chcesz to zrobić. Kilka miesięcy temu zastanawiałem się nad rozwiązaniem, które pozwoliłoby stworzyć wybraną wtyczkę dla urządzeń mobilnych
https://github.com/HemantNegi/jquery.sumoselect
Ostatecznie skończyło się na zamaskowaniu niestandardowego div (lub dowolnego innego elementu) przezroczystym elementem select, tak aby mógł bezpośrednio współdziałać z użytkownikiem.
iniMouseEvent
wydaje się działać, ale dlaczego $(select).trigger('mousedown')
nie działa?
Oto najlepszy sposób, jaki znalazłem. UWAGA Działa tylko z IE w systemie Windows, a Twoja sieć prawdopodobnie musiałaby znajdować się w bezpiecznej strefie - ponieważ mamy dostęp do powłoki. Sztuczka polega na tym, że ALT-strzałka w dół jest klawiszem skrótu do otwierania listy rozwijanej wyboru.
<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>
Przestań myśleć, że jedna rzecz jest niemożliwa, nic nie jest niemożliwe do zrobienia, kiedy chcesz.
Użyj tej rozszerzającej funkcji JS stworzonej przez faceta.
http://code.google.com/p/expandselect/
Uwzględnij ten kod JS i po prostu wywołaj przekazanie parametru jako wybranego identyfikatora, na przykład:
ExpandSelect(MySelect)
<SELECT>
upadku a. Jak wyraźnie stwierdza się, że „przeglądarki nie pozwalają na rozwijanie <select> w czystym javascript, tę kontrolkę można rozwinąć tylko poprzez bezpośrednie kliknięcie myszą”. Więc jest to „niemożliwe”! Zamiast tego JS stwierdza: „Imitujemy rozszerzoną kontrolkę <select>, tworząc kolejną selekcję z wieloma opcjami wyświetlanymi jednocześnie ...” Co jest zupełnie inne i może, ale nie musi, być akceptowalne w Twoim przypadku użycia ...
Może się mylę, ale nie wierzę, że jest to możliwe przy domyślnym polu wyboru. Możesz zrobić coś z JS i CSS, co da pożądany rezultat, ale nie (o ile wiem) waniliowy SELECT.
Otwarcie opcji „HTML select” jest możliwe dzięki niektórym obejściom wspomnianym w tym pytaniu i podobnym. Jednak prostszym sposobem na zrobienie tego jest dodanie do projektu biblioteki wyboru, takiej jak „select2” lub „selected”. Na przykład, programowe otwarcie select2 byłoby tak proste, jak:
$('#target-select').select2('open');
Nie jest to dokładnie to, o co prosiłeś, ale podoba mi się to rozwiązanie ze względu na jego prostotę. W większości przypadków, gdy chcę zainicjować listę rozwijaną, dzieje się tak, ponieważ sprawdzam, czy użytkownik faktycznie dokonał wyboru. Zmieniam rozmiar menu rozwijanego i ustawiam na nim ostrość, co ładnie podkreśla to, co pominęli:
$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();
<select>
, ponieważ ludzie oczekują, że będzie się zachowywać w określony sposób, a Ty będziesz uniemożliwiać użytkownikom innych platform (takich jak urządzenia mobilne) korzystanie z Twojej witryny.