Comment déclencher un événement en JavaScript?

523

J'ai joint un événement à une zone de texte à l'aide de addEventListener. Ça fonctionne bien. Mon problème est survenu lorsque j'ai voulu déclencher l'événement par programme à partir d'une autre fonction.

Comment puis-je le faire?

KoolKabin
la source
11
Mozilla a un très bel article expliquant la création et le déclenchement d'événements en Javascript . J'espère que cela aide!
Ricky Stam
1
Veuillez modifier la réponse acceptée à cela , elle est plus à jour.
Michał Perłakowski
1
@RickyStam Il semble que l'article de MDN a déménagé ici
styfle

Réponses:

454

Vous pouvez utiliser fireEvent sur IE 8 ou inférieur, et dispatchEvent du W3C sur la plupart des autres navigateurs. Pour créer l'événement que vous souhaitez déclencher, vous pouvez utiliser soit createEventou createEventObjectselon le navigateur.

Voici un morceau de code explicite (du prototype) qui déclenche un événement dataavailablesur 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
la source
6
N'oubliez pas que seule la version IE a le «on» en face (je l'ai manqué au début)
hugomg
45
Que contient la variable eventNameici?
NeDark
1
Les données disponibles doivent être dans eventName et le mémo doit également être défini (définir sur {} est correct).
Charles
4
Internet Explorer 9+ gère les commandes createEvent et dispatchEvent, il n'y a donc pas besoin de ces instructions if.
Blake
5
Cet exemple ne fonctionne même pas, voir ma réponse: stackoverflow.com/a/20548330/407213
Dorian
334

Un exemple pratique:

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

Pour les anciens navigateurs polyfill et des exemples plus complexes, voir la documentation MDN .

Voir les tableaux de support pour EventTarget.dispatchEventet CustomEvent.

Dorian
la source
11
Cette réponse est plus réelle maintenant. Une chose à ajouter: s'il doit y avoir un événement de type connu (comme TransitionEvent , ClipboardEvent , etc.), le constructeur approprié pourrait être appelé.
Kiril
6
@AngelPolitis: Parce qu'elle a été écrite après que la précédente a déjà été acceptée et que la personne qui a écrit la question (@KoolKabin) n'a probablement pas relu les réponses
Dorian
4
Et parce qu'il a été demandé en 2010
DarkNeuron
Ne fonctionnera avec aucune version d'IE ( caniuse.com/#feat=customevent ). Voir ma réponse pour un correctif.
Yarin
Remarque pour les futurs lecteurs, detailest une propriété de la Event, alors affectez-lui toutes les données auxquelles vous souhaitez accéder à l'autre extrémité et accédez-y event.detail. +1
daka
71

Si vous ne voulez pas utiliser jQuery et n'êtes pas particulièrement préoccupé par la compatibilité descendante, utilisez simplement:

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

Voir la documentation ici et ici .

EDIT: Selon votre configuration, vous voudrez peut-être ajouter bubbles: true:

let element = document.getElementById(id);
element.dispatchEvent(new Event('change', { 'bubbles': true }));
e18r
la source
4
Cela devrait être la réponse acceptée car elle n'utilise pas de méthodes obsolètes comme initEvent ()
user2912903
2
Belle solution, mais sachez que cela ne fonctionnera pas sur IE11. Vous devez ensuite utiliser CustomEventet le polyfill correspondant.
Fabian von Ellerts
2
Mieux que la réponse sélectionnée
WitnessTruth
42

si vous utilisez jQuery, vous pouvez simplement faire

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

et le manipuler avec

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

où "[arg0, arg1, ..., argN]" signifie que ces arguments sont facultatifs.

Hilder Vitor Lima Pereira
la source
4
La syntaxe correcte est $ ('# yourElement'). Trigger ('customEventName', [arg0, arg1, ..., argN]); Vous avez oublié le [] au deuxième paramètre
Harry
25

Si vous prenez en charge IE9 +, vous pouvez utiliser ce qui suit. Le même concept est incorporé dans 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 vous utilisez déjà jQuery, voici la version jQuery du code ci-dessus.

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

M. Polywhirl
la source
Cela ne fonctionnera pour aucune version d'IE, car il window.CustomEventexiste, mais il ne peut pas être appelé en tant que constructeur: caniuse.com/#search=CustomEvent ;)
SidOfc
13

J'ai recherché des clics de tir, des mousedown et des mouseup sur mouseover en utilisant JavaScript. J'ai trouvé une réponse fournie par Juan Mendes . Pour la réponse cliquez ici .

