Làm cách nào để kích hoạt sự kiện trong JavaScript?


523

Tôi đã đính kèm một sự kiện vào một hộp văn bản bằng cách sử dụng addEventListener. Nó hoạt động tốt. Vấn đề của tôi nảy sinh khi tôi muốn kích hoạt sự kiện theo chương trình từ một chức năng khác.

Tôi làm nó như thế nào?


11
Mozilla có một bài viết rất hay giải thích về việc Tạo và kích hoạt các sự kiện trong Javascript . Hy vọng nó giúp!
Ricky Stam

1
Vui lòng thay đổi câu trả lời được chấp nhận cho điều này , nó cập nhật hơn.
Michał Perłakowski

1
@RickyStam Có vẻ như bài viết MDN đã được chuyển đến đây
styfle

Câu trả lời:


454

Bạn có thể sử dụng fireEvent trên IE 8 hoặc giảm, và W3C của dispatchEvent trên hầu hết các trình duyệt khác. Để tạo sự kiện bạn muốn kích hoạt, bạn có thể sử dụng createEventhoặc createEventObjecttùy thuộc vào trình duyệt.

Đây là một đoạn mã tự giải thích (từ nguyên mẫu) thực hiện một sự kiện dataavailabletrên 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
Đừng quên rằng chỉ có phiên bản IE có 'bật' ở phía trước (lúc đầu tôi đã bỏ lỡ điều đó)
hugomg

45
Biến eventNamechứa gì ở đây?
NeDark

1
Yep dataav Available nên có trong eventName và ghi nhớ cũng nên được xác định (xác định thành {} là ok).
Charles

4
Internet Explorer 9+ xử lý createdEvent và ClarkEvent, do đó không cần những câu lệnh if.
Blake

5
Ví dụ này thậm chí không hoạt động, xem câu trả lời của tôi: stackoverflow.com/a/20548330/407213
Dorian

334

Một ví dụ làm việc:

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

Đối với các trình duyệt cũ polyfill và các ví dụ phức tạp hơn, hãy xem tài liệu MDN .

Xem bảng hỗ trợ cho EventTarget.dispatchEventCustomEvent.


11
Câu trả lời này là thực tế hơn bây giờ. Một điều cần thêm: nếu cần phải có một sự kiện được biết đến (như TransitionEvent , ClipboardEvent , v.v.) thì có thể gọi hàm tạo thích hợp.
Kiril

6
@AngelPolitis: Bởi vì nó được viết sau khi câu hỏi trước đã được chấp nhận và người viết câu hỏi (@KoolKabin) có lẽ đã không đọc lại câu trả lời
Dorian

4
Và bởi vì nó đã được hỏi vào năm 2010
DarkNeuron

Không hoạt động với bất kỳ phiên bản IE nào ( caniuse.com/#feat=customevent ). Xem câu trả lời của tôi để sửa chữa.
Yarin

Lưu ý cho người đọc trong tương lai, detaillà một thuộc tính của Event, vì vậy hãy gán bất kỳ dữ liệu nào bạn muốn truy cập ở đầu kia cho nó và truy cập theo event.detail. +1
daka

71

Nếu bạn không muốn sử dụng jQuery và đặc biệt không quan tâm đến khả năng tương thích ngược, chỉ cần sử dụng:

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

Xem tài liệu ở đâyở đây .

BIÊN TẬP: Tùy thuộc vào thiết lập của bạn, bạn có thể muốn thêm bubbles: true:

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

4
Đây phải là câu trả lời được chấp nhận vì nó không sử dụng các phương thức không dùng nữa như initEvent ()
user2912903

2
Giải pháp tuyệt vời, nhưng lưu ý rằng điều này sẽ không hoạt động trên IE11. Sau đó bạn nên sử dụng CustomEventvà theo polyfill.
Fabian von Ellerts

2
Tốt hơn câu trả lời được chọn
WitnessTruth

42

nếu bạn sử dụng jQuery, bạn có thể làm đơn giản

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

và xử lý nó với

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

trong đó "[arg0, arg1, ..., argN]" có nghĩa là các đối số này là tùy chọn.


4
Cú pháp đúng là $ ('# yourEuity'). Trigger ('customEventName', [arg0, arg1, ..., argN]); Bạn đã quên [] ở tham số thứ hai
harry

25

Nếu bạn đang hỗ trợ IE9 +, bạn có thể sử dụng như sau. Khái niệm tương tự được kết hợp trong 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...'
});


Nếu bạn đã sử dụng jQuery, đây là phiên bản mã jQuery ở trên.

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


Điều này sẽ không hoạt động đối với bất kỳ phiên bản IE nào, vì window.CustomEventnó tồn tại nhưng nó không thể được gọi là hàm tạo: caniuse.com/#search=CustomEvent ;)
SidOfc

13

Tôi đã tìm kiếm sự kiện nhấp chuột, mousedown và mouseup khi di chuột bằng JavaScript. Tôi tìm thấy một câu trả lời được cung cấp bởi Juan Mendes . Đối với câu trả lời bấm vào đây .

