Tổng hợp Event (Sự kiện) trong JavaScript
Trần Thị Vân
- 110
- 25/07/2026
Khám phá đầy đủ kiến thức về Event (Sự kiện) trong JavaScript từ khái niệm, cách hoạt động, Event Object, Event Listener, Bubbling, Capturing, Delegation đến các nhóm sự kiện phổ biến kèm ví dụ dễ hiểu, chi tiết như nào hãy cùng chúng tôi phân tích:
Event (sự kiện) là một trong những nền tảng quan trọng nhất của JavaScript. Nhờ cơ chế này, trang web có thể phản hồi ngay lập tức khi người dùng nhấp chuột, nhập dữ liệu, cuộn trang, thay đổi kích thước cửa sổ hoặc thực hiện hàng trăm thao tác khác. Nếu không có Event, một website sẽ chỉ hiển thị nội dung tĩnh mà không thể tương tác.
Trong bài viết này, Web Mới sẽ tổng hợp đầy đủ kiến thức về Event trong JavaScript, từ khái niệm, cách hoạt động, các nhóm sự kiện phổ biến cho đến những kỹ thuật xử lý hiện đại. Nội dung được trình bày theo hướng thực tế, dễ hiểu và phù hợp cho cả người mới học lẫn lập trình viên muốn hệ thống lại kiến thức.

