Comment pouvez-vous dire par programmation à un SELECT HTML de dérouler (par exemple, en raison d'un survol de la souris)?

106

Comment pouvez-vous dire par programmation à un code HTML selectde se dérouler (par exemple, en raison d'un survol de la souris)?

Corey Trager
la source
6
Je recommanderais de ne pas bousiller le comportement par défaut <select>, car les gens s'attendent à ce qu'il se comporte d'une certaine manière et vous empêcherez les personnes sur d'autres plates-formes (comme les mobiles) d'utiliser votre site.
Brian Donovan
1
@BrianDonovan Ce n'est pas comme si vous ne pouviez pas ajouter de traitement pour cela.
Morg.
@shasikanth: votre violon ne fonctionne pas non plus dans Firefox 37 nr dans Chrome
rubo77
Ok, je pense que le violon a fonctionné auparavant. Quoi qu'il en soit, je supprimerais mon commentaire ici.
shasi kanth
@BrianDonovan En fait, le mobile est un bon cas d'utilisation de cela ... générant par programme une sélection et faisant apparaître automatiquement ses options.
Michael

Réponses:

16

Vous ne pouvez pas faire cela avec une balise de sélection HTML, mais vous pouvez le faire avec JavaScript et HTML. Il existe une variété de contrôles existants qui font cela - par exemple, la liste "suggérer" attachée à l'entrée SO "balise intéressante / ignorée", ou la recherche des adresses e-mail par Gmail.

Il existe de nombreux contrôles JavaScript + HTML qui offrent cette fonctionnalité - recherchez des contrôles de saisie semi-automatique pour des idées.

Voir ce lien pour le contrôle de saisie semi-automatique ... http://ajaxcontroltoolkit.codeplex.com/

rp.
la source
6
c'est une honte - les navigateurs mobiles fournissent une liste déroulante spécifique au système d'exploitation, et j'ai besoin que cela apparaisse automatiquement.
Michael
120

Cela était en fait possible avec HTML + Javascript, bien que partout ailleurs les gens disent que ce n'est pas le cas, mais cela a été obsolète plus tard et ne fonctionne plus maintenant.

Cependant, cela ne fonctionnait que dans Chrome. En savoir plus si vous êtes intéressé.


Selon le projet de travail du W3C pour HTML5, section 3.2.5.1.7. Contenu interactif :

Certains éléments en HTML ont un comportement d'activation, ce qui signifie que l'utilisateur peut les activer. Cela déclenche une séquence d'événements dépendant du mécanisme d'activation [...] par exemple à l'aide du clavier ou de la voix, ou par des clics de souris .

Lorsque l'utilisateur déclenche un élément avec un comportement d'activation défini d'une manière autre que de cliquer dessus, l'action par défaut de l'événement d'interaction doit être d'exécuter des étapes d'activation de clic synthétique sur l'élément.

<select>étant un contenu interactif, je pensais qu'il était possible d'afficher ses <option>s. Après quelques heures à jouer, j'ai découvert que l'utilisation document.createEvent()et le .dispatchEvent()fonctionnement.

Cela dit, l'heure de la démonstration. Voici un violon qui fonctionne.


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

Si quelqu'un trouve un moyen de faire de même mais pas dans Chrome, n'hésitez pas à modifier ce violon .

Xavier Ho
la source
2
Merci pour ça! J'avais besoin d'émuler le comportement ALT + DOWN ARROW d'IE avec précision dans Chrome.
J Bryan Price
3
J'aimerais pouvoir ajouter à votre prime pour cela. Merci beaucoup.
Adam Tuttle
7
Ne fonctionne pas sur: IE10, FF 24. Travaux sur: Chrome 30, Safari 6.0.5,Opera 16
hitautodestruct
2
@AdamTuttle Cela ne fonctionne pas non plus sur Android 4.4.2
Mirko
42
Il est désormais obsolète sur Chrome 53+
Washington Guedes
47

La réponse de Xavier Ho couvre comment résoudre le problème dans la plupart des navigateurs actuellement disponibles. Mais, il est une bonne pratique « de ne pas l' envoi / modifier » par les événements JavaScript plus . (Comme, mousedowndans ce cas)

À partir de la version 53+, Google Chrome n'effectuera pas d'action par défaut pour les événements non fiables . Tels que les événements créés ou modifiés par script, ou distribués via une dispatchEventméthode. Ce changement concerne l'alignement sur Firefox et IE qui, je pense, n'effectuent déjà pas l'action.

À des fins de test, Fiddle fourni que la réponse de Xavier ne fonctionnera pas dans Chrome 53+. (Je ne le teste pas FF et IE).

Liens pour référence:

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

Et initMouseEvent est également obsolète

Asim KT
la source
Cela peut-il être fait avec MouseEvents? developer.mozilla.org/en-US/docs/Web/API/MouseEvent
Shamal Perera
Je ne pense pas. avez-vous essayé quelque chose?
Asim KT
28

C'est le plus proche que je puisse obtenir, changer la taille de l'élément sur la souris et restaurer la taille sur la souris:

       <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>

CMS
la source
13
ou <SELECT onMouseOut = "this.size = 1;" onMouseOver = "this.size = this.length;"> ... </SELECT>
RealHowTo
1
Il faut également ajouter onchange = "this.size = 1" pour que le menu se replie dès que la sélection est effectuée. Les règles CSS de l'élément doivent également être configurées.
gm2008
Cela semble fonctionner. La largeur de la sélection se réduit et cela provoque un événement de sortie de la souris qui réinitialise la sélection à sa largeur d'origine. Cela provoque un effet de crise. Définir une largeur fixe semble le résoudre. Avec plus de quelques éléments, la liste s'étend au-delà de la vue.
1,21 gigawatts le
16

J'ai ce même problème et le moyen le plus simple que j'ai trouvé pour résoudre c'était avec html et css.

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

Rafael Umbelino
la source
2
Cela fait longtemps que je n'ai pas vu cette approche, et c'est la référence que j'espérais trouver. Mieux vaut avec du CSS supplémentaire pour correspondre à la taille de la sélection cachée à déclencher (bouton, img, div, etc.) ... 1) Assure que la région cliquable remplit le déclencheur 2) Le menu s'ouvre directement sous le déclencheur. Remarque: il se peut également que vous deviez ajouter un z-index pour vous assurer que la région cliquable est l'élément le plus haut dans certaines mises en page.
Mavelo le
cependant, si l'utilisateur fait défiler la page vers le bas, le bouton se déplace en conséquence mais la sélection reste à la même position; pas vraiment comme prévu. une solution pour cela?
David Portabella
Solution parfaite. Mais mieux vaut peut-être envelopper le bouton et sélectionner sur div comme ça <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

Je pense que ce n'est plus possible dans Chrome.

Il semble que la version 53 de chrome désactive cette fonctionnalité comme indiqué par Asim K T.

Selon la spécification http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events

Les événements approuvés ne doivent pas déclencher l'action par défaut (sauf l'événement de clic).

Ils l'ont cependant activé dans la vue Web, mais je ne l'ai pas testé.

Nous avons constaté que certaines vues Web utilisent fastclick à l'intérieur et, en raison d'un risque de rupture, nous allons autoriser la désactivation de la souris sur les sélections même si elles ne sont pas fiables.

Et dans cette discussion, l'idée de laisser les développeurs ouvrir une liste déroulante par programme est abandonnée.

Discret
la source
7

Si quelqu'un cherche toujours ceci:

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

Mettre à jour:

Un jusqu'à ce qu'il n'y ait pas de solution parfaite à ce problème, mais vous pouvez essayer d'éviter ce scénario. Pourquoi veux-tu faire cela. Je me demandais une solution il y a quelques mois pour créer un plugin de sélection pour les appareils mobiles

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

Enfin, nous avons masqué le div personnalisé (ou tout autre élément) avec un élément de sélection transparent, afin qu'il puisse interagir directement avec l'utilisateur.

Hemant_Negi
la source
1
Les plugins tels que github.com/HemantNegi/jquery.sumoselect sont la seule solution multi-navigateurs qui est réellement meilleure que le contrôle par défaut.
Justin
iniMouseEventsemble fonctionner, mais pourquoi ne $(select).trigger('mousedown')fonctionne pas?
coding_idiot
3

Voici le meilleur moyen que j'ai trouvé. REMARQUE Cela ne fonctionne qu'avec IE sous Windows et votre site Web devrait probablement se trouver dans une zone sécurisée - car nous accédons au shell. L'astuce est que ALT-Flèche bas est une touche de raccourci pour ouvrir une liste déroulante de sélection.

<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>
sproketboy
la source
3
Il ne fonctionnera pas à moins que vous ne cela .
Knu
1
@Knu Internet Explorer ajoute automatiquement les ID des éléments en tant que références à l'élément à la portée globale.
user2428118
@KlasMellbourn probablement. Ils essaient de rendre leurs navigateurs plus conformes maintenant. Utilisez la solution «taille» mentionnée.
sproketboy
2

Arrêtez de penser qu'une chose est impossible, rien n'est impossible à faire, quand vous le souhaitez.

Utilisez cette fonction d'extension JS créée par un gars.

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

Incluez ce JS et appelez-le simplement en passant le paramètre comme identifiant de sélection, comme ça:

ExpandSelect(MySelect)
Paulo Roberto Rosa
la source
2
Pour être clair, que JS ne pas provoquer une <SELECT>à la chute vers le bas. Comme il déclare explicitement "Les navigateurs ne permettent pas de développer <select> en pur javascript, ce contrôle ne peut être développé qu'en cliquant directement dessus à l'aide de la souris". Ainsi , il est « impossible »! Au lieu de cela, le JS déclare «Nous imitons le contrôle <select> étendu en créant une autre sélection avec plusieurs options affichées à la fois ...» Ce qui est assez différent, et peut ou non être acceptable pour votre cas d'utilisation ....
JonBrave
1

Je me trompe peut-être, mais je ne pense pas que ce soit possible avec la boîte de sélection par défaut. Vous pouvez faire quelque chose avec JS et CSS qui atteint le résultat souhaité, mais pas (à ma connaissance) le SELECT vanilla.

Mandrin
la source
0

L'ouverture d'une "sélection HTML" est possible grâce à certaines solutions de contournement mentionnées dans cette question et d'autres similaires. Cependant, une manière plus propre de faire ceci est d'ajouter une bibliothèque de sélection à votre projet comme "select2" ou "choisi". Par exemple, ouvrir un select2 par programme serait aussi simple que:

$('#target-select').select2('open');
Kasra Ebrahimi
la source
-2

Ce n'est pas exactement ce que vous avez demandé, mais j'aime cette solution pour sa simplicité. Dans la plupart des cas où je souhaite lancer une liste déroulante, c'est parce que je valide que l'utilisateur a effectivement fait une sélection. Je change la taille de la liste déroulante et la concentre, ce qui met bien en évidence ce qu'ils ont sauté:

$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();
Rob3C
la source
Je ne sais pas pourquoi vous avez été critiqué car ce n'est pas la «pire» façon de le faire. J'éviterais cela simplement parce que cela change la disposition des éléments environnants. Bien que je pense que la solution de @CMS est plus facilement comprise avec les événements de mise au point / flou au contrôle.
Mavelo le