Cliquez ici est la démo en direct et ci-dessous est le code:

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
la source
8

Juste pour suggérer une alternative qui n'implique pas la nécessité d'appeler manuellement un événement d'écoute:

Quoi que fasse votre écouteur d'événements, déplacez-le dans une fonction et appelez cette fonction à partir de l'écouteur d'événements.

Ensuite, vous pouvez également appeler cette fonction n'importe où ailleurs dont vous avez besoin pour accomplir la même chose que l'événement fait lorsqu'il se déclenche.

Je trouve cela moins "intensif en code" et plus facile à lire.

Kirby L. Wallace
la source
1
Et si vous voulez faire plusieurs choses différentes pour le même événement (ou bien, la fonction de rappel dans votre cas) selon le contexte? :) C'est une bonne alternative mais cela ressemble plus à un commentaire qu'à une réponse car l'OP veut savoir comment déclencher un événement par programmation plutôt que d'utiliser un rappel :)
SidOfc
Vous avez tout à fait raison de dire que cela aurait dû être un commentaire plutôt qu'une réponse. Pourquoi? Parce que, euh, eh bien, ... cela ne répond pas à la question qui a été effectivement posée. Bon appel. Quant à votre propre question, je dirais que ce serait une excellente opportunité pour les constructeurs en JavaScript! ;-) Mais sans eux, je dirais, envoyez un argument avec votre appel de fonction et laissez-le être utilisé pour déterminer ce que la fonction devrait faire.
Kirby L. Wallace,
5

Je viens d'utiliser ce qui suit (semble être beaucoup plus simple):

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

Dans ce cas, l'événement n'est déclenché que si la valeur a vraiment été modifiée, tout comme vous le déclencheriez par un locus de mise au point normal perdu effectué par l'utilisateur.

Aleksander Lech
la source
1
Cela ne tient pas compte du type d'événement qu'il s'agit. Le flou et la mise au point peuvent déclencher l'événement, mais pas aussi. C'est invitant des bogues.
Mardok
1
Cela vaut également pour element.click().
AxeEffect
Cela a corrigé un problème étrange pour mon application Angular / Cordova, dans Android, où la zone de texte refusait de s'effacer. Donc merci.
DarkNeuron
5

Modification de la réponse de @ Dorian pour travailler avec 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/

VOIR AUSSI:
https://caniuse.com/#feat=customevent

Yarin
la source
4

La réponse acceptée n'a pas fonctionné pour moi, aucune de celles de createEvent n'a fonctionné.

Ce qui a finalement fonctionné pour moi, c'est:

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

Voici un extrait:

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 lecture: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent

Ming
la source
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
la source
1
C'est obsolète. Utile uniquement pour les polyfills. developer.mozilla.org/en-US/docs/Web/API/MouseEvent/…
hipkiss
1

Vous pouvez utiliser cette fonction que j'ai compilée ensemble.

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

Déclenchez un événement ci-dessous:

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

Regarder l'événement:

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

J'espère que cela t'aides!

Ifeanyi Amadi
la source
1

Vous pouvez utiliser le code ci-dessous pour déclencher un événement à l'aide de la méthode 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
la source
0

Le moyen le plus efficace consiste à appeler addEventListenerdirectement la même fonction qui a été enregistrée .

Vous pouvez également déclencher un faux événement avec CustomEventet co.

Enfin, certains éléments tels que la <input type="file">prise en charge d'une .click()méthode.

Walle Cyril
la source
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);

cela déclenchera immédiatement un événement «beforeinstallprompt»

Dan Alboteanu
la source
-2

Utilisez l'appel d'événement jquery. Écrivez la ligne ci-dessous à l'endroit où vous souhaitez déclencher le changement d'un élément.

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

element_id est l'ID de l'élément dont onChange vous souhaitez déclencher.

Évitez l'utilisation de

 element.fireEvent("onchange");

Parce qu'il a très moins de support. Référez-vous à ce document pour son support .

Bhuvan Arora
la source
-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
la source
-9

Ce que vous voulez, c'est quelque chose comme ceci:

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

En utilisant jQuery, ce serait quelque chose comme ceci:

$(".example").trigger("click");
Osiris RD
la source
la méthode de déclenchement n'est pas fausse, mais c'est une méthode jquery
Kamuran Sönecek
2
1. document.getElementByClassNamen'existe pas. 2. document.getElementsByClassNameexiste mais renvoie une liste. 3. cela ne fonctionne que pour quelques événements natifs sélectionnés. 4. Le dernier exemple déclenche un événement jQuery où aucun événement natif sous-jacent n'existe.
Glenn Jorde