JavaScript'te etkinlik nasıl tetiklenir?


523

Kullanarak bir metin kutusuna bir olay ekledim addEventListener. İyi çalışıyor. Olayı programlı olarak başka bir işlevden tetiklemek istediğimde sorunum ortaya çıktı.

Nasıl yapabilirim?


11
Mozilla'nın Javascript'te etkinlik oluşturma ve tetikleme konusunda çok güzel bir makalesi var . Umarım yardımcı olur!
Ricky Stam

1
İçin kabul edilen cevabını değiştirin bu , bu kadar fazla yukarı güncel.
Michał Perłakowski

1
@RickyStam MDN makalesi buraya taşınmış
styfle

Yanıtlar:


454

Sen kullanabilirsiniz FireEvent üzerinde IE 8 veya daha düşük ve W3C dispatchEvent üzerinde en diğer tarayıcılar. Ateşlemek istediğiniz etkinliği oluşturmak için tarayıcıdan birini createEventveya createEventObjecttarayıcıyı kullanabilirsiniz.

İşte bir etkinlik tetikleyecek (prototipten) kod kendini açıklayan parçasıdır dataavailable, bir de 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
Unutmayın sadece IE sürümü önünde 'açık' (ilk başta özledim)
hugomg

45
Değişken eventNameburada ne içeriyor?
NeDark

1
Kullanılabilir veri olayı eventName olmalı ve not da tanımlanmalıdır ({} için tanım tamam).
Charles

4
Internet Explorer 9+, createEvent ve dispatchEvent öğelerini işler, bu nedenle if ifadelerine gerek yoktur.
Blake

5
Bu örnek bile işe yaramıyor, cevabımı görün: stackoverflow.com/a/20548330/407213
Dorian

334

Çalışan bir örnek:

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

Daha eski tarayıcıların çoklu dolgusu ve daha karmaşık örnekler için bkz. MDN belgeleri .

İçin destek tablolara bakın EventTarget.dispatchEventve CustomEvent.


11
Bu cevap şimdi daha gerçek. Eklenecek bir şey var: Bilenmiş bir olay ( TransitionEvent , ClipboardEvent , vb. Gibi) olması durumunda uygun kurucu çağrılabilir.
Kiril

6
@AngelPolitis: Çünkü bir önceki kabul edildikten sonra yazılmış ve soruyu yazan kişi (@KoolKabin) muhtemelen cevapları tekrar okumamıştı
Dorian

4
Ve 2010'da sorulduğu için
DarkNeuron

IE'nin herhangi bir sürümü ile çalışmaz ( caniuse.com/#feat=customevent ). Düzeltme için cevabımı görün .
Yarin

Gelecekteki okuyuculara not detail, bir özelliğidir Event, bu nedenle diğer ucundan erişmek ve erişmek için istediğiniz verileri atayın event.detail. +1
daka

71

JQuery kullanmak istemiyorsanız ve özellikle geriye dönük uyumluluktan endişe etmiyorsanız, şunları kullanın:

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

Buradaki ve buradaki belgelere bakın .

EDIT: Kurulumunuza bağlı olarak eklemek isteyebilirsiniz bubbles: true:

let element = document.getElementById(id);
element.dispatchEvent(new Event('change', { 'bubbles': true }));

4
Bu initEvent () gibi kaldırılmış yöntemleri kullanmaz olarak kabul cevap olmalıdır
user2912903

2
Güzel bir çözüm, ancak bunun IE11 üzerinde çalışmayacağını unutmayın. Daha sonra CustomEventve uygun poli dolguyu kullanmalısınız .
Fabian von Ellerts

2
Seçilen cevaptan daha iyi
WitnessTruth

42

jQuery kullanıyorsanız, basit

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

ve onunla başa çık

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

burada "[arg0, arg1, ..., argN]" bu bağımsız değişkenlerin isteğe bağlı olduğu anlamına gelir.


4
Doğru sözdizimi $ ('# yourElement'). Trigger ('customEventName', [arg0, arg1, ..., argN]); İkinci parametrede [] unuttunuz
harry

25

IE9 + 'yı destekliyorsanız aşağıdakileri kullanabilirsiniz. Aynı kavram jQuery'ye ihtiyacınız olmayabilir .

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


Zaten jQuery kullanıyorsanız, yukarıdaki kodun jQuery sürümü.

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


Bu, herhangi bir IE sürümü için window.CustomEventmevcut değildir, ancak bir yapıcı olarak çağrılamaz : caniuse.com/#search=CustomEvent ;)
SidOfc

13

JavaScript kullanarak fareyle üzerine gelindiğinde tıklatma, fareyle üzerine gelme ve fare olayını aradım. Juan Mendes tarafından verilen bir cevap buldum . Cevap için buraya tıklayın .

