Bagaimana cara memicu event di JavaScript?

523

Saya telah melampirkan acara ke kotak teks menggunakan addEventListener. Ini bekerja dengan baik. Masalah saya muncul ketika saya ingin memicu acara secara terprogram dari fungsi lain.

Bagaimana saya bisa melakukannya?

KoolKin
sumber
11
Mozilla memiliki artikel yang sangat bagus menjelaskan Membuat dan memicu acara di Javascript . Semoga ini bisa membantu!
Ricky Stam
1
Harap ubah jawaban yang diterima untuk ini , ini lebih mutakhir.
Michał Perłakowski
1
@ RickyStam Sepertinya artikel MDN pindah ke sini
styfle

Jawaban:

454

Anda dapat menggunakan fireEvent di IE 8 atau lebih rendah, dan dispatchEvent W3C di sebagian besar browser lain. Untuk membuat acara yang ingin Anda jalankan, Anda dapat menggunakan salah satu createEventatau createEventObjecttergantung pada browser.

Berikut ini adalah sepotong kode yang cukup jelas (dari prototipe) yang menjalankan suatu peristiwa dataavailablepada 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
sumber
6
Jangan lupa bahwa hanya versi IE yang memiliki 'on' di depan (saya melewatkannya pada awalnya)
hugomg
45
Apa isi variabel di eventNamesini?
NeDark
1
Yap data yang tersedia harus dalam eventName dan memo harus didefinisikan juga (define to {} is ok).
Charles
4
Internet Explorer 9+ menangani createEvent dan dispatchEvent, jadi tidak perlu untuk pernyataan if.
Blake
5
Contoh ini bahkan tidak berfungsi, lihat jawaban saya: stackoverflow.com/a/20548330/407213
Dorian
334

Contoh kerja:

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

Untuk browser lama, polyfill dan contoh yang lebih kompleks, lihat dokumen MDN .

Lihat tabel dukungan untuk EventTarget.dispatchEventdan CustomEvent.

Dorian
sumber
11
Jawaban ini lebih aktual sekarang. Satu hal yang perlu ditambahkan: jika harus ada acara yang diketik tahu (seperti TransitionEvent , ClipboardEvent , dll) konstruktor yang sesuai dapat dipanggil.
Kiril
6
@AngelPolitis: Karena itu ditulis setelah yang sebelumnya sudah diterima dan orang yang menulis pertanyaan (@KoolKabin) mungkin tidak membaca kembali jawabannya
Dorian
4
Dan karena diminta pada tahun 2010
DarkNeuron
Tidak akan berfungsi dengan versi IE mana pun ( caniuse.com/#feat=customevent ). Lihat jawaban saya untuk perbaikan.
Yarin
Catatan untuk pembaca yang akan datang, detailadalah properti dari Event, jadi tetapkan setiap data yang ingin Anda akses di ujung yang lain dan akses oleh event.detail. +1
daka
71

Jika Anda tidak ingin menggunakan jQuery dan tidak terlalu khawatir tentang kompatibilitas mundur, gunakan saja:

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

Lihat dokumentasi di sini dan di sini .

EDIT: Tergantung pada pengaturan Anda, Anda mungkin ingin menambahkan bubbles: true:

let element = document.getElementById(id);
element.dispatchEvent(new Event('change', { 'bubbles': true }));
e18r
sumber
4
Ini harus menjadi jawaban yang diterima karena tidak menggunakan metode usang seperti initEvent ()
user2912903
2
Solusi yang bagus, tetapi perlu diingat ini tidak akan bekerja pada IE11. Anda kemudian harus menggunakan CustomEventdan polyfill yang sesuai.
Fabian von Ellerts
2
Lebih baik daripada jawaban yang dipilih
WitnessTruth
42

jika Anda menggunakan jQuery, Anda dapat melakukannya dengan mudah

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

dan menanganinya dengan

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

di mana "[arg0, arg1, ..., argN]" berarti bahwa args ini opsional.

Hilder Vitor Lima Pereira
sumber
4
Sintaks yang benar adalah $ ('# yourElement'). Trigger ('customEventName', [arg0, arg1, ..., argN]); Anda lupa [] pada parameter kedua
harry
25

Jika Anda mendukung IE9 +, Anda dapat menggunakan yang berikut ini. Konsep yang sama tergabung dalam 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...'
});


Jika Anda sudah menggunakan jQuery, ini adalah versi jQuery dari kode di atas.

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

Pak Polywhirl
sumber
Ini tidak akan berfungsi untuk versi IE mana pun, sebagai window.CustomEventada tetapi tidak dapat disebut sebagai konstruktor: caniuse.com/#search=CustomEvent ;)
SidOfc
13

Saya mencari firing click, mousedown dan acara mouseup di mouse menggunakan JavaScript. Saya menemukan jawaban yang diberikan oleh Juan Mendes . Untuk jawabannya klik di sini .

