Come attivare l'evento in JavaScript?


523

Ho allegato un evento a una casella di testo utilizzando addEventListener. Funziona bene Il mio problema è sorto quando volevo attivare l'evento a livello di codice da un'altra funzione.

Come posso farlo?


11
Mozilla ha un bellissimo articolo che spiega come creare e attivare eventi in Javascript . Spero che sia d'aiuto!
Ricky Stam,

1
Si prega di cambiare la risposta accettata a questo , è più aggiornato.
Michał Perłakowski il

1
@RickyStam Sembra che l'articolo MDN sia stato spostato qui
Styfle

Risposte:


454

È possibile utilizzare fireEvent su IE 8 o versioni precedenti e il dispatchEvent di W3C sulla maggior parte degli altri browser. Per creare l'evento che si desidera attivare, è possibile utilizzare uno createEvento in createEventObjectbase al browser.

Ecco un pezzo di codice autoesplicativo (dal prototipo) che genera un evento dataavailablesu 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);
}

6
Non dimenticare che solo la versione di IE ha "on" davanti (l'ho perso all'inizio)
hugomg

45
Cosa contiene la variabile eventNamequi?
NeDark,

1
I dati disponibili dovrebbero essere in eventName e anche il memo deve essere definito (definire su {} è ok).
Charles,

4
Internet Explorer 9+ gestisce createEvent e dispatchEvent, quindi non sono necessarie istruzioni if.
Blake,

5
Questo esempio non funziona nemmeno, vedi la mia risposta: stackoverflow.com/a/20548330/407213
Dorian

334

Un esempio funzionante:

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

Per il polyfill dei browser meno recenti e esempi più complessi, consultare i documenti MDN .

Vedere le tabelle di supporto per EventTarget.dispatchEvente CustomEvent.


11
Questa risposta è più attuale ora. Una cosa da aggiungere: se dovesse esserci un evento tipizzato (come TransitionEvent , ClipboardEvent , ecc.), Potrebbe essere chiamato il costruttore appropriato.
Kiril,

6
@AngelPolitis: Perché è stato scritto dopo che la precedente era già stata accettata e la persona che ha scritto la domanda (@KoolKabin) probabilmente non ha riletto le risposte
Dorian

4
E perché è stato chiesto nel 2010
DarkNeuron l'

Non funziona con nessuna versione di IE ( caniuse.com/#feat=customevent ). Vedi la mia risposta per una correzione.
Yarin,

Nota per i lettori futuri, detailè una proprietà di Event, quindi assegna a tutti i dati a cui vuoi accedere dall'altra parte e accedi tramite event.detail. +1
daka,

71

Se non vuoi usare jQuery e non sei particolarmente preoccupato per la retrocompatibilità, usa semplicemente:

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

Vedi la documentazione qui e qui .

MODIFICA: a seconda della configurazione, potresti voler aggiungere bubbles: true:

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

4
Questa dovrebbe essere la risposta accettata in quanto non utilizza metodi obsoleti come initEvent ()
user2912903

2
Bella soluzione, ma tieni presente che non funzionerà su IE11. Dovresti quindi utilizzare CustomEventil polyfill corrispondente.
Fabian von Ellerts

2
Meglio della risposta selezionata
WitnessTruth,

42

se usi jQuery, puoi semplicemente farlo

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

e gestirlo con

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

dove "[arg0, arg1, ..., argN]" significa che questi argomenti sono opzionali.


4
La sintassi corretta è $ ('# yourElement'). Trigger ('customEventName', [arg0, arg1, ..., argN]); Hai dimenticato [] al secondo parametro
harry

25

Se si supporta IE9 +, è possibile utilizzare quanto segue. Lo stesso concetto è incorporato in 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...'
});


Se stai già utilizzando jQuery, ecco la versione jQuery del codice sopra.

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


Questo non funzionerà per nessuna versione di IE, poiché window.CustomEventesiste ma non può essere chiamato come costruttore: caniuse.com/#search=CustomEvent ;)
SidOfc

13