Buraya tıklayın canlı demo ve aşağıda kodu:

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

Bir dinleyici etkinliğini manuel olarak başlatma ihtiyacını içermeyen bir alternatif önermek için:

Olay dinleyiciniz ne yaparsa yapın, onu bir işleve taşıyın ve olay dinleyicisinden bu işlevi çağırın.

Ardından, bu işlevi, etkinliğin tetiklendiğinde yaptığıyla aynı şeyi gerçekleştirmeniz gereken başka herhangi bir yerde de çağırabilirsiniz.

Bu daha az "kod yoğun" ve okunması kolay buluyorum.


1
Bağlama bağlı olarak, aynı etkinlik için (veya durumunuzda geri arama işlevi) birden çok farklı şey yapmak isterseniz ne olur? :) İyi bir alternatif ama OP bir geri arama kullanmak yerine programlı olarak bir olayı nasıl tetiklemek istediğini bilmek istediğinden, bu bir yanıttan daha çok bir yorum gibi geliyor :)
SidOfc

Bunun bir cevaptan ziyade bir yorum olması gerektiği konusunda haklısınız. Neden? Çünkü, uhm, şey, ... aslında sorulan soruya cevap vermiyor. İyi karar. Kendi sorunuza gelince, bunun JavaScript'teki inşaatçılar için harika bir fırsat olacağını söyleyebilirim! ;-) Ama onlarsız, diyebilirim ki, fonksiyon çağrınızla bir argüman gönderin ve bunun fonksiyonun ne yapması gerektiğini belirlemek için kullanılmasına izin verin.
Kirby L. Wallace

5

Sadece aşağıdakileri kullandım (çok daha basit görünüyor):

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

Bu durumda olay, yalnızca değer, kullanıcı tarafından gerçekleştirilen normal odak noktası kaybıyla tetiklediğiniz gibi gerçekten değiştirildiyse tetiklenir.


1
Bu ne tür bir olay olduğunu dikkate almaz. Bulanıklaştırma ve odaklanma olayı tetikleyebilir, ancak bu da olmayabilir. Bu böcekleri davet ediyor.
Mardok

1
Bu aynı zamanda geçerlidir element.click().
AxeEffect

Bu, Android'deki Angular / Cordova uygulamam için, textarea'nın kendisini temizlemeyi reddedeceği garip bir sorunu düzeltti. Çok teşekkürler.
DarkNeuron

5

@ Dorian'ın IE ile çalışmaya cevabı değiştirildi:

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/

AYRICA BAKIN:
https://caniuse.com/#feat=customevent


4

Kabul edilen cevap benim için işe yaramadı, createEvent'in hiçbiri işe yaramadı.

Sonunda benim için işe yarayan şuydu:

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

İşte bir pasaj:

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>

Okumadan: 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
Bu kullanımdan kaldırıldı. Sadece çoklu dolgular için kullanışlıdır. developer.mozilla.org/tr-TR/docs/Web/API/MouseEvent/…
hipkiss

1

Birlikte derlediğim bu işlevi kullanabilirsiniz.

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

Aşağıdaki bir etkinliği tetikleyin:

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

Etkinliği İzle:

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

Bu yardımcı olur umarım!


1

Element yöntemini kullanarak olayı tetiklemek için aşağıdaki kodu kullanabilirsiniz:

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

En etkili yol, addEventListenerdoğrudan kaydedilmiş olan aynı işlevi çağırmaktır .

Ayrıca CustomEventve co ile sahte bir olayı tetikleyebilirsiniz .

Son olarak, bazı unsurlar <input type="file">bir .click()yöntemi desteklemektedir .


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

bu, hemen 'eventinstall' isteminden önce bir etkinliği tetikler


-2

Jquery olay çağrısı kullanın. Herhangi bir öğeyi değiştirmek için aşağıdaki satırı yazın.

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

element_id , onChange öğesini tetiklemek istediğiniz öğenin kimliğidir.

Kullanmaktan kaçının

 element.fireEvent("onchange");

Çünkü çok daha az desteği var. Desteği için bu belgeye başvurun .


-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

Ne istiyorsun böyle bir şey:

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

JQuery kullanmak, böyle bir şey olurdu:

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

tetikleme yöntemi yanlış değil, ama bir jquery yöntemidir
Kamuran Sönecek

2
1. document.getElementByClassNamemevcut değil. 2. document.getElementsByClassNamevar ama bir liste döndürüyor. 3. Bu yalnızca belirli birkaç yerel etkinlik için geçerlidir. 4. Son örnek, temel bir yerel olayın bulunmadığı bir jQuery olayını tetikler.
Glenn Jorde
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.