web-dev-qa-db-fra.com

Modifier l'option <select> et déclencher des événements avec JavaScript

Comment puis-je changer l'option d'un HTML <select> Avec JavaScript (sans aucune bibliothèque comme jQuery), tout en déclenchant les mêmes événements que si un utilisateur avait fait le changement?

Par exemple, en utilisant le code suivant, si je modifie l'option avec ma souris, un événement se déclenche (c'est-à-dire que onchange est exécuté). Cependant, lorsque je change l'option en utilisant JavaScript, cela ne déclenche aucun événement. Est-il possible de déclencher des gestionnaires d'événements associés comme onclick, onchange, etc., lorsqu'une option est sélectionnée avec JavaScript?

<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" onclick='document.getElementById("sel").options[1].selected = true;' value="Change option to 2" />

http://jsfiddle.net/xwywvd1a/

29
user1798933

Malheureusement, vous devez déclencher manuellement l'événement change. Et Event Contructor sera la meilleure solution.

var select = document.querySelector('#sel'),
    input = document.querySelector('input[type="button"]');
select.addEventListener('change',function(){
    alert('changed');
});
input.addEventListener('click',function(){
    select.value = 2;
    select.dispatchEvent(new Event('change'));
});
<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3' selected>Three</option>
</select>
<input type="button" value="Change option to 2" />

Et bien sûr, le constructeur d'événements n'est pas pris en charge sur IE. Vous devrez donc peut-être remplir avec ceci:

function Event( event, params ) {
    params = params || { bubbles: false, cancelable: false, detail: undefined };
    var evt = document.createEvent( 'CustomEvent' );
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
    return evt;
}
32
Lewis

Le violon de ma solution est ici . Mais juste au cas où il expirerait, je collerais aussi le code.

HTML:

<select id="sel">
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" id="button" value="Change option to 2" />

JS:

var sel = document.getElementById('sel'),
    button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;

    // firing the event properly according to StackOverflow
    // http://stackoverflow.com/questions/2856513/how-can-i-trigger-an-onchange-event-manually
    if ("createEvent" in document) {
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent("change", false, true);
        sel.dispatchEvent(evt);
    }
    else {
        sel.fireEvent("onchange");
    }
});

sel.addEventListener('change', function (e) {
    alert('changed');
});
11
Karol

C'est aussi simple que cela:

var sel = document.getElementById('sel');
var button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;
    sel.onchange();
});

Mais cette façon a un problème. Vous ne pouvez pas appeler des événements comme vous le feriez avec des fonctions normales, car il peut y avoir plus d'une fonction à l'écoute d'un événement, et elles peuvent être configurées de plusieurs manières différentes.

Malheureusement, la "bonne façon" de déclencher un événement n'est pas si facile car vous devez le faire différemment dans Internet Explorer (en utilisant document.createEventObject) et Firefox (en utilisant document.createEvent ("HTMLEvents"))

var sel = document.getElementById('sel');
var button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;
    fireEvent(sel,'change');

});


function fireEvent(element,event){
    if (document.createEventObject){
    // dispatch for IE
    var evt = document.createEventObject();
    return element.fireEvent('on'+event,evt)
    }
    else{
    // dispatch for firefox + others
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent(event, true, true ); // event type,bubbling,cancelable
    return !element.dispatchEvent(evt);
    }
}
6
galeonweb

L'ensemble de la création et de la répartition des événements fonctionne, mais puisque vous utilisez l'attribut onchange, votre vie peut être un peu plus simple:

http://jsfiddle.net/xwywvd1a/3/

var selEl = document.getElementById("sel");
selEl.options[1].selected = true;
selEl.onchange();

Si vous utilisez l'API d'événements du navigateur (addEventListener, AttachEvent d'IE, etc.), vous devrez créer et distribuer des événements comme d'autres l'ont déjà souligné.

2
Ryan Wheale

Essaye ça:

<select id="sel">
 <option value='1'>One</option>
  <option value='2'>Two</option> 
  <option value='3'>Three</option> 
  </select> 


  <input type="button" value="Change option to 2"  onclick="changeOpt()"/>

  <script>

  function changeOpt(){
  document.getElementById("sel").options[1].selected = true;

alert("changed")
  }

  </script>
1
Vicky Gonsalves

Ces questions peuvent être pertinentes pour ce que vous demandez:

Voici mes réflexions: vous pouvez cumuler plusieurs appels dans votre événement onclick comme ceci:

<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" onclick='document.getElementById("sel").options[1].selected = true; alert("changed");' value="Change option to 2" />

Vous pouvez également appeler une fonction pour ce faire.

Si vous voulez vraiment appeler une fonction et que les deux se comportent de la même manière, je pense que quelque chose comme ça devrait fonctionner. Il ne suit pas vraiment la meilleure pratique de "Les fonctions devraient faire une chose et bien le faire", mais il vous permet d'appeler une fonction pour gérer les deux façons de modifier la liste déroulante. Fondamentalement, je passe (valeur) sur l'événement onchange et (null, index of option) sur l'événement onclick.

Voici le codepen: http://codepen.io/mmaynar1/pen/ZYJaaj

<select id="sel" onchange='doThisOnChange(this.value)'>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
</select>
<input type="button" onclick='doThisOnChange(null,1);' value="Change option to 2"/>

<script>
doThisOnChange = function( value, optionIndex)
{
    if ( optionIndex != null )
    {
       var option = document.getElementById( "sel" ).options[optionIndex];
       option.selected = true;
       value = option.value;
    }
    alert( "Do something with the value: " + value );
}
</script>
1
mmaynar1

Vous pouvez déclencher l'événement manuellement après avoir modifié l'option sélectionnée sur l'événement onclick en faisant: document.getElementById("sel").onchange();

0
eldano

html utilisant Razor:

 @Html.DropDownList("test1", Model.SelectOptionList, new { id = "test1", onchange = "myFunction()" })

Code JS:

function myFunction() {

            var value = document.getElementById('test1').value;

            console.log("it has been changed! to " + value );
        }
0
Primoshenko