Wie kann ein Ereignis in JavaScript ausgelöst werden?

523

Ich habe ein Ereignis mit an ein Textfeld angehängt addEventListener. Es funktioniert gut. Mein Problem trat auf, als ich das Ereignis programmgesteuert von einer anderen Funktion aus auslösen wollte.

Wie kann ich es tun?

KoolKabin
quelle
11
Mozilla hat einen sehr schönen Artikel, der das Erstellen und Auslösen von Ereignissen in Javascript erklärt . Ich hoffe es hilft!
Ricky Stam
1
Bitte ändern Sie die akzeptierte Antwort darauf , sie ist aktueller.
Michał Perłakowski
1
@ RickyStam Es sieht so aus, als wäre dieser MDN-Artikel hierher gezogen
styfle

Antworten:

454

Sie können fireEvent in IE 8 oder niedriger und dispatchEvent von W3C in den meisten anderen Browsern verwenden. Um das Ereignis zu erstellen, das Sie auslösen möchten, können Sie entweder createEventoder createEventObjectje nach Browser verwenden.

Hier ist ein selbsterklärender Code (vom Prototyp), der ein Ereignis dataavailableauf Folgendes auslöst 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
quelle
6
Vergessen Sie nicht, dass nur die IE-Version das "Ein" vorne hat (das habe ich zuerst verpasst)
hugomg
45
Was enthält die Variable eventNamehier?
NeDark
1
Ja, die verfügbaren Daten sollten sich in eventName befinden und das Memo sollte ebenfalls definiert sein (definieren auf {} ist in Ordnung).
Charles
4
Internet Explorer 9+ verarbeitet createEvent und dispatchEvent, sodass diese if-Anweisungen nicht erforderlich sind.
Blake
5
Dieses Beispiel funktioniert nicht einmal, siehe meine Antwort: stackoverflow.com/a/20548330/407213
Dorian
334

Ein Arbeitsbeispiel:

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

Informationen zu Polyfill für ältere Browser und komplexere Beispiele finden Sie in den MDN-Dokumenten .

Siehe Supporttabellen für EventTarget.dispatchEventund CustomEvent.

Dorian
quelle
11
Diese Antwort ist jetzt aktueller. Eine Sache, die hinzugefügt werden muss: Sollte es ein wissensartiges Ereignis geben (wie TransitionEvent , ClipboardEvent usw.), könnte der entsprechende Konstruktor aufgerufen werden.
Kiril
6
@ AngelPolitis: Weil es geschrieben wurde, nachdem das vorherige bereits akzeptiert wurde und die Person, die die Frage geschrieben hat (@KoolKabin), die Antworten wahrscheinlich nicht erneut gelesen hat
Dorian
4
Und weil es im Jahr 2010 gefragt wurde
DarkNeuron
Funktioniert mit keiner IE-Version ( caniuse.com/#feat=customevent ). Siehe meine Antwort für eine Lösung.
Yarin
Hinweis für zukünftige Leser, detailist eine Eigenschaft derEvent , weisen Sie also alle Daten, auf die Sie am anderen Ende zugreifen möchten, zu und greifen Sie über zu event.detail. +1
Daka
71

Wenn Sie jQuery nicht verwenden möchten und sich nicht besonders um die Abwärtskompatibilität kümmern, verwenden Sie einfach:

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

Siehe die Dokumentation hier und hier .

BEARBEITEN: Abhängig von Ihrem Setup möchten Sie möglicherweise Folgendes hinzufügen bubbles: true:

let element = document.getElementById(id);
element.dispatchEvent(new Event('change', { 'bubbles': true }));
e18r
quelle
4
Dies sollte die akzeptierte Antwort sein, da keine veralteten Methoden wie initEvent ()
user2912903
2
Gute Lösung, aber beachten Sie, dass dies unter IE11 nicht funktioniert. Sie sollten dann CustomEventdie entsprechende Polyfüllung verwenden.
Fabian von Ellerts
2
Besser als die ausgewählte Antwort
WitnessTruth
42

Wenn Sie jQuery verwenden, können Sie dies einfach tun

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

und damit umgehen

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

Dabei bedeutet "[arg0, arg1, ..., argN]", dass diese Argumente optional sind.

Hilder Vitor Lima Pereira
quelle
4
Die korrekte Syntax lautet $ ('# yourElement'). Trigger ('customEventName', [arg0, arg1, ..., argN]); Sie haben das [] beim zweiten Parameter vergessen
Harry
25

Wenn Sie IE9 + unterstützen, können Sie Folgendes verwenden. Das gleiche Konzept ist in You Might Not Need jQuery enthalten .

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


Wenn Sie bereits jQuery verwenden, finden Sie hier die jQuery-Version des obigen Codes.

$(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
quelle
Dies funktioniert nicht für jede Version von IE, da eine window.CustomEventexistiert, kann aber nicht als Konstruktor aufgerufen werden : caniuse.com/#search=CustomEvent ;)
SidOfc
13

Ich habe beim Mouseover mit JavaScript nach Klick-, Maus- und Mausereignissen gesucht. Ich habe eine Antwort von Juan Mendes gefunden . Für die Antwort klicken Sie hier .

Klicken Sie hier ist die Live-Demo und unten ist der 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
quelle
8

Nur um eine Alternative vorzuschlagen, bei der ein Listener-Ereignis nicht manuell aufgerufen werden muss:

Was auch immer Ihr Ereignis-Listener tut, verschieben Sie es in eine Funktion und rufen Sie diese Funktion vom Ereignis-Listener auf.

Dann können Sie diese Funktion auch an einer anderen Stelle aufrufen, an der Sie dasselbe ausführen müssen, was das Ereignis beim Auslösen tut.

Ich finde das weniger "codeintensiv" und leichter zu lesen.

Kirby L. Wallace
quelle
1
Was ist, wenn Sie je nach Kontext mehrere verschiedene Aktionen für dasselbe Ereignis ausführen möchten (oder in Ihrem Fall die Rückruffunktion)? :) Es ist eine gute Alternative, aber dies fühlt sich eher wie ein Kommentar als wie eine Antwort an, da das OP wissen möchte, wie man ein Ereignis programmgesteuert auslöst,
anstatt
Sie haben völlig Recht, dass dies eher ein Kommentar als eine Antwort sein sollte. Warum? Weil, ähm, na ja, ... es beantwortet nicht die Frage, die tatsächlich gestellt wurde. Guter Anruf. Zu Ihrer eigenen Frage würde ich sagen, dass dies eine großartige Gelegenheit für Konstrukteure in JavaScript wäre! ;-) Aber ohne sie würde ich sagen, senden Sie ein Argument mit Ihrem Funktionsaufruf und lassen Sie dies verwenden, um zu bestimmen, was die Funktion tun soll.
Kirby L. Wallace
5

