Como você pode definir programaticamente um HTML selectpara cair (por exemplo, devido ao mouseover)?
Como você pode definir programaticamente um HTML selectpara cair (por exemplo, devido ao mouseover)?
Respostas:
Você não pode fazer isso com uma tag de seleção de HTML, mas pode fazer isso com JavaScript e HTML. Há uma variedade de controles existentes que fazem isso - por exemplo, a lista de "sugestões" anexada à entrada do SO "tag interessante / ignorada" ou a pesquisa do Gmail por endereços de e-mail.
Existem muitos controles JavaScript + HTML que fornecem esse recurso - procure por controles de preenchimento automático para ideias.
Veja este link para o controle de preenchimento automático ... http://ajaxcontroltoolkit.codeplex.com/
Isso costumava ser possível com HTML + Javascript, apesar de em todos os outros lugares as pessoas dizerem que não é, mas foi obsoleto mais tarde e não funciona agora.
No entanto, isso só funcionou no Chrome. Leia mais se você estiver interessado.
De acordo com o W3C Working Draft para HTML5, Seção 3.2.5.1.7. Conteúdo interativo :
Certos elementos em HTML têm um comportamento de ativação, o que significa que o usuário pode ativá-los. Isso dispara uma sequência de eventos dependentes do mecanismo de ativação, [...] por exemplo, usando teclado ou entrada de voz, ou através de cliques do mouse .
Quando o usuário dispara um elemento com um comportamento de ativação definido de uma maneira diferente de clicar nele, a ação padrão do evento de interação deve ser executar as etapas de ativação de clique sintético no elemento.
<select>sendo um Conteúdo Interativo, acreditei ser possível exibir programaticamente seus <option>s. Depois de algumas horas brincando, descobri que usar document.createEvent()e .dispatchEvent()funciona.
Dito isso, é hora da demonstração. Aqui está um Fiddle funcionando.
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);
};
Se alguém encontrar uma maneira de fazer o mesmo, mas não no Chrome, sinta-se à vontade para modificar este violino .
IE10, FF 24. Funciona em: Chrome 30, Safari 6.0.5,Opera 16
A resposta de Xavier Ho cobre como resolver o problema na maioria dos navegadores que existem atualmente. Mas, é uma boa prática 'não despachar / modificar' mais eventos por JavaScript . (Como, mousedownneste caso)
A partir da versão 53+, o Google Chrome não executará a ação padrão para eventos não confiáveis . Como eventos criados ou modificados por script ou despachados por meio de dispatchEventmétodo. Essa mudança é para alinhar com Firefox e IE que eu acho que já não estão realizando a ação.
Para fins de teste, Fiddle forneceu a resposta de Xavier que não funcionará no Chrome 53+. (Eu não testo FF e IE).
Links para referência:
https://www.chromestatus.com/features/5718803933560832 https://www.chromestatus.com/features/6461137440735232
E initMouseEvent também está obsoleto
Este é o mais próximo que consegui obter, alterar o tamanho do elemento no mouseover e restaurar o tamanho no mouseout:
<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>
Eu tenho esse mesmo problema e a maneira mais fácil que encontrei de resolver isso foi com html e 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>empurre o botão e selecione um div como este @DavidPortabella
Acho que isso não é mais possível no Chrome.
Parece que a versão 53 do Chrome desativa essa funcionalidade, conforme afirmado por Asim K T.
De acordo com a especificação http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events
Os eventos confiáveis não devem disparar a ação padrão (exceto o evento de clique).
No entanto, eles habilitaram no webview, mas eu não testei isso.
Descobrimos que alguns webviews estão usando fastclick dentro deles e, devido ao risco de quebra, permitiremos o mouse sobre seleções, mesmo que não sejam confiáveis.
E nesta discussão, a ideia de permitir que os desenvolvedores abram um menu suspenso programaticamente foi abandonada.
Se alguém ainda estiver procurando por isso:
<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; });
});
Atualizar:
Um até que não haja uma solução perfeita para esse problema, mas você pode tentar evitar esse cenário. Por que você quer fazer isso. Eu estava pensando em uma solução alguns meses atrás para fazer um plugin selecionado para dispositivos móveis
https://github.com/HemantNegi/jquery.sumoselect
Finalmente acabamos mascarando o div customizado (ou qualquer outro elemento) com um elemento select transparente, para que ele possa interagir diretamente com o usuário.
iniMouseEventparece funcionar, mas por $(select).trigger('mousedown')que não funciona?
Aqui está a melhor maneira que encontrei. NOTA Ele só funciona com o IE no Windows e sua web provavelmente precisaria estar em uma zona segura - porque acessamos o shell. O truque é que ALT-Seta para baixo é uma tecla de atalho para abrir uma lista suspensa de seleção.
<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>
Pare de pensar que uma coisa é impossível, nada é impossível de fazer, quando você quer fazer.
Use esta função expandir JS criada por um cara.
http://code.google.com/p/expandselect/
Inclua este JS e apenas chame-o, passando o parâmetro como seu id de seleção, assim:
ExpandSelect(MySelect)
<SELECT>caia. Como afirma explicitamente "Os navegadores não permitem a expansão de <select> em javascript puro, esse controle pode ser expandido apenas clicando nele diretamente com o mouse". Portanto, é "impossível"! Em vez disso, o JS afirma "Nós imitamos o controle <select> expandido criando outro select com várias opções exibidas ao mesmo tempo ..." O que é bem diferente e pode ou não ser aceitável para o seu caso de uso ...
Abrir uma "seleção de HTML" é possível por meio de algumas soluções alternativas mencionadas nesta pergunta e outras semelhantes. No entanto, uma maneira mais limpa de fazer isso é adicionar uma biblioteca de seleção ao seu projeto, como "select2" ou "escolhido". Por exemplo, abrir um select2 programaticamente seria tão fácil quanto:
$('#target-select').select2('open');
Não é exatamente o que você pediu, mas gosto desta solução pela sua simplicidade. Na maioria dos casos em que desejo iniciar um menu suspenso, é porque estou validando que o usuário realmente fez uma seleção. Eu mudo o tamanho da lista suspensa e focalizo, o que destaca bem o que eles pularam:
$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();
<select>, já que as pessoas esperam que ele se comporte de uma certa maneira e você estará impedindo que pessoas em outras plataformas (como celular) usem seu site.