Come si forza a livello di codice un evento onchange su un input?


123

Come si forza a livello di codice un evento onchange su un input?

Ho provato qualcosa di simile:

var code = ele.getAttribute('onchange');
eval(code);

Ma il mio obiettivo finale è attivare qualsiasi funzione di ascolto e questo non sembra funzionare. Né si limita ad aggiornare l'attributo "valore".

Risposte:


142

Crea un Eventoggetto e passalo al dispatchEventmetodo dell'elemento:

var element = document.getElementById('just_an_example');
var event = new Event('change');
element.dispatchEvent(event);

Ciò attiverà i listener di eventi indipendentemente dal fatto che siano stati registrati chiamando il addEventListenermetodo o impostando la onchangeproprietà dell'elemento.


Se vuoi che l'evento diventi bolla, devi passare un secondo argomento al Eventcostruttore:

var event = new Event('change', { bubbles: true });

Informazioni sulla compatibilità del browser:


2
Sì, la creazione e l'attivazione di eventi MDN è una buona risorsa!
Jakub Holý

1
Ecco come farlo correttamente, in modo nativo. Supportato in tutti i browser ora: caniuse.com/#feat=dispatchevent
Willem Mulder

1
Questa è una vera risposta a questa domanda. Dobbiamo raggiungere questo obiettivo in modo moderno.
Константин Ван

1
Sto provando a fare l'equivalente su IE11 ma non funziona quando provo a cambiare un campo di input di reactjs. var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); elem.dispatchEvent(evt);
Bodosko

3
Perché tutti dicono che questa è la risposta migliore? Secondo il documento Event collegato, anche la versione corrente di IE non lo supporta ancora .
jeff-h

96

In jQuery utilizzo principalmente:

$("#element").trigger("change");

2
tihs mi ha aiutato! Stavo impostando il valore di una casella di controllo (selezionata o meno) utilizzando il codice e l'evento non si attivava affatto in IE, indipendentemente da ciò che facevo. Ho provato blur () focus () e poche altre cose. dopo aver impostato il valore ho chiamato trigger e ho aggiunto anche un evento clic per chiamare trigger. Causa più fuochi ma non mi importa. In IE aggiungo le caselle di controllo tramite il codice e devi fare clic su di esse due volte prima che si attivi l'evento di modifica. Grazie per questo suggerimento.
Dustin Davis

6
Come aggiornamento, $ ("# elemento"). Change (); fa la stessa cosa da jquery 1.0.
CookieOfFortune

3
Notare che questo NON attiva una modifica nativa. Si attiverà solo su tutti gli ascoltatori onchange collegati tramite jQuery!
Willem Mulder,

Qualche aiuto qui per favore? Nessuna di queste soluzioni sembra funzionare per me .. stackoverflow.com/questions/51216332/…
Gabe

61

ugh non usare eval per niente . Bene, ci sono alcune cose, ma sono estremamente rare. Piuttosto, faresti questo:

document.getElementById("test").onchange()

Cerca qui altre opzioni: http://jehiah.cz/archive/firing-javascript-events-properly


3
eval per oggettivare JSON;)
Aaron Powell

3
json2.js per oggettivare JSON! JSON.parse è già disponibile sui browser moderni
jinglesthula

12
Questa tecnica funziona solo se il gestore delle modifiche è stato collegato impostando "onchange". Non genera un evento "reale" che attiva i gestori di eventi w3c o microsoft. Vedi il link per maggiori dettagli.
Stephen Nelson

6
Penso che questa risposta sia obsoleta ora, la risposta di Miscreant usando new Event(...)ed dispatchEventè la soluzione giusta al giorno d'oggi, a quanto pare.
Jakub Holý

4
Questa risposta è obsoleta ; il codice sopra non funzionerà se hai usato Element.addEventListenerper gestire gli eventi. Per realizzarlo in modo moderno, vedere la risposta di @ Miscreant.
Константин Ван

23

Per qualche motivo ele.onchange () sta lanciando un'eccezione "metodo non trovato" per me in IE sulla mia pagina, quindi ho finito per usare questa funzione dal collegamento fornito da Kolten e chiamare fireEvent (ele, 'change'), che ha funzionato :

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

Tuttavia, ho creato una pagina di prova che ha confermato che la chiamata dovrebbe funzionare su onchange ():

