¿Cómo activar un evento en JavaScript?

523

He adjuntado un evento a un cuadro de texto usando addEventListener. Funciona bien. Mi problema surgió cuando quise activar el evento mediante programación desde otra función.

¿Cómo puedo hacerlo?

KoolKabin
fuente
11
Mozilla tiene un artículo muy bueno que explica la creación y activación de eventos en Javascript . ¡Espero eso ayude!
Ricky Stam
1
Cambie la respuesta aceptada a esto , está más actualizada.
Michał Perłakowski
1
@RickyStam Parece que ese artículo de MDN se mudó aquí
styfle

Respuestas:

454

Puede usar fireEvent en IE 8 o inferior, y dispatchEvent de W3C en la mayoría de los otros navegadores. Para crear el evento que desea activar, puede usar cualquiera createEvento createEventObjectdependiendo del navegador.

Aquí hay una pieza de código que se explica por sí mismo (del prototipo) que dispara un evento dataavailableen un element:

var event; // The custom event that will be created
if(document.createEvent){
    event = document.createEvent("HTMLEvents");
    event.initEvent("dataavailable", true, true);
    event.eventName = "dataavailable";
    element.dispatchEvent(event);
} else {
    event = document.createEventObject();
    event.eventName = "dataavailable";
    event.eventType = "dataavailable";
    element.fireEvent("on" + event.eventType, event);
}
Alsciende
fuente
66
'T No se olvide que sólo la versión de IE tiene el 'on' en el frente (me perdí en un primer momento)
hugomg
45
¿Qué contiene la variable eventNameaquí?
NeDark
1
Los datos disponibles deben estar en eventName y la nota también debe estar definida (definir a {} está bien).
Charles
44
Internet Explorer 9+ maneja createEvent y dispatchEvent, por lo que no hay necesidad de esas declaraciones if.
Blake
55
Este ejemplo ni siquiera funciona, mira mi respuesta: stackoverflow.com/a/20548330/407213
Dorian
334

Un ejemplo de trabajo:

// Add an event listener
document.addEventListener("name-of-event", function(e) {
  console.log(e.detail); // Prints "Example of an event"
});

// Create the event
var event = new CustomEvent("name-of-event", { "detail": "Example of an event" });

// Dispatch/Trigger/Fire the event
document.dispatchEvent(event);

Para los polyfill de navegadores más antiguos y ejemplos más complejos, consulte los documentos de MDN .

Ver tablas de soporte para EventTarget.dispatchEventy CustomEvent.

