web-dev-qa-db-fra.com

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

J'ai attaché un événement à une zone de texte à l'aide de addEventListener. Ça fonctionne bien. Mon problème est apparu lorsque je voulais déclencher l'événement par programmation à partir d'une autre fonction.

Comment puis-je le faire?

486
KoolKabin

Vous pouvez utiliser fireEvent sur IE 8 ou inférieur, ainsi que celui du W3C dispatchEvent sur la plupart des autres navigateurs. Pour créer l'événement que vous voulez déclencher, vous pouvez utiliser createEvent ou createEventObject, selon le navigateur.

Voici un morceau de code explicite (du prototype) qui déclenche un événement dataavailable sur 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);
}
433
Alsciende

Un exemple de travail:

_// 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 MDN docs .

Voir les tableaux de support pour EventTarget.dispatchEvent et CustomEvent .

300
Dorian

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.

Si vous ne voulez pas utiliser jQuery et que la compatibilité avec les versions antérieures ne vous préoccupe pas particulièrement, 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 }));
38
e18r

Si vous prenez en charge IE9 +, vous pouvez utiliser les éléments suivants. Le même concept est incorporé dans vous pourriez ne pas avoir besoin de 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>
24
Mr. Polywhirl

J'ai recherché des clics de tir, des souris et des événements de souris au survol de souris 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 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);
    }
};
13
S.Mishra

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

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

Ensuite, vous pouvez également appeler cette fonction partout où vous avez besoin d'accomplir la même chose que l'événement fait quand il se déclenche.

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

7
Kirby L. Wallace

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

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

Dans ce cas, l'événement est déclenché uniquement si la valeur a été réellement modifiée, comme vous le déclencheriez par la perte du locus de focus normal effectué par l'utilisateur.

5
Aleksander Lech

@ Dorian's modifié réponse pour fonctionner 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

5
Yarin
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");
3
toto

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

var input = document.getElementById("my_input");
var button = document.getElementById("my_button");

input.addEventListener('change', function (e) {
    alert('change event fired');
});
button.addEventListener('click', function (e) {
    input.value = "Bye World";
    input.triggerEvent("change");
});
<input id="my_input" type="input" value="Hellow World">
<button id="my_button">Change Input</button>
1
iProDev

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éclencher 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!

1
Ifeanyi Amadi
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'

0
Dan Alboteanu

Le moyen le plus efficace consiste à appeler la même fonction que celle enregistrée avec addEventListener directement.

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

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

0
Walle Cyril