Ho cercato l'evento click, mousedown e mouseup di attivazione al passaggio del mouse utilizzando JavaScript. Ho trovato una risposta fornita da Juan Mendes . Per la risposta clicca qui .

Fai clic qui per la demo live e sotto il codice:

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

Solo per suggerire un'alternativa che non comporta la necessità di invocare manualmente un evento listener:

Qualunque cosa faccia il tuo listener di eventi, spostalo in una funzione e chiama quella funzione dal listener di eventi.

Quindi, puoi anche chiamare quella funzione in qualsiasi altro luogo per eseguire la stessa cosa che l'evento fa quando si attiva.

Trovo questo meno "ad alta intensità di codice" e più facile da leggere.


1
Cosa succede se si desidera fare più cose diverse per lo stesso evento (o bene, la funzione di callback nel proprio caso) a seconda del contesto? :) È una buona alternativa, ma sembra più un commento che una risposta poiché l'OP vuole sapere come innescare a livello di programmazione un evento invece di usare un callback :)
SidOfc

Hai perfettamente ragione sul fatto che questo avrebbe dovuto essere un commento piuttosto che una risposta. Perché? Perché, uhm, beh, .... non risponde alla domanda che è stata effettivamente posta. Ottima scelta. Per quanto riguarda la tua domanda, direi che sarebbe una grande opportunità per i costruttori in JavaScript! ;-) Ma senza di loro, direi, invia un argomento con la tua chiamata di funzione e lascia che sia usato per determinare cosa dovrebbe fare la funzione.
Kirby L. Wallace,

5

Ho appena usato il seguente (sembra essere molto più semplice):

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

In questo caso, l'evento viene attivato solo se il valore è stato realmente modificato, così come lo si innescerebbe dal normale focus locus perso eseguito dall'utente.


1
Questo non tiene conto del tipo di evento. La sfocatura e la messa a fuoco possono innescare l'evento, ma potrebbe anche non esserlo. Questo è invitante bug.
Mardok,

1
Questo vale anche per element.click().
AxeEffect,

Questo risolto un problema strano per la mia app Angular / Cordova, in Android, in cui la textarea si sarebbe rifiutata di cancellarsi. Quindi grazie.
DarkNeuron,

5

Modificata la risposta di Dorian per lavorare con 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/

VEDERE ANCHE:
https://caniuse.com/#feat=customevent


4

La risposta accettata non ha funzionato per me, nessuno di quelli createEvent ha funzionato.

Ciò che ha funzionato per me alla fine è stato:

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

Ecco uno snippet:

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>

Dalla lettura: 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
Questo è deprecato. Utile solo per i polyfill. developer.mozilla.org/en-US/docs/Web/API/MouseEvent/…
hipkiss

1

È possibile utilizzare questa funzione che ho compilato insieme.

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

Attiva un evento di seguito:

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

Guarda l'evento:

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

Spero che sia di aiuto!


1

Puoi usare il codice seguente per generare l'evento usando il metodo 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);
        }
    };
}


0

Il modo più efficiente è chiamare la stessa funzione con cui è stata registrata addEventListenerdirettamente.

Puoi anche attivare un evento falso con CustomEvente co.

Infine alcuni elementi come <input type="file">supportano un .click()metodo.


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

questo attiverà immediatamente un evento 'beforeinstallprompt'


-2

Usa la chiamata all'evento jquery. Scrivi la riga in basso in cui desideri attivare onChange di qualsiasi elemento.

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

element_id è l'ID dell'elemento di cui desideri attivare onChange.

Evitare l'uso di

 element.fireEvent("onchange");

Perché ha molto meno supporto. Consultare questo documento per il suo supporto .


-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

Quello che vuoi è qualcosa del genere:

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

Usando jQuery, sarebbe qualcosa del genere:

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

il metodo di trigger non è sbagliato, ma è un metodo jquery
Kamuran Sönecek,

2
1. document.getElementByClassNamenon esiste. 2. document.getElementsByClassNameesiste ma restituisce un elenco. 3. funziona solo per alcuni eventi nativi selezionati. 4. L'ultimo esempio attiva un evento jQuery in cui non esiste alcun evento nativo sottostante.
Glenn Jorde,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.