dorio
fuente
11
Esta respuesta es más actual ahora. Una cosa para agregar: si hubiera un evento conocido (como TransitionEvent , ClipboardEvent , etc.) se podría llamar al constructor apropiado.
Kiril
66
@AngelPolitis: Debido a que fue escrito después de que el anterior ya fue aceptado y la persona que escribió la pregunta (@KoolKabin) probablemente no volvió a leer las respuestas
Dorian
44
Y porque fue preguntado en 2010
DarkNeuron
No funcionará con ninguna versión de IE ( caniuse.com/#feat=customevent ). Vea mi respuesta para una solución.
Yarin
Nota para futuros lectores, detailes una propiedad de la Event, así que asigne cualquier información a la que desee acceder en el otro extremo y acceda a ella event.detail. +1
daka
71

Si no desea usar jQuery y no está especialmente preocupado por la compatibilidad con versiones anteriores, simplemente use:

let element = document.getElementById(id);
element.dispatchEvent(new Event("change")); // or whatever the event type might be

Vea la documentación aquí y aquí .

EDITAR: Dependiendo de su configuración, puede agregar bubbles: true:

let element = document.getElementById(id);
element.dispatchEvent(new Event('change', { 'bubbles': true }));
e18r
fuente
44
Esta debería ser la respuesta aceptada, ya que no utiliza métodos obsoletos como initEvent ()
user2912903
2
Buena solución, pero tenga en cuenta que esto no funcionará en IE11. Luego debe usar CustomEventy el polyfill correspondiente.
Fabian von Ellerts
2
Mejor que la respuesta seleccionada
WitnessTruth
42

si usas jQuery, puedes simplemente hacer

$('#yourElement').trigger('customEventName', [arg0, arg1, ..., argN]);

y manejarlo con

$('#yourElement').on('customEventName',
   function (objectEvent, [arg0, arg1, ..., argN]){
       alert ("customEventName");
});

donde "[arg0, arg1, ..., argN]" significa que estos argumentos son opcionales.

Hilder Vitor Lima Pereira
fuente
44
La sintaxis correcta es $ ('# yourElement'). Trigger ('customEventName', [arg0, arg1, ..., argN]); Has olvidado el [] en el segundo parámetro
harry
25

Si es compatible con IE9 +, puede usar lo siguiente. El mismo concepto está incorporado en You Might Not Need jQuery .

function addEventListener(el, eventName, handler) {
  if (el.addEventListener) {
    el.addEventListener(eventName, handler);
  } else {
    el.attachEvent('on' + eventName, function() {
      handler.call(el);
    });
  }
}

function triggerEvent(el, eventName, options) {
  var event;
  if (window.CustomEvent) {
    event = new CustomEvent(eventName, options);
  } else {
    event = document.createEvent('CustomEvent');
    event.initCustomEvent(eventName, true, true, options);
  }
  el.dispatchEvent(event);
}

// Add an event listener.
addEventListener(document, 'customChangeEvent', function(e) {
  document.body.innerHTML = e.detail;
});

// Trigger the event.
triggerEvent(document, 'customChangeEvent', {
  detail: 'Display on trigger...'
});


Si ya está utilizando jQuery, aquí está la versión jQuery del código anterior.

$(function() {
  // Add an event listener.
  $(document).on('customChangeEvent', function(e, opts) {
    $('body').html(opts.detail);
  });

  // Trigger the event.
  $(document).trigger('customChangeEvent', {
    detail: 'Display on trigger...'
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Mr. Polywhirl
fuente
Esto no funcionará para ninguna versión de IE, ya que window.CustomEventexiste, pero no se puede llamar como constructor: caniuse.com/#search=CustomEvent ;)
SidOfc
13

Busqué eventos de clic de disparo, mousedown y mouseup en mouseover usando JavaScript. Encontré una respuesta proporcionada por Juan Mendes . Para la respuesta haz clic aquí .

Haga clic aquí para ver la demostración en vivo y debajo está el código:

function fireEvent(node, eventName) {
    // Make sure we use the ownerDocument from the provided node to avoid cross-window problems
    var doc;
    if (node.ownerDocument) {
        doc = node.ownerDocument;
    } else if (node.nodeType == 9) {
        // the node may be the document itself, nodeType 9 = DOCUMENT_NODE
        doc = node;
    } else {
        throw new Error("Invalid node passed to fireEvent: " + node.id);
    }

    if (node.dispatchEvent) {
        // Gecko-style approach (now the standard) takes more work
        var eventClass = "";

        // Different events have different event classes.
        // If this switch statement can't map an eventName to an eventClass,
        // the event firing is going to fail.
        switch (eventName) {
        case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.
        case "mousedown":
        case "mouseup":
            eventClass = "MouseEvents";
            break;

        case "focus":
        case "change":
        case "blur":
        case "select":
            eventClass = "HTMLEvents";
            break;

        default:
            throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
            break;
        }
        var event = doc.createEvent(eventClass);

        var bubbles = eventName == "change" ? false : true;
        event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable.

        event.synthetic = true; // allow detection of synthetic events
        // The second parameter says go ahead with the default action
        node.dispatchEvent(event, true);
    } else if (node.fireEvent) {
        // IE-old school style
        var event = doc.createEventObject();
        event.synthetic = true; // allow detection of synthetic events
        node.fireEvent("on" + eventName, event);
    }
};
S.Mishra
fuente
8

Solo para sugerir una alternativa que no implique la necesidad de invocar manualmente un evento de escucha:

Independientemente de lo que haga su escucha de eventos, muévalo a una función y llame a esa función desde la escucha de eventos.

Luego, también puede llamar a esa función en cualquier otro lugar que necesite para lograr lo mismo que hace el evento cuando se dispara.

Encuentro esto menos "intensivo en código" y más fácil de leer.

Kirby L. Wallace
fuente
1
¿Qué sucede si desea hacer varias cosas diferentes para el mismo evento (o bueno, la función de devolución de llamada en su caso) dependiendo del contexto? :) Es una buena alternativa, pero parece más un comentario que una respuesta, ya que el OP quiere saber cómo activar un evento mediante programación en lugar de usar una devolución de llamada :)
SidOfc
Tienes toda la razón en que esto debería haber sido un comentario en lugar de una respuesta. ¿Por qué? Porque, uhm, bueno ... no responde la pregunta que realmente se hizo. Buena llamada. En cuanto a su propia pregunta, ¡diría que esta sería una gran oportunidad para los constructores en JavaScript! ;-) Pero sin ellos, diría, envíe un argumento con su llamada a la función y deje que se use para determinar qué debe hacer la función.
Kirby L. Wallace
5

Acabo de usar lo siguiente (parece ser mucho más simple):

element.blur();
element.focus();

En este caso, el evento se desencadena solo si el valor realmente cambió, tal como lo desencadenaría la pérdida de foco normal realizada por el usuario.

Aleksander Lech
fuente
1
Esto no tiene en cuenta qué tipo de evento es. El desenfoque y el enfoque pueden desencadenar el evento, pero puede que no sea tan bueno. Esto está invitando a los errores.
Mardok el
1
Esto también se aplica a element.click().
AxeEffect
Esto solucionó un problema extraño para mi aplicación Angular / Cordova, en Android, donde el área de texto se negaría a borrarse. Así que gracias.
DarkNeuron
5

La respuesta de @ Dorian modificada para trabajar con IE:

document.addEventListener("my_event", function(e) {
  console.log(e.detail);
});

var detail = 'Event fired';

try {

    // For modern browsers except IE:
    var event = new CustomEvent('my_event', {detail:detail});

} catch(err) {

  // If IE 11 (or 10 or 9...?) do it this way:

    // Create the event.
    var event = document.createEvent('Event');
    // Define that the event name is 'build'.
    event.initEvent('my_event', true, true);
    event.detail = detail;

}

// Dispatch/Trigger/Fire the event
document.dispatchEvent(event);

FIDDLE: https://jsfiddle.net/z6zom9d0/1/

VEA TAMBIÉN:
https://caniuse.com/#feat=customevent

Yarin
fuente
4

La respuesta aceptada no funcionó para mí, ninguno de los createEvent sí.

Lo que funcionó para mí al final fue:

targetElement.dispatchEvent(
    new MouseEvent('click', {
        bubbles: true,
        cancelable: true,
        view: window,
}));

Aquí hay un fragmento:

const clickBtn = document.querySelector('.clickme');
const viaBtn = document.querySelector('.viame');

viaBtn.addEventListener('click', function(event) {
    clickBtn.dispatchEvent(
        new MouseEvent('click', {
            bubbles: true,
            cancelable: true,
            view: window,
    }));
});

clickBtn.addEventListener('click', function(event) {
    console.warn(`I was accessed via the other button! A ${event.type} occurred!`);
});
<button class="clickme">Click me</button>

<button class="viame">Via me</button>

De la lectura: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent

Ming
fuente
3
function fireMouseEvent(obj, evtName) {
    if (obj.dispatchEvent) {
        //var event = new Event(evtName);
        var event = document.createEvent("MouseEvents");
        event.initMouseEvent(evtName, true, true, window,
                0, 0, 0, 0, 0, false, false, false, false, 0, null);
        obj.dispatchEvent(event);
    } else if (obj.fireEvent) {
        event = document.createEventObject();
        event.button = 1;
        obj.fireEvent("on" + evtName, event);
        obj.fireEvent(evtName);
    } else {
        obj[evtName]();
    }
}

var obj = document.getElementById("......");
fireMouseEvent(obj, "click");
toto
fuente
1
Esto está en desuso. Solo útil para polyfills. developer.mozilla.org/en-US/docs/Web/API/MouseEvent/…
hipkiss
1

Podrías usar esta función que compilé juntos.

if (!Element.prototype.trigger)
  {
    Element.prototype.trigger = function(event)
    {
        var ev;

        try
        {
            if (this.dispatchEvent && CustomEvent)
            {
                ev = new CustomEvent(event, {detail : event + ' fired!'});
                this.dispatchEvent(ev);
            }
            else
            {
                throw "CustomEvent Not supported";
            }
        }
        catch(e)
        {
            if (document.createEvent)
            {
                ev = document.createEvent('HTMLEvents');
                ev.initEvent(event, true, true);

                this.dispatchEvent(event);
            }
            else
            {
                ev = document.createEventObject();
                ev.eventType = event;
                this.fireEvent('on'+event.eventType, event);
            }
        }
    }
  }

Activa un evento a continuación:

var dest = document.querySelector('#mapbox-directions-destination-input');
dest.trigger('focus');

Ver evento:

dest.addEventListener('focus', function(e){
   console.log(e);
});

¡Espero que esto ayude!

Ifeanyi Amadi
fuente
1

Puede usar el siguiente código para disparar eventos usando el método Element:

if (!Element.prototype.triggerEvent) {
    Element.prototype.triggerEvent = function (eventName) {
        var event;

        if (document.createEvent) {
            event = document.createEvent("HTMLEvents");
            event.initEvent(eventName, true, true);
        } else {
            event = document.createEventObject();
            event.eventType = eventName;
        }

        event.eventName = eventName;

        if (document.createEvent) {
            this.dispatchEvent(event);
        } else {
            this.fireEvent("on" + event.eventType, event);
        }
    };
}

iProDev
fuente
0

La forma más eficiente es llamar a la misma función que se ha registrado con addEventListener directamente.

También puede desencadenar un evento falso con CustomEvent y co.

Finalmente, algunos elementos como el <input type="file">soporte de un .click()método.

Walle Cyril
fuente
0
var btn = document.getElementById('btn-test');
var event = new Event(null);

event.initEvent('beforeinstallprompt', true, true);
btn.addEventListener('beforeinstallprompt', null, false);
btn.dispatchEvent(event);

esto desencadenará de inmediato un evento 'beforeinstallprompt'

Dan Alboteanu
fuente
-2

Use jquery event call. Escriba la línea a continuación donde desea activar onChange de cualquier elemento.

$("#element_id").change();

element_id es el ID del elemento cuyo onChange desea activar.

Evitar el uso de

 element.fireEvent("onchange");

Porque tiene muy menos apoyo. Consulte este documento para su apoyo .

Bhuvan Arora
fuente
-2

HTML

<a href="demoLink" id="myLink"> myLink </a>
<button onclick="fireLink(event)"> Call My Link </button>

JS

// click event listener of the link element --------------  
document.getElementById('myLink').addEventListener("click", callLink);
function callLink(e) {
    // code to fire
}

// function invoked by the button element ----------------
function fireLink(event) {                   
    document.getElementById('myLink').click();      // script calls the "click" event of the link element 
}
Pall Arpad
fuente
-9

Lo que quieres es algo como esto:

document.getElementByClassName("example").click();

Usando jQuery, sería algo como esto:

$(".example").trigger("click");
Osiris RD
fuente
el método de activación no está mal, pero es un método jquery
Kamuran Sönecek
2
1. document.getElementByClassNameno existe 2. document.getElementsByClassNameexiste pero devuelve una lista. 3. esto solo funciona para unos pocos eventos nativos seleccionados. 4. El último ejemplo desencadena un evento jQuery donde no existe ningún evento nativo subyacente.
Glenn Jorde