Як запустити подію в JavaScript?


523

Я додав подію до текстового поля за допомогою addEventListener. Це чудово працює. Моя проблема виникла, коли я хотів програмно запустити подію з іншої функції.

Як я можу це зробити?


11
У Mozilla є дуже приємна стаття, яка пояснює створення та запуск подій у Javascript . Сподіваюся, це допомагає!
Ricky Stam

1
Будь ласка, змініть прийняту відповідь на це , вона є більш актуальною.
Michał Perłakowski

1
@RickyStam Схоже, що сюди перенесли
styfle

Відповіді:


454

Ви можете використовувати fireEvent на IE 8 або новішої версії , а W3C - dispatchEvent у більшості інших браузерів. Щоб створити подію, яку ви хочете запустити, ви можете використовувати createEventабо в createEventObjectзалежності від браузера.

Ось роз'яснювальний фрагмент коду (від прототипу), який запускає подію dataavailableна 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
Не забувайте, що лише у версії IE попереду "увімкнено" (я пропустив це спочатку)
hugomg

45
Що eventNameтут містить змінна ?
NeDark

1
Так, дані мають бути в eventName, а також нагадування слід також визначити (визначте {{нормально).
Чарльз

4
Internet Explorer 9+ обробляє createEvent і dispatchEvent, тому немає необхідності в цих операторах.
Блейк

5
Цей приклад навіть не працює, дивіться мою відповідь: stackoverflow.com/a/20548330/407213
Доріан

334

Робочий приклад:

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

Про старіші заповнення браузерів та більш складні приклади див . У документах MDN .

Див. Таблиці підтримки для EventTarget.dispatchEventта CustomEvent.


11
Ця відповідь зараз актуальніша. Ще одне, що слід додати: якщо має бути відома подія (наприклад TransitionEvent , ClipboardEvent тощо), може бути викликаний відповідний конструктор.
Кирило

6
@AngelPolitis: Тому що це було написано після того, як попереднє було вже прийняте, і людина, яка написала запитання (@KoolKabin), ймовірно, не перечитала відповіді
Доріан

4
А тому, що його запитали у 2010 році
DarkNeuron

Не працюватиме з будь-якою версією IE ( caniuse.com/#feat=customevent ). Дивіться мою відповідь для виправлення.
Ярін

Примітка для майбутніх читачів detail- це властивість Event, тому призначте будь-які дані, до яких ви хочете отримати доступ з іншого кінця, та отримайте доступ до них event.detail. +1
дака

71

Якщо ви не хочете використовувати jQuery і не особливо стурбовані зворотною сумісністю, просто використовуйте:

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

Дивіться документацію тут і тут .

РЕДАКТУВАННЯ. Залежно від налаштувань ви можете додати bubbles: true:

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

4
Це має бути прийнятою відповіддю, оскільки він не використовує застарілі методи, такі як initEvent ()
user2912903

2
Приємне рішення, але пам’ятайте, що це не працюватиме на IE11. Потім слід використовувати CustomEventі відповідний поліфіл.
Фабіан фон Еллертс

2
Краще, ніж обрана відповідь
WitnessTruth

42

якщо ви використовуєте jQuery, це можна зробити просто

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

і впоратися з цим

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

де "[arg0, arg1, ..., argN]" означає, що ці аргументи необов'язкові.


4
Правильний синтаксис - $ ('# yourElement'). Тригер ('customEventName', [arg0, arg1, ..., argN]); Ви забули [] за другим параметром
гаррі

25

Якщо ви підтримуєте IE9 +, ви можете скористатися наступним. Ця ж концепція закладена в 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...'
});


Якщо ви вже використовуєте jQuery, ось версія jQuery коду вище.

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


Це не працює для будь-якої версії IE, оскільки window.CustomEventіснує, але її не можна назвати конструктором: caniuse.com/#search=CustomEvent ;)
SidOfc

13

Я шукав події натискання, миші та миші при переході миші за допомогою JavaScript. Я знайшов відповідь, яку надав Хуан Мендес . Для відповіді натисніть тут .

Клацніть тут - демонстрація в реальному часі, а нижче - код:

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

Просто запропонуйте альтернативу, яка не передбачає необхідності вручну викликати події слухача:

Що б ваш слухач подій не робив, перемістіть його у функцію та зателефонуйте їй у слухача події.

Потім ви можете також зателефонувати на цю функцію де завгодно, що вам потрібно виконати те саме, що робить подія під час її запуску.

Я вважаю це менш "інтенсивним кодом" і його легше читати.


1
Що робити, якщо ви хочете зробити кілька різних речей для однієї події (або добре, функція зворотного дзвінка у вашому випадку) залежно від контексту? :) Це гарна альтернатива, але це більше схоже на коментар, ніж на відповідь, оскільки ОП хоче знати, як програмно викликати подію на відміну від зворотного дзвінка :)
SidOfc

Ви абсолютно праві, що це повинен був бути коментарем, а не відповіддю. Чому? Тому що, ну, ну .... це не відповідає на запитання, яке було насправді задано. Гарний дзвінок. Щодо вашого власного питання, я б сказав, що це буде чудовою можливістю для конструкторів у JavaScript! ;-) Але без них я б сказав, надішліть аргумент із вашим викликом функції і нехай це буде використано для визначення того, що функція повинна робити.
Кірбі Л. Уоллес

5

Я просто використав наступне (здається, набагато простіше):

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

У цьому випадку подія запускається лише в тому випадку, якщо значення було дійсно змінено так само, як ви викликали б його нормальний локус фокусування, який виконує користувач.


1
Це не враховує, що це за подія. Розмивання та фокусування можуть спричинити подію, але це може не так. Це запрошення помилок.
Мардок

1
Це стосується і element.click().
AxeEffect

Це вирішило дивну проблему для мого додатка Angular / Cordova в Android, де textarea відмовилась би очиститись. Тож спасибі
DarkNeuron

5

Модифікований @ Доріана відповідь на роботу з 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);

ПЕРЕДАЧА: https://jsfiddle.net/z6zom9d0/1/

ВИДАЙТЕ ТАКОЖ:
https://caniuse.com/#feat=customevent


4

Прийнята відповідь не спрацювала для мене, ніхто з createEvent не зробив.

Що зрештою для мене спрацювало:

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

Ось фрагмент:

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>

З читання: 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
Це застаріло. Корисний лише для поліфілів. developer.mozilla.org/en-US/docs/Web/API/MouseEvent/…
hipkiss

1

Ви можете використовувати цю функцію, яку я компілював разом.

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

Запустити подію нижче:

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

Дивитися подію:

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

Сподіваюся, це допомагає!


1

Ви можете використовувати код нижче, щоб запустити подію методом 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

Найефективніший спосіб - викликати ту саму функцію, яку було зареєстровано addEventListenerбезпосередньо.

Ви також можете запустити фальшиву подію з CustomEventі co.

Нарешті, деякі елементи, такі як метод <input type="file">підтримки .click().


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

це негайно спровокує подію "до встановлення"


-2

Використовуйте виклик події jquery. Напишіть рядок нижче, де потрібно запустити onChange будь-якого елемента.

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

element_id - ідентифікатор елемента, чию зміну ви хочете запустити.

Уникайте використання

 element.fireEvent("onchange");

Тому що він має дуже меншу підтримку. Зверніться до цього документа для його підтримки .


-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

Те, що ви хочете, є приблизно таким:

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

Використовуючи jQuery, це було б щось подібне:

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

метод тригера не помиляється, але це метод jquery
Kamuran Sönecek

2
1. document.getElementByClassNameне існує. 2. document.getElementsByClassNameіснує, але повертає список. 3. це працює лише для кількох місцевих подій. 4. Останній приклад запускає подію jQuery, де не існує основної події.
Glenn Jorde
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.