¿Cómo fuerzo programáticamente un evento onchange en una entrada?

123

¿Cómo fuerzo programáticamente un evento onchange en una entrada?

He intentado algo como esto:

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

Pero mi objetivo final es activar cualquier función de escucha, y eso no parece funcionar. Tampoco lo hace simplemente actualizar el atributo 'valor'.

Soldarnal
fuente

Respuestas:

142

Crea un Eventobjeto y pásalo al dispatchEventmétodo del elemento:

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

Esto activará detectores de eventos independientemente de si se registraron llamando al addEventListenermétodo o estableciendo la onchangepropiedad del elemento.


Si desea que el evento burbujee, debe pasar un segundo argumento al Eventconstructor:

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

Información sobre la compatibilidad del navegador:

Sinvergüenza
fuente
2
Sí, la creación y activación de eventos de MDN es un buen recurso.
Jakub Holý
1
Así es como se hace correctamente, de forma nativa. Compatible con todos los navegadores ahora: caniuse.com/#feat=dispatchevent
Willem Mulder
1
Esta es una verdadera respuesta para esta pregunta. Debemos lograr esto de una manera moderna.
Константин Ван
1
Estoy tratando de hacer el equivalente en IE11 pero no funciona cuando intento cambiar un campo de entrada reactjs. var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); elem.dispatchEvent(evt);
Bodosko
3
¿Por qué todo el mundo dice que esta es la mejor respuesta? Según el documento de Event vinculado, incluso la versión actual de IE todavía no es compatible con esto.
jeff-h
96

En jQuery utilizo principalmente:

$("#element").trigger("change");
Danita
fuente
2
¡tihs me ayudó! Estaba configurando el valor de una casilla de verificación (marcada o no) usando código y el evento no se activaba en IE sin importar lo que hice. Intenté desenfocar () enfocar () y algunas otras cosas. después de establecer el valor, llamé disparador y agregué un evento de clic para llamar al disparador también. Provoca múltiples incendios, pero no me importa. En IE, agrego casillas de verificación a través del código y debe hacer clic en ellas dos veces antes de que se active el evento de cambio. Gracias por este consejo.
Dustin Davis
6
Como actualización, $ ("# elemento"). Change (); hace lo mismo desde jquery 1.0.
CookieOfFortune
3
Tenga en cuenta que esto NO desencadena un cambio nativo. ¡Solo disparará a todos los oyentes onchange que estaban vinculados a través de jQuery!
Willem Mulder
¿Alguna ayuda aquí por favor? Ninguna de estas soluciones parece funcionar para mí .. stackoverflow.com/questions/51216332/…
Gabe
61

uf, no uses eval para nada . Bueno, hay ciertas cosas, pero son extremadamente raras. Más bien, harías esto:

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

Busque aquí más opciones: http://jehiah.cz/archive/firing-javascript-events-properly

Kolten
fuente
3
eval para objetivar JSON;)
Aaron Powell
3
json2.js para objetivar JSON! JSON.parse ya está disponible en los navegadores modernos
jinglesthula
12
Esta técnica solo funciona si el controlador de cambios se adjuntó configurando "onchange". No genera un evento "real" que active los controladores de eventos w3c o microsoft. Vea el vínculo para mas detalles.
Stephen Nelson
6
Creo que esta respuesta está desactualizada ahora, parece que la respuesta de Miscreant se usa new Event(...)y dispatchEventes la solución correcta hoy en día.
Jakub Holý
4
Esta respuesta está obsoleta ; el código anterior no funcionará si solía Element.addEventListenermanejar eventos. Para lograrlo de una manera moderna, consulte la respuesta de @ Miscreant.
Константин Ван
23

Por alguna razón, ele.onchange () está lanzando una excepción de "método no encontrado" en IE en mi página, así que terminé usando esta función desde el enlace que Kolten proporcionó y llamando a fireEvent (ele, 'change'), que funcionó :

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

Sin embargo, creé una página de prueba que confirmó que la llamada debería funcionar con onchange ():

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

Editar: La razón por la que ele.onchange () no funcionó fue porque en realidad no había declarado nada para el evento onchange. Pero el fireEvent todavía funciona.

Soldarnal
fuente
2
Me gusta este método de detección del navegador (por detección de objetos) más que el ejemplo que proporcioné.
Chris MacDonald
Esto ya no funciona para Firefox 23: "element.dispatchEvent no es una función"
Oliver
4
Hola, compañeros de Google. ¡Es 2016! Hoy en día escribimos código como en element.dispatchEvent(new Event('change', true, true))lugar de todo ese arcano y en su mayoría obsoleto createEventy initEventesas cosas.
ericsoco
3

Esta es la respuesta más correcta para IE y Chrome:

javascript=>

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

Tomado de la parte inferior de 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);
    }
}

Por supuesto, puede reemplazar las cosas $ .browser por sus propios métodos de detección de navegador para hacerlo independiente de jQuery.

Para utilizar esta función:

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

Esto básicamente activará el evento DOM real como si algo hubiera cambiado.

Chris MacDonald
fuente
1

Si agrega todos sus eventos con este fragmento de código:

//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){...});

entonces puede usar element.on<EVENTNAME>()dónde <EVENTNAME>está el nombre de su evento, y eso llamará a todos los eventos con<EVENTNAME>

Wntiv Senyh
fuente
-2

Para activar cualquier evento en Javascript.

 document.getElementById("yourid").addEventListener("change", function({
    //your code here
})
Hareesh Seela
fuente
2
esto es escuchar eventos, no desencadenarlos.
usuario no válido
-4

si estás usando jQuery tendrías:

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

o MS AJAX:

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

O en el HTML sin formato del elemento:

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

Después de volver a leer la pregunta, creo que no leí lo que se debía hacer. Nunca encontré una manera de actualizar un elemento DOM de una manera que fuerce un evento de cambio, lo que mejor puede hacer es tener un método de controlador de eventos separado, como este:

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

Como ya está escribiendo un método JavaScript que hará el cambio, solo hay 1 línea adicional para llamar.

O, si está utilizando el marco de Microsoft AJAX, puede acceder a todos los controladores de eventos a través de:

$get('elementId')._events

Le permitiría hacer algunos trabajos de estilo de reflexión para encontrar el controlador de eventos adecuado para disparar.

Aaron Powell
fuente
1
Creo que quiere disparar el evento real, no ejecutar una función cuando se dispara el evento ... creo . lol
Kolten
-5

Usando JQuery puede hacer lo siguiente:

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

// for the element which uses class name
$(".class_name").trigger("change");
ITBOY DE ACERO
fuente
undefined no es una función.
Hristo Venev