Event trong JavaScript là gì?
Event (Sự kiện) là những hành động hoặc trạng thái xảy ra trên trình duyệt và có thể được JavaScript theo dõi để thực hiện một đoạn mã tương ứng.
Sự kiện có thể được tạo ra bởi:
- Người dùng thao tác với chuột.
- Người dùng sử dụng bàn phím.
- Trình duyệt tải xong tài nguyên.
- Form được gửi.
- Video phát hoặc kết thúc.
- Thiết bị thay đổi kích thước màn hình.
- JavaScript chủ động phát sinh sự kiện.
Ví dụ, khi người dùng nhấn vào một nút, JavaScript có thể hiển thị thông báo, gửi dữ liệu lên máy chủ hoặc thay đổi giao diện ngay lập tức.
Cơ chế hoạt động của Event
Mỗi khi một sự kiện xảy ra, trình duyệt sẽ tạo ra một đối tượng Event chứa toàn bộ thông tin liên quan đến sự kiện đó. Sau đó, trình duyệt sẽ tìm những hàm đã đăng ký lắng nghe sự kiện và thực thi chúng.
Quá trình này thường diễn ra theo các bước:
- Người dùng hoặc trình duyệt tạo ra sự kiện.
- Đối tượng Event được sinh ra.
- JavaScript kiểm tra xem có Event Listener nào đang lắng nghe không.
- Nếu có, callback tương ứng sẽ được gọi.
- Đoạn mã bên trong callback được thực thi.
Đây chính là mô hình lập trình hướng sự kiện (Event-Driven Programming) mà hầu hết các ứng dụng web hiện đại đều sử dụng.
Các thành phần chính khi xử lý sự kiện
Event
Là hành động đã xảy ra.
Ví dụ:
- click
- input
- keydown
- scroll
- submit
Event Target
Là phần tử phát sinh sự kiện.
Ví dụ người dùng nhấn vào nút Đăng ký thì chính nút đó là Event Target.
Event Listener
Là hàm được đăng ký để theo dõi một sự kiện cụ thể.
Callback Function
Đây là hàm sẽ được gọi khi sự kiện thực sự xảy ra.
Cách đăng ký Event trong JavaScript
Có nhiều cách để gắn sự kiện cho phần tử HTML, tuy nhiên hiện nay phương pháp sử dụng addEventListener() được khuyến khích nhất.
Sử dụng addEventListener()
const button = document.querySelector("#btn");
button.addEventListener("click", function () {
alert("Bạn vừa nhấn nút.");
});
Đây là cách hiện đại vì:
- Có thể đăng ký nhiều sự kiện trên cùng một phần tử.
- Dễ quản lý.
- Dễ gỡ bỏ.
- Không ghi đè Event khác.
Sử dụng thuộc tính của phần tử
const button = document.querySelector("#btn");
button.onclick = function () {
alert("Hello");
};
Nhược điểm là mỗi phần tử chỉ có thể lưu một hàm cho từng loại sự kiện.
Viết trực tiếp trong HTML
Cách này vẫn hoạt động nhưng không còn được khuyến khích trong các dự án hiện đại.
<button onclick="showMessage()">
Nhấn vào đây
</button>
Việc trộn JavaScript vào HTML sẽ khiến mã nguồn khó bảo trì khi dự án phát triển lớn.
Nhóm Event chuột (Mouse Events)
Đây là nhóm sự kiện xuất hiện nhiều nhất trên website.
| Sự kiện | Mô tả |
|---|---|
| click | Nhấn chuột. |
| dblclick | Nhấn đúp chuột. |
| mousedown | Bắt đầu nhấn chuột. |
| mouseup | Thả chuột. |
| mousemove | Di chuyển chuột. |
| mouseenter | Chuột đi vào phần tử. |
| mouseleave | Chuột rời phần tử. |
| contextmenu | Nhấn chuột phải. |
Ví dụ:
const box = document.querySelector(".box");
box.addEventListener("mouseenter", function () {
console.log("Chuột vừa đi vào.");
});
Nhóm Event bàn phím
Những sự kiện này được sử dụng khi làm form, game hoặc xử lý phím tắt.
| Sự kiện | Ý nghĩa |
|---|---|
| keydown | Nhấn phím xuống. |
| keyup | Nhả phím. |
Ví dụ:
document.addEventListener("keydown", function (event) {
console.log(event.key);
});
Thuộc tính event.key cho biết chính xác phím mà người dùng vừa nhấn.
Nhóm Event dành cho Form
Khi xây dựng biểu mẫu đăng ký, đăng nhập, tìm kiếm hoặc nhập dữ liệu, JavaScript thường sử dụng các sự kiện của Form để kiểm tra dữ liệu và phản hồi ngay khi người dùng thao tác.
| Sự kiện | Mô tả |
|---|---|
| submit | Xảy ra khi biểu mẫu được gửi. |
| change | Giá trị của phần tử thay đổi và đã hoàn tất. |
| input | Kích hoạt ngay khi dữ liệu thay đổi. |
| focus | Con trỏ được đặt vào phần tử. |
| blur | Con trỏ rời khỏi phần tử. |
| reset | Biểu mẫu được đặt lại. |
Sự kiện submit
Đây là sự kiện quan trọng nhất của Form. Nó thường được dùng để kiểm tra dữ liệu trước khi gửi lên máy chủ.
const form = document.querySelector("form");
form.addEventListener("submit", function (event) {
event.preventDefault();
console.log("Đã chặn gửi Form.");
});
Phương thức preventDefault() giúp ngăn trình duyệt gửi Form ngay lập tức, từ đó JavaScript có thể kiểm tra dữ liệu trước.
Sự kiện input
Sự kiện này xảy ra mỗi khi người dùng nhập hoặc xóa ký tự.
const input = document.querySelector("#name");
input.addEventListener("input", function () {
console.log(input.value);
});
Đây là lựa chọn phù hợp khi cần kiểm tra dữ liệu theo thời gian thực.
Sự kiện change
Khác với input, change chỉ được kích hoạt sau khi người dùng hoàn tất việc thay đổi giá trị.
const select = document.querySelector("#city");
select.addEventListener("change", function () {
console.log(select.value);
});
Sự kiện focus và blur
Hai sự kiện này thường được dùng để tạo hiệu ứng khi người dùng bắt đầu hoặc kết thúc việc nhập dữ liệu.
const email = document.querySelector("#email");
email.addEventListener("focus", function () {
console.log("Đang nhập email.");
});
email.addEventListener("blur", function () {
console.log("Đã rời ô nhập.");
});
Nhóm Event của Window và Document
Ngoài các phần tử HTML, chính cửa sổ trình duyệt và tài liệu cũng có rất nhiều sự kiện hữu ích.
| Sự kiện | Mô tả |
|---|---|
| load | Toàn bộ trang đã tải xong. |
| DOMContentLoaded | HTML đã được phân tích xong. |
| resize | Thay đổi kích thước cửa sổ. |
| scroll | Người dùng cuộn trang. |
| beforeunload | Chuẩn bị rời khỏi trang. |
Sự kiện DOMContentLoaded
Sự kiện này được sử dụng rất phổ biến vì chỉ cần HTML sẵn sàng mà không phải đợi toàn bộ hình ảnh hoặc video tải xong.
document.addEventListener("DOMContentLoaded", function () {
console.log("HTML đã sẵn sàng.");
});
Sự kiện load
Khác với DOMContentLoaded, load chỉ xảy ra sau khi tất cả tài nguyên trên trang đều đã tải hoàn tất.
window.addEventListener("load", function () {
console.log("Trang đã tải hoàn toàn.");
});
Sự kiện scroll
Sự kiện này thường được dùng để tạo nút lên đầu trang, hiệu ứng xuất hiện khi cuộn hoặc tải thêm nội dung.
window.addEventListener("scroll", function () {
console.log(window.scrollY);
});
Sự kiện resize
Khi cửa sổ trình duyệt thay đổi kích thước, JavaScript có thể cập nhật giao diện phù hợp.
window.addEventListener("resize", function () {
console.log(window.innerWidth);
});
Nhóm Clipboard Event
Clipboard Event giúp theo dõi các thao tác sao chép, cắt hoặc dán nội dung.
| Sự kiện | Mô tả |
|---|---|
| copy | Sao chép dữ liệu. |
| cut | Cắt dữ liệu. |
| paste | Dán dữ liệu. |
Ví dụ:
document.addEventListener("copy", function () {
console.log("Đã sao chép.");
});
Nhóm Drag and Drop Event
Kéo và thả là tính năng thường gặp trong các ứng dụng quản lý tệp, bảng Kanban hoặc trình chỉnh sửa trực tuyến.
| Sự kiện | Mô tả |
|---|---|
| dragstart | Bắt đầu kéo. |
| drag | Đang kéo. |
| dragenter | Đi vào vùng nhận. |
| dragover | Đang ở trên vùng nhận. |
| drop | Thả đối tượng. |
| dragend | Kết thúc kéo. |
Ví dụ:
const item = document.querySelector(".item");
item.addEventListener("dragstart", function () {
console.log("Bắt đầu kéo.");
});
Nhóm Event dành cho Media
Các phần tử âm thanh và video cũng hỗ trợ nhiều sự kiện để theo dõi trạng thái phát.
| Sự kiện | Mô tả |
|---|---|
| play | Bắt đầu phát. |
| pause | Tạm dừng. |
| ended | Đã phát hết. |
| volumechange | Âm lượng thay đổi. |
| timeupdate | Thời gian phát thay đổi. |
Ví dụ:
const video = document.querySelector("video");
video.addEventListener("play", function () {
console.log("Video đang phát.");
});
Đối tượng Event trong JavaScript
Mỗi khi một sự kiện xảy ra, JavaScript sẽ truyền vào hàm xử lý một đối tượng Event. Đối tượng này chứa rất nhiều thông tin liên quan đến sự kiện.
Một số thuộc tính và phương thức được sử dụng nhiều gồm:
| Thuộc tính hoặc phương thức | Ý nghĩa |
|---|---|
| target | Phần tử phát sinh sự kiện. |
| currentTarget | Phần tử đang xử lý sự kiện. |
| type | Tên sự kiện. |
| preventDefault() | Ngăn hành động mặc định. |
| stopPropagation() | Ngăn sự kiện lan truyền. |
Ví dụ:
document.querySelector("#btn").addEventListener("click", function (event) {
console.log(event.type);
console.log(event.target);
});
Đối tượng Event đóng vai trò rất quan trọng vì hầu hết các kỹ thuật xử lý sự kiện đều dựa vào những thông tin mà nó cung cấp.
Sự khác nhau giữa event.target và event.currentTarget
Đây là hai thuộc tính thường gây nhầm lẫn đối với người mới học JavaScript.
event.target là phần tử thực sự phát sinh sự kiện.
event.currentTarget là phần tử đang được gắn Event Listener.
Ví dụ:
const list = document.querySelector("#list");
list.addEventListener("click", function (event) {
console.log(event.target);
console.log(event.currentTarget);
});
Nếu người dùng nhấn vào một phần tử con bên trong #list, thì:
- event.target là phần tử con được nhấn.
- event.currentTarget luôn là phần tử #list.
Việc hiểu rõ hai thuộc tính này rất quan trọng khi làm việc với Event Delegation.
Ngăn hành động mặc định bằng preventDefault()
Nhiều phần tử HTML có sẵn hành động mặc định. Ví dụ, khi nhấn vào liên kết, trình duyệt sẽ chuyển sang trang mới; khi gửi Form, trình duyệt sẽ gửi dữ liệu lên máy chủ.
Nếu muốn JavaScript kiểm soát hoàn toàn quá trình này, có thể sử dụng preventDefault().
Ví dụ với liên kết:
const link = document.querySelector("a");
link.addEventListener("click", function (event) {
event.preventDefault();
console.log("Đã chặn chuyển trang.");
});
Ví dụ với Form:
const form = document.querySelector("form");
form.addEventListener("submit", function (event) {
event.preventDefault();
console.log("Kiểm tra dữ liệu trước khi gửi.");
});
Phương thức này thường được sử dụng khi xây dựng Form, SPA hoặc các ứng dụng có xử lý dữ liệu bằng Ajax và Fetch API.
Ngăn sự kiện lan truyền bằng stopPropagation()
Mặc định, một sự kiện có thể lan truyền từ phần tử con lên phần tử cha. Nếu không muốn điều này xảy ra, có thể sử dụng stopPropagation().
Ví dụ:
const parent = document.querySelector(".parent");
const child = document.querySelector(".child");
parent.addEventListener("click", function () {
console.log("Parent");
});
child.addEventListener("click", function (event) {
event.stopPropagation();
console.log("Child");
});
Khi nhấn vào phần tử con, chỉ thông báo Child được hiển thị vì sự kiện đã bị chặn trước khi lan truyền lên phần tử cha.
Event Bubbling là gì?
Event Bubbling (lan truyền nổi bọt) là cơ chế mặc định của trình duyệt. Sau khi sự kiện xảy ra trên phần tử con, sự kiện sẽ tiếp tục truyền lên các phần tử cha cho đến đối tượng document và window.
Ví dụ cấu trúc HTML:
<div class="parent">
<button>Click</button>
</div>
Khi người dùng nhấn vào nút, trình tự xử lý thường là:
- button.
- div.
- body.
- html.
- document.
- window.
Đây là cơ chế mặc định mà hầu hết các sự kiện của JavaScript đều sử dụng.
Event Capturing là gì?
Trái ngược với Bubbling, Event Capturing sẽ truyền sự kiện từ phần tử ngoài cùng xuống phần tử bên trong.
Để kích hoạt Capturing, tham số thứ ba của addEventListener() phải được đặt là true.
const parent = document.querySelector(".parent");
parent.addEventListener("click", function () {
console.log("Capture");
}, true);
Trong thực tế, Bubbling được sử dụng nhiều hơn Capturing, tuy nhiên việc hiểu cả hai cơ chế sẽ giúp xử lý các trường hợp phức tạp dễ dàng hơn.
Event Delegation
Event Delegation là kỹ thuật chỉ gắn một Event Listener cho phần tử cha thay vì gắn cho từng phần tử con.
Kỹ thuật này mang lại nhiều lợi ích:
- Giảm số lượng Event Listener.
- Tăng hiệu năng.
- Hoạt động với cả phần tử được thêm động.
- Dễ bảo trì mã nguồn.
Ví dụ:
const list = document.querySelector("#list");
list.addEventListener("click", function (event) {
if (event.target.tagName === "LI") {
console.log(event.target.textContent);
}
});
Dù danh sách có thêm bao nhiêu phần tử mới, chỉ cần một Event Listener duy nhất.
removeEventListener()
Khi không còn cần lắng nghe sự kiện, nên gỡ bỏ Event Listener để tránh tiêu tốn bộ nhớ không cần thiết.
Ví dụ:
function handleClick() {
console.log("Click");
}
const button = document.querySelector("#btn");
button.addEventListener("click", handleClick);
button.removeEventListener("click", handleClick);
Để gỡ bỏ thành công, phải truyền đúng hàm đã được đăng ký trước đó.
Custom Event
Ngoài các sự kiện có sẵn, JavaScript còn cho phép tạo sự kiện riêng nhằm phục vụ nhu cầu của ứng dụng.
Ví dụ tạo Custom Event:
const customEvent = new CustomEvent("loaded");
document.addEventListener("loaded", function () {
console.log("Đã nhận Custom Event.");
});
document.dispatchEvent(customEvent);
Custom Event thường xuất hiện trong các thư viện, framework hoặc các dự án lớn có nhiều module giao tiếp với nhau.
Passive Event Listener
Đối với các sự kiện như scroll hoặc touchmove, trình duyệt có thể phải chờ JavaScript xử lý xong mới tiếp tục cuộn trang.
Để cải thiện hiệu năng, có thể khai báo Event Listener ở chế độ passive.
window.addEventListener("scroll", function () {
}, {
passive: true
});
Passive Event Listener giúp việc cuộn trang mượt hơn, đặc biệt trên thiết bị di động.
Những lỗi thường gặp khi làm việc với Event
Gắn Event trước khi phần tử được tạo
Nếu JavaScript chạy trước khi HTML được tải xong, phần tử sẽ không tồn tại và việc đăng ký Event sẽ thất bại.
Giải pháp là đặt mã JavaScript sau HTML hoặc sử dụng sự kiện DOMContentLoaded.
Đăng ký quá nhiều Event Listener
Việc gắn Event cho hàng nghìn phần tử có thể làm giảm hiệu năng. Trong trường hợp này nên áp dụng Event Delegation.
Quên gỡ bỏ Event
Đối với các ứng dụng lớn hoặc ứng dụng một trang (SPA), Event Listener không còn sử dụng nên được gỡ bỏ để hạn chế rò rỉ bộ nhớ.
Lạm dụng inline Event
Việc viết JavaScript trực tiếp trong HTML khiến mã nguồn khó đọc, khó mở rộng và khó bảo trì. Nên ưu tiên sử dụng addEventListener().
Kinh nghiệm sử dụng Event hiệu quả
- Ưu tiên sử dụng addEventListener() thay cho inline Event.
- Đặt tên hàm xử lý rõ ràng thay vì lạm dụng hàm ẩn danh.
- Áp dụng Event Delegation khi xử lý danh sách lớn.
- Sử dụng preventDefault() đúng mục đích.
- Chỉ dùng stopPropagation() khi thực sự cần thiết.
- Gỡ bỏ Event Listener khi không còn sử dụng.
- Không thực hiện các tác vụ nặng trong sự kiện scroll hoặc resize.
- Tận dụng Passive Event Listener để tăng hiệu năng.
Tổng kết
Event là nền tảng của mọi ứng dụng JavaScript hiện đại. Từ những thao tác đơn giản như nhấn chuột, nhập dữ liệu cho đến các chức năng phức tạp như kéo thả, phát video hay xử lý biểu mẫu đều được xây dựng dựa trên cơ chế sự kiện.
Nắm vững cách hoạt động của Event, hiểu rõ Event Object, Event Bubbling, Event Capturing, Event Delegation cùng các phương thức như preventDefault(), stopPropagation() và removeEventListener() sẽ giúp bạn xây dựng những website có khả năng tương tác tốt, dễ mở rộng và đạt hiệu năng cao. Đây cũng là nhóm kiến thức không thể thiếu trước khi tiếp cận các framework phổ biến như React, Vue hoặc Angular.
- 0 Bình luận
Email, Điện thoại của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *