Come si può dire a livello di programmazione a un HTML SELECT di scorrere verso il basso (ad esempio, a causa del passaggio del mouse)?


106

Come si può dire a livello di codice selecta un HTML di scorrere verso il basso (ad esempio, a causa del passaggio del mouse)?


6
Consiglierei di non rovinare il comportamento predefinito <select>, poiché le persone si aspettano che si comporti in un certo modo e impedirai alle persone su altre piattaforme (come i dispositivi mobili) di utilizzare il tuo sito.
Brian Donovan

1
@BrianDonovan Non è che non puoi aggiungere un po 'di gestione per questo.
Morg.

@shasikanth: il tuo violino non funziona nemmeno in Firefox 37 nr in Chrome
rubo77

Ok, penso che il violino abbia funzionato in precedenza. Comunque cancellerei il mio commento qui.
shasi kanth

@BrianDonovan In realtà, il cellulare è un buon caso d'uso di questo ... generare programmaticamente una selezione e quindi visualizzare automaticamente le sue opzioni.
Michael

Risposte:


16

Non puoi farlo con un tag di selezione HTML, ma puoi farlo con JavaScript e HTML. Esistono numerosi controlli esistenti che eseguono questa operazione, ad esempio l'elenco "suggerimenti" allegato alla voce "tag interessante / ignorato" o la ricerca di indirizzi email da parte di Gmail.

Esistono molti controlli JavaScript + HTML che forniscono questa funzionalità: cerca i controlli di completamento automatico per le idee.

Vedere questo collegamento per il controllo del completamento automatico ... http://ajaxcontroltoolkit.codeplex.com/


6
questo è un vero peccato: i browser mobili forniscono un elenco di scorrimento specifico del sistema operativo e ho bisogno che venga visualizzato automaticamente.
Michael

120

Questo era effettivamente possibile con HTML + Javascript, nonostante ovunque la gente dica che non lo è, ma è stato deprecato in seguito e ora non funziona.

Tuttavia, questo ha funzionato solo in Chrome. Leggi di più se sei interessato.


Secondo W3C Working Draft for HTML5, Sezione 3.2.5.1.7. Contenuto interattivo :

Alcuni elementi in HTML hanno un comportamento di attivazione, il che significa che l'utente può attivarli. Ciò innesca una sequenza di eventi dipendenti dal meccanismo di attivazione, [...] ad esempio utilizzando la tastiera o l'input vocale o tramite clic del mouse .

Quando l'utente attiva un elemento con un comportamento di attivazione definito in un modo diverso dal clic, l'azione predefinita dell'evento di interazione deve essere l'esecuzione di passaggi di attivazione del clic sintetico sull'elemento.

<select>essendo un contenuto interattivo, ho creduto che fosse possibile visualizzare programmaticamente i suoi <option>. Dopo alcune ore di gioco, ho scoperto che l'uso document.createEvent()e .dispatchEvent()funziona.

Detto questo, tempo demo. Ecco un violino funzionante.


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 qualcuno trova un modo per fare lo stesso ma non in Chrome, sentiti libero di modificare questo violino .


2
Grazie per questo! Avevo bisogno di emulare il comportamento ALT + FRECCIA GIÙ di IE proprio in Chrome.
J Bryan Price

3
Vorrei poter aggiungere alla tua taglia per questo. Grazie mille.
Adam Tuttle

7
Non funziona su: IE10, FF 24. Funziona su: Chrome 30, Safari 6.0.5,Opera 16
hitautodestruct

2
@AdamTuttle Non funziona neanche su Android 4.4.2
Mirko

42
Ora è deprecato su Chrome 53+
Washington Guedes

47

La risposta di Xavier Ho riguarda come risolvere il problema nella maggior parte dei browser attualmente in circolazione. Tuttavia, è buona norma "non inviare / modificare" eventi tramite JavaScript . (Come, mousedownin questo caso)

Dalla versione 53+, Google Chrome non eseguirà l'azione predefinita per eventi non attendibili . Come eventi creati o modificati da script o inviati tramite dispatchEventmetodo. Questa modifica è per l'allineamento con Firefox e IE che penso non stiano già eseguendo l'azione.

A scopo di test, Fiddle ha fornito che la risposta di Xavier non funzionerà in Chrome 53+. (Non lo provo FF e IE).

Link di riferimento:

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

E anche initMouseEvent è deprecato



Non credo proprio. hai provato qualcosa?
Asim KT

28

Questo è il più vicino possibile, cambia la dimensione dell'elemento sumouseover e ripristina la dimensione sumouseout:

       <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
o <SELECT onMouseOut = "this.size = 1;" onMouseOver = "this.size = this.length;"> ... </SELECT>
RealHowTo

1
Inoltre è necessario aggiungere onchange = "this.size = 1" in modo che il menu si chiuda non appena viene effettuata la selezione. Anche le regole CSS dell'elemento devono essere configurate.
gm2008

Sembra funzionare. La larghezza di selezione si riduce e quindi questo causa un evento di mouse out che reimposta la selezione alla larghezza originale. Ciò provoca un effetto convulsivo. L'impostazione di una larghezza fissa sembra risolverlo. Con più di pochi elementi l'elenco si espande oltre la visualizzazione.
1,21 gigawatt

16

Ho lo stesso problema e il modo più semplice che ho trovato per risolverlo è stato con 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>


2
È passato molto tempo da quando ho visto questo approccio, ed è il riferimento che speravo di trovare. Meglio con CSS extra per abbinare la dimensione della selezione nascosta al trigger (pulsante, img, div, ecc.) ... 1) Assicura che la regione selezionabile riempia il trigger 2) Il menu si apre direttamente sotto il trigger. Nota: potrebbe anche essere necessario aggiungere uno z-index per garantire che la regione selezionabile sia l'elemento più in alto in alcuni layout.
Mavelo,

tuttavia, se l'utente scorre la pagina verso il basso, il pulsante si sposta di conseguenza ma la selezione rimane nella stessa posizione; non proprio come previsto. qualche soluzione per questo?
David Portabella

Soluzione perfetta. Ma meglio forse avvolgere il pulsante e selezionare un div come questo <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

Penso che questo non sia più possibile in Chrome.

Sembra che la versione 53 di Chrome disabiliti questa funzionalità come affermato da Asim K T.

Secondo le specifiche http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events

Gli eventi attendibili non dovrebbero attivare l'azione predefinita (eccetto l'evento clic).

Tuttavia l'hanno abilitato in webview, ma non l'ho testato.

Abbiamo scoperto che alcune visualizzazioni web utilizzano il fastclick al loro interno e, a causa del rischio di rottura, consentiremo il mousedown sulle selezioni anche se non sono attendibili.

E in questa discussione l'idea di consentire agli sviluppatori di aprire un menu a discesa in modo programmatico viene abbandonata.


7

Se qualcuno sta ancora cercando questo:

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

Aggiornare:

Uno finché non c'è una soluzione perfetta a questo problema, ma puoi provare a evitare questo scenario. Perchè vuoi fare questo. Qualche mese fa mi chiedevo una soluzione per creare un plug-in selezionato per dispositivi mobili

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

Alla fine si è finito con il mascherare il div personalizzato (o qualsiasi altro elemento) con un elemento di selezione trasparente, in modo che possa interagire direttamente con l'utente.


1
Plugin come github.com/HemantNegi/jquery.sumoselect sono l'unica soluzione cross-browser che in realtà ha un aspetto migliore del controllo predefinito.
Justin

iniMouseEventsembra funzionare, ma perché $(select).trigger('mousedown')non funziona?
coding_idiot

3

Ecco il modo migliore che ho trovato. NOTA Funziona solo con IE su Windows e probabilmente il tuo web dovrebbe trovarsi in una zona sicura, perché accediamo alla shell. Il trucco è che ALT-Freccia giù è un tasto di scelta rapida per aprire un menu a discesa di selezione.

<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
Non funzionerà a meno che non si fa questo .
Knu

1
@Knu Internet Explorer aggiunge automaticamente gli ID degli elementi come riferimenti all'elemento nell'ambito globale.
user2428118

@KlasMellbourn probabilmente. Stanno cercando di rendere i loro browser più conformi ora. Usa la soluzione "taglia" menzionata.
sproketboy

2

Smettila di pensare che una cosa è impossibile, niente è impossibile da fare, quando vuoi farlo.

Usa questa funzione di espansione JS creata da un ragazzo.

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

Includere questo JS e chiamarlo semplicemente passando il parametro come ID di selezione, in questo modo:

ExpandSelect(MySelect)

2
Per essere chiari, che JS non causa la <SELECT>caduta di a. Come afferma esplicitamente "I browser non consentono l'espansione di <select> in puro javascript, quel controllo può essere espanso solo facendo clic direttamente su di esso utilizzando il mouse". Quindi è "impossibile"! Invece il JS afferma "Imitiamo il controllo <select> espanso creando un'altra selezione con più opzioni visualizzate contemporaneamente ..." Il che è abbastanza diverso e può o non può essere accettabile per il tuo caso di utilizzo ....
JonBrave

1

Potrei sbagliarmi, ma non credo che sia possibile con la casella di selezione predefinita. Potresti fare qualcosa con JS e CSS che raggiunge il risultato desiderato, ma non (per quanto ne so) il vanilla SELECT.


0

L'apertura di una "selezione HTML" è possibile attraverso alcune soluzioni alternative menzionate in questa domanda e altre simili. Tuttavia, un modo più pulito per farlo è aggiungere una libreria di selezione al tuo progetto come "select2" o "selected". Ad esempio, aprire un select2 a livello di codice sarebbe facile come:

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

-2

Non è esattamente quello che chiedevi, ma mi piace questa soluzione per la sua semplicità. Nella maggior parte dei casi in cui desidero avviare un menu a discesa, è perché sto convalidando che l'utente ha effettivamente effettuato una selezione. Cambio la dimensione del menu a discesa e lo metto a fuoco, il che evidenzia bene ciò che hanno saltato:

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

Non sono sicuro del motivo per cui sei stato screditato perché non è il modo "peggiore" per farlo. Lo eviterei semplicemente perché sposta la disposizione degli elementi circostanti. Anche se penso che la soluzione di @CMS sia più facilmente comprensibile con gli eventi di messa a fuoco / sfocatura sul controllo.
Mavelo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.