Bấm vào đây là bản demo trực tiếp và bên dưới là mã:

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

Chỉ để đề xuất một giải pháp thay thế không liên quan đến nhu cầu gọi thủ công một sự kiện người nghe:

Dù người nghe sự kiện của bạn làm gì, hãy chuyển nó vào một hàm và gọi hàm đó từ trình nghe sự kiện.

Sau đó, bạn cũng có thể gọi chức năng đó ở bất cứ nơi nào khác mà bạn cần để thực hiện điều tương tự mà sự kiện thực hiện khi nó kích hoạt.

Tôi thấy điều này ít "mã chuyên sâu" và dễ đọc hơn.


1
Điều gì sẽ xảy ra nếu bạn muốn làm nhiều việc khác nhau cho cùng một sự kiện (hoặc tốt, chức năng gọi lại trong trường hợp của bạn) tùy thuộc vào ngữ cảnh? :) Đó là một lựa chọn tốt nhưng điều này cảm thấy giống như một nhận xét hơn là một câu trả lời vì OP muốn biết cách kích hoạt lập trình một sự kiện thay vì sử dụng một cuộc gọi lại :)
SidOfc

Bạn hoàn toàn đúng rằng đây nên là một bình luận chứ không phải là một câu trả lời. Tại sao? Bởi vì, uhm, tốt, .... nó không trả lời câu hỏi thực sự được hỏi. Cuộc gọi tốt Đối với câu hỏi của riêng bạn, tôi muốn nói rằng đây sẽ là một cơ hội tuyệt vời cho các nhà xây dựng trong JavaScript! ;-) Nhưng nếu không có chúng, tôi sẽ nói, gửi một đối số với lệnh gọi hàm của bạn và để nó được sử dụng để xác định hàm nên làm gì.
Kirby L. Wallace

5

Tôi chỉ sử dụng như sau (có vẻ đơn giản hơn nhiều):

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

Trong trường hợp này, sự kiện chỉ được kích hoạt nếu giá trị thực sự thay đổi giống như bạn sẽ kích hoạt nó bởi vị trí tiêu điểm bình thường bị mất do người dùng thực hiện.


1
Điều này không tính đến loại sự kiện. Làm mờ và tập trung có thể kích hoạt sự kiện nhưng nó có thể không tốt. Đây là mời lỗi.
Mardok

1
Điều này cũng áp dụng cho element.click().
AxeEffect

Điều này đã khắc phục một sự cố kỳ lạ cho ứng dụng Angular / Cordova của tôi, trong Android, nơi mà vùng văn bản sẽ từ chối tự xóa. Cảm ơn
DarkNeuron

5

Đã sửa đổi câu trả lời của @ Dorian để làm việc với 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/

XEM CSONG:
https://caniuse.com/#feat=customevent


4

Câu trả lời được chấp nhận không có tác dụng với tôi, không ai trong số những người tạo ra.

Điều làm việc cho tôi cuối cùng là:

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

Đây là một đoạn:

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>

Từ đọc: 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
Điều này không được chấp nhận. Chỉ hữu ích cho polyfill. developer.mozilla.org/en-US/docs/Web/API/MouseEvent/ory
hipkiss

1

Bạn có thể sử dụng chức năng này tôi biên dịch cùng nhau.

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

Kích hoạt một sự kiện dưới đây:

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

Xem sự kiện:

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

Hi vọng điêu nay co ich!


1

Bạn có thể sử dụng mã dưới đây để kích hoạt sự kiện bằng phương thức 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

Cách hiệu quả nhất là gọi cùng chức năng đã được đăng ký với addEventListener trực tiếp.

Bạn cũng có thể kích hoạt một sự kiện giả mạo với CustomEvent và đồng.

Cuối cùng một số yếu tố như <input type="file">hỗ trợ một .click()phương thức.


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

điều này sẽ kích hoạt một sự kiện 'beforeinstallprompt'


-2

Sử dụng cuộc gọi sự kiện jquery. Viết dòng dưới đây mà bạn muốn kích hoạt onChange của bất kỳ phần tử nào.

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

Element_id là ID của phần tử có onChange bạn muốn kích hoạt.

Tránh sử dụng

 element.fireEvent("onchange");

Bởi vì nó có rất ít hỗ trợ. Tham khảo tài liệu này để được hỗ trợ .


-2

HTML

<a href="demoLink" id="myLink"> myLink </a>
<button onclick="fireLink(event)"> Call My Link </button>

Mã não

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

Những gì bạn muốn là một cái gì đó như thế này:

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

Sử dụng jQuery, nó sẽ giống như thế này:

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

Phương pháp kích hoạt không sai, nhưng đó là một phương pháp jquery
Kamuran Sönecek

2
1. document.getElementByClassNamekhông tồn tại. 2. document.getElementsByClassNametồn tại nhưng trả về một danh sách. 3. điều này chỉ hoạt động cho một vài sự kiện bản địa được chọn. 4. Ví dụ cuối cùng kích hoạt một sự kiện jQuery trong đó không có sự kiện gốc nào tồn tại.
Glenn Jorde
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.