Klik di sini adalah demo langsung dan di bawah ini adalah kode:

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
sumber
8

Hanya untuk menyarankan alternatif yang tidak melibatkan kebutuhan untuk secara manual memohon acara pendengar:

Apa pun yang dilakukan pendengar acara Anda, pindahkan ke fungsi dan panggil fungsi itu dari pendengar acara.

Kemudian, Anda juga dapat memanggil fungsi itu di tempat lain yang Anda perlukan untuk mencapai hal yang sama seperti yang dilakukan oleh acara saat kebakaran.

Saya menemukan ini kurang "kode intensif" dan lebih mudah dibaca.

Kirby L. Wallace
sumber
1
Bagaimana jika Anda ingin melakukan banyak hal berbeda untuk acara yang sama (atau yah, fungsi panggilan balik dalam kasus Anda) tergantung pada konteksnya? :) Ini adalah alternatif yang baik tetapi ini terasa lebih seperti komentar daripada jawaban karena OP ingin tahu bagaimana secara terprogram memicu suatu peristiwa yang bertentangan dengan menggunakan panggilan balik :)
SidOfc
Anda benar bahwa ini seharusnya komentar daripada jawaban. Mengapa? Karena, uhm, yah, .... tidak menjawab pertanyaan yang sebenarnya ditanyakan. Panggilan yang bagus. Mengenai pertanyaan Anda sendiri, saya akan mengatakan ini akan menjadi peluang besar bagi konstruktor dalam JavaScript! ;-) Tetapi tanpa mereka, saya katakan, mengirim argumen dengan pemanggilan fungsi Anda dan biarkan itu digunakan untuk menentukan apa yang harus dilakukan fungsi.
Kirby L. Wallace
5

Saya hanya menggunakan yang berikut ini (tampaknya jauh lebih sederhana):

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

Dalam hal ini acara dipicu hanya jika nilai benar-benar berubah sama seperti Anda akan memicu itu oleh lokus fokus normal yang hilang dilakukan oleh pengguna.

Aleksander Lech
sumber
1
Ini tidak memperhitungkan acara apa itu. Kabur dan fokus dapat memicu acara tetapi mungkin juga tidak. Ini mengundang bug.
Mardok
1
Ini juga berlaku untuk element.click().
AxeEffect
Ini memperbaiki masalah aneh untuk aplikasi Angular / Cordova saya, di Android, di mana textarea akan menolak untuk membersihkan sendiri. Jadi terima kasih.
DarkNeuron
5

Diubah @ Dorian jawaban untuk bekerja dengan 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/

LIHAT JUGA:
https://caniuse.com/#feat=customevent

Yarin
sumber
4

Jawaban yang diterima tidak bekerja untuk saya, tidak ada yang membuat createEvent melakukannya.

Apa yang berhasil bagi saya pada akhirnya adalah:

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

Berikut cuplikan:

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>

Dari membaca: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent

Ming
sumber
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
sumber
1
Ini sudah usang. Hanya berguna untuk polyfill. developer.mozilla.org/en-US/docs/Web/API/MouseEvent/…
hipkiss
1

Anda dapat menggunakan fungsi ini yang saya kompilasi bersama.

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

Picu acara di bawah ini:

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

Tonton Acara:

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

Semoga ini membantu!

Ifeanyi Amadi
sumber
1

Anda dapat menggunakan kode di bawah ini untuk memecat acara menggunakan metode Elemen:

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

Cara paling efisien adalah memanggil fungsi yang sama dengan yang telah didaftarkan addEventListener secara langsung.

Anda juga dapat memicu acara palsu dengan CustomEvent dan co.

Akhirnya beberapa elemen seperti <input type="file"> mendukung suatu .click()metode.

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

ini akan segera memicu suatu acara 'sebelum menginstalprompt'

Dan Alboteanu
sumber
-2

Gunakan panggilan acara jquery. Tulis baris di bawah ini di mana Anda ingin memicu onChange elemen apa pun.

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

element_id adalah ID elemen yang onChange-nya ingin Anda picu.

Hindari penggunaan

 element.fireEvent("onchange");

Karena memiliki dukungan yang sangat kurang. Rujuk dokumen ini untuk dukungannya .

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

Yang Anda inginkan adalah sesuatu seperti ini:

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

Menggunakan jQuery, itu akan menjadi seperti ini:

$(".example").trigger("click");
Osiris RD
sumber
metode pemicu tidak salah, tetapi ini adalah metode jquery
Kamuran Sönecek
2
1. document.getElementByClassNametidak ada. 2. document.getElementsByClassNameada tetapi mengembalikan daftar. 3. ini hanya berfungsi untuk beberapa acara asli tertentu. 4. Contoh terakhir memicu acara jQuery di mana tidak ada acara asli yang mendasarinya.
Glenn Jorde