<input id="test1" name="test1" value="Hello" onchange="alert(this.value);"/>
<input type="button" onclick="document.getElementById('test1').onchange();" value="Say Hello"/>

Modifica: il motivo per cui ele.onchange () non ha funzionato era perché in realtà non avevo dichiarato nulla per l'evento onchange. Ma fireEvent funziona ancora.


2
Mi piace questo metodo di rilevamento del browser (tramite rilevamento di oggetti) meglio dell'esempio che ho fornito.
Chris MacDonald,

Questo non funziona più per Firefox 23: "element.dispatchEvent non è una funzione"
Oliver

4
Ciao amici googler. È il 2016! Al giorno d'oggi scriviamo codice come element.dispatchEvent(new Event('change', true, true))invece di tutto quel arcano e per lo più deprecato createEvente initEventcose del genere.
ericsoco

3

Questa è la risposta più corretta per IE e Chrome:

javascript=>

var element = document.getElementById('xxxx');
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
element.dispatchEvent(evt);

2

Preso dal fondo di QUnit

function triggerEvent( elem, type, event ) {
    if ( $.browser.mozilla || $.browser.opera ) {
        event = document.createEvent("MouseEvents");
        event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
            0, 0, 0, 0, 0, false, false, false, false, 0, null);
        elem.dispatchEvent( event );
    } else if ( $.browser.msie ) {
        elem.fireEvent("on"+type);
    }
}

Ovviamente puoi sostituire $ .browser con i metodi di rilevamento del tuo browser per renderlo indipendente da jQuery.

Per utilizzare questa funzione:

var event;
triggerEvent(ele, "change", event);

Questo fondamentalmente attiverà il vero evento DOM come se qualcosa fosse effettivamente cambiato.


1

Se aggiungi tutti i tuoi eventi con questo snippet di codice:

//put this somewhere in your JavaScript:
HTMLElement.prototype.addEvent = function(event, callback){
  if(!this.events)this.events = {};
  if(!this.events[event]){
    this.events[event] = [];
    var element = this;
    this['on'+event] = function(e){
      var events = element.events[event];
      for(var i=0;i<events.length;i++){
        events[i](e||event);
      }
    }
  }
  this.events[event].push(callback);
}
//use like this:
element.addEvent('change', function(e){...});

quindi puoi semplicemente usare element.on<EVENTNAME>()dov'è <EVENTNAME>il nome del tuo evento e questo chiamerà tutti gli eventi con<EVENTNAME>


-2

Per attivare qualsiasi evento in Javascript.

 document.getElementById("yourid").addEventListener("change", function({
    //your code here
})

2
questo è ascoltare gli eventi, non innescarli.
invalidusername

-4

se stai usando jQuery avresti:

$('#elementId').change(function() { alert('Do Stuff'); });

o MS AJAX:

$addHandler($get('elementId'), 'change', function(){ alert('Do Stuff'); });

O nell'HTML grezzo dell'elemento:

<input type="text" onchange="alert('Do Stuff');" id="myElement" />

Dopo aver riletto la domanda credo di aver letto male quello che doveva essere fatto. Non ho mai trovato un modo per aggiornare un elemento DOM in un modo che forzerà un evento di modifica, quello che stai facendo meglio è avere un metodo di gestione eventi separato, come questo:

$addHandler($get('elementId'), 'change', elementChanged);
function elementChanged(){
  alert('Do Stuff!');
}
function editElement(){
  var el = $get('elementId');
  el.value = 'something new';
  elementChanged();
}

Poiché stai già scrivendo un metodo JavaScript che effettuerà la modifica, è solo 1 riga aggiuntiva da chiamare.

Oppure, se si sta utilizzando il framework Microsoft AJAX è possibile accedere a tutti i gestori di eventi tramite:

$get('elementId')._events

Ti consentirebbe di eseguire alcune operazioni in stile riflessione per trovare i gestori di eventi giusti da attivare.


1
Credo che voglia attivare l'evento reale, non eseguire una funzione quando l'evento viene attivato ... penso . lol
Kolten

-5

Utilizzando JQuery puoi fare quanto segue:

// for the element which uses ID
$("#id").trigger("change");

// for the element which uses class name
$(".class_name").trigger("change");

undefined non è una funzione.
Hristo Venev
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.