Ich habe gerade Folgendes verwendet (scheint viel einfacher zu sein):

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

In diesem Fall wird das Ereignis nur ausgelöst, wenn der Wert tatsächlich so geändert wurde, wie Sie ihn durch den vom Benutzer durchgeführten normalen Fokusortauslöser auslösen würden.

Aleksander Lech
quelle
1
Dies berücksichtigt nicht, um welche Art von Ereignis es sich handelt. Unschärfe und Fokussierung können das Ereignis auslösen, aber möglicherweise auch nicht. Dies führt zu Fehlern.
Mardok
1
Dies gilt auch für element.click().
AxeEffect
Dies behebt ein seltsames Problem für meine Angular / Cordova-App in Android, bei dem sich der Textbereich weigert, sich selbst zu löschen. So danke.
DarkNeuron
5

Die Antwort von @ Dorian für die Arbeit mit IE wurde geändert :

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/

SIEHE AUCH:
https://caniuse.com/#feat=customevent

Yarin
quelle
4

Die akzeptierte Antwort hat bei mir nicht funktioniert, keine der createEvent-Antworten.

Was am Ende für mich funktioniert hat war:

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

Hier ist ein Ausschnitt:

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>

Aus dem Lesen: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent

Ming
quelle
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
quelle
1
Dies ist veraltet. Nur nützlich für Polyfills. developer.mozilla.org/en-US/docs/Web/API/MouseEvent/…
hipkiss
1

Sie könnten diese Funktion verwenden, die ich zusammen kompiliert habe.

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

Löse ein Ereignis aus:

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

Watch Event:

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

Hoffe das hilft!

Ifeanyi Amadi
quelle
1

Sie können den folgenden Code verwenden, um ein Ereignis mit der Element-Methode auszulösen:

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
quelle
0

Am effizientesten ist es, dieselbe Funktion aufzurufen, bei der registriert wurde addEventListener direkt .

Sie können auch ein gefälschtes Ereignis mit auslösen CustomEvent und co .

Schließlich unterstützen einige Elemente wie <input type="file">eine .click()Methode.

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

Dies löst sofort ein Ereignis 'vor der Installation' aus.

Dan Alboteanu
quelle
-2

Verwenden Sie den Ereignisaufruf jquery. Schreiben Sie die folgende Zeile, in der Sie onChange eines Elements auslösen möchten.

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

element_id ist die ID des Elements, dessen onChange Sie auslösen möchten.

Vermeiden Sie die Verwendung von

 element.fireEvent("onchange");

Weil es sehr wenig Unterstützung hat. Siehe dieses Dokument für seine Unterstützung .

Bhuvan Arora
quelle
-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
quelle
-9

Was Sie wollen, ist ungefähr so:

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

Mit jQuery wäre es ungefähr so:

$(".example").trigger("click");
Osiris RD
quelle
Trigger-Methode ist nicht falsch, aber es ist eine Abfragemethode
Kamuran Sönecek
2
1. document.getElementByClassNameexistiert nicht. 2. document.getElementsByClassNameexistiert, gibt aber eine Liste zurück. 3. Dies funktioniert nur für einige ausgewählte native Ereignisse. 4. Das letzte Beispiel löst ein jQuery-Ereignis aus, bei dem kein zugrunde liegendes natives Ereignis vorhanden ist.
Glenn Jorde