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?


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

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.


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

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.


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>


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

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.


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.


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


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


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

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!


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


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.


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'


-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 .


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

-9

Yang Anda inginkan adalah sesuatu seperti ini:

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

Menggunakan jQuery, itu akan menjadi seperti ini:

$(".example").trigger("click");

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.