1. DOM EventListener trong JavaScript là gì?

Dom Event Listener – trình lắng nghe sự kiện cũng giống như Event handlers , ngoại trừ việc ta có thể chỉ định bao nhiêu trình xử lý sự kiện tùy thích cho một sự kiện cụ thể trên phần tử cụ thể.

Ví dụ: Giả sử rằng tạo hai hàm và bạn cố gắng thực thi cả hai hàm khi click vào nút bằng cách sử dụng trình xử lý sự kiện onclick, như được hiển thị trong ví dụ sau

<button id="myBtn">Click vào đây</button>
<script>
// Tạo ra các hàm tùy chỉnh
function hamDauTien() {
    alert("Hàm đầu tiên thực thi thành công!");
}
 
function hamThuHai() {
    alert("Hàm thứ hai thực thi thành công!");
}
 
// Nhắm đến phần tử myBtn
var btn = document.getElementById("myBtn");
 
// Gán Event Listener cho phần tử button
btn.addEventListener("click", hamDauTien);
btn.addEventListener("click", hamThuHai);
</script>

Chạy ví dụ trên và click vào phần tử button, chỉ hamThuHai() được thực thi, vì việc gán trình xử lý sự kiện thứ hai sẽ ghi đè trình xử lý sự kiện đầu tiên. Đây là thiếu sót của Event Handlers . Ta chỉ có thể chỉ định một trình xử lý sự kiện cho một sự kiện cụ thể trên một phần tử cụ thể, tức là một hàm duy nhất cho mỗi sự kiện trên mỗi phần tử. Để giải quyết vấn đề này thì EventListener đã ra đời.

Bất kỳ phần tử HTML nào cũng có thể có nhiều Event Listener , do đó ta có thể gán nhiều hàm cho cùng một sự kiện cho cùng một phần tử.

<button id="myBtn">Click vào đây</button>
 
<script>
// Tạo ra các hàm tùy chỉnh
function hamDauTien() {
    alert("Hàm đầu tiên thực thi thành công!");
}
 
function hamThuHai() {
    alert("Hàm thứ hai thực thi thành công!");
}
 
// Nhắm đến phần tử myBtn
var btn = document.getElementById("myBtn");
 
// Gán Event Listener cho phần tử button
btn.addEventListener("click", hamDauTien);
btn.addEventListener("click", hamThuHai);
</script>

Bây giờ, nếu chạy ví dụ trên và click vào nút đó, cả hai hàm sẽ được thực thi chứ không bị ghi đè nữa.

2. Hàm addEventListener() trong JavaScript

AddEventListener là một phương thức được tích hợp sẵn vào các đối tượng HTML thông qua cơ chế DOM. Khi sử dụng addEventListener thì ta có thể bổ sung rất nhiều hành động vào sự kiện tại nhiều thời điểm khác nhau.

Cú pháp: element.addEventListener('eventName',functionName, useCapture);

Trong đó:

  • element : là các đối tượng HTML (được gọi bằng các phương thức getElement…).
  • eventName : là tên các sự kiện (bỏ chữ ‘on’) như click , mouseover ,…
  • functionName : là tên hàm mà các bạn muốn gọi khi xảy ra sự kiện.
  • useCapture : Giá trị boolean (mặc định là false) là tham số được sử dụng để xử lý sự kiện lan truyền.

Ví dụ:

<p>Ví dụ này sử dụng phương thức addEventListener () để đính kèm một sự kiện nhấp chuột vào một nút.</p>

<button id="myBtn">Bấm vào đây</button>

<p id="demo"></p>

<script>
document.getElementById("myBtn").addEventListener("click", displayDate);

function displayDate() {
  document.getElementById("demo").innerHTML = Date();
}
</script>

3. Thêm các kiểu Event Listener khác nhau cho phần tử

Giống như Event Handler , ta có thể chỉ định các Event Listener khác nhau cho các loại sự kiện khác nhau trên cùng một phần tử.

Ví dụ: gán các hàm khác nhau cho các sự kiện ‘click’, ‘mouseover’ và ‘mouseout’ của một phần tử button .

<button id="myBtn">Click vào đây</button>
<script>
   // Nhắm đến phần tử myBtn
var btn = document.getElementById("myBtn");
 
// Tạo ra các hàm tùy chỉnh
function xinChao() {
    alert("Xin chào, bạn đang làm gì thế?");
}
 
function thietLapMauHover() {
    btn.style.background = "yellow";
}
 
function thietLapMauBinhThuong() {
    btn.style.background = "";
}
 
// Gán event listeners cho myBtn
btn.addEventListener("click", xinChao);
btn.addEventListener("mouseover", thietLapMauHover);
btn.addEventListener("mouseout", thietLapMauBinhThuong); </script>

4. Thêm Event Listeners vào đối tượng Window

Phương thức addEventListener() cho phép ta thêm trình xử lý sự kiện vào bất kỳ phần tử DOM HTML nào. Cho đó là Window object , Document object hay bất kỳ đối tượng nào khác hỗ trợ sự kiện. Đối tượng window ta có thể ví nó như cửa sổ trình duyệt browser nên nó cũng có một số sự kiện riêng, điển hình là sự kiện resize browser .

Ví dụ: Thêm trình xử lý sự kiện sẽ kích hoạt khi người dùng thay đổi kích thước cửa sổ

<p>Ví dụ này sử dụng phương thức addEventListener () trên đối tượng window.</p>

<p>Hãy thử thay đổi kích thước cửa sổ trình duyệt này để kích hoạt trình xử lý sự kiện "resize"(thay đổi kích thước).</p>

<p id="demo"></p>

<script>
window.addEventListener("resize", function(){
  document.getElementById("demo").innerHTML = Math.random();
});
</script>

5. Xóa Event Listeners trong JavaScript

Ta có thể sử dụng phương thức removeEventListener() để xóa một Event Listener đã được đính kèm trước đó với phương thức addEventListener() .

Cú pháp: element.removeEventListener("eventName", FunctionName);

Ví dụ:

<div id="myDIV">
  <p>Phần tử div này có một trình xử lý sự kiện onmousemove hiển thị một số ngẫu nhiên mỗi khi bạn di chuyển chuột vào bên trong trường màu cam này.</p>
  <p>Nhấp vào nút để loại bỏ trình xử lý sự kiện của div.</p>
  <button onclick="removeHandler()" id="myBtn">Remove</button>
</div>

<p id="demo"></p>

<script>
document.getElementById("myDIV").addEventListener("mousemove", myFunction);

function myFunction() {
  document.getElementById("demo").innerHTML = Math.random();
}

function removeHandler() {
  document.getElementById("myDIV").removeEventListener("mousemove", myFunction);
}
</script>

Chú ý

Hàm addEventListener()removeEventListener() không hoạt động trên phiên bản IE8 trở về trước, ta có thể dùng attachEvent()detachEvent() để thay thế

element.attachEvent("EventName", funciton);
element.detachEvent("EventName", funciton);

6. Event Bubbling và Event Capturing trong JavaScript

Có 2 cách để lan truyền sự kiện trong HTML Dom đó là Event Bubbling – sự kiện sủi bọt và Event Capturing – chụp sự kiện. Sự lan truyền sự kiện là một cách xác định thứ tự phần tử khi một sự kiện xảy ra. Nếu ta có phần tử <p> bên trong phần tử <div> và người dùng nhấp vào phần tử <p> , thì sự kiện “nhấp chuột” của phần tử nào sẽ được xử lý đầu tiên?

Với bubbling sự kiện của phần tử bên trong nhất được xử lý trước rồi đến phần bên ngoài: sự kiện nhấp chuột của phần tử <p> được xử lý đầu tiên, sau đó là sự kiện nhấp chuột của phần tử <div> .

Với capturing sự kiện của phần tử bên ngoài nhất được xử lý trước và sau đó sự kiện nhấp chuột của phần tử bên trong: <div> sẽ được xử lý đầu tiên, sau đó là sự kiện nhấp chuột của phần tử <p> .

Với phương thức addEventListener() , ta có thể chỉ định kiểu truyền bằng cách sử dụng tham số “useCapture” như cú pháp ở phần trên:

element.addEventListener('eventName',functionName, useCapture);

Ví dụ:

<!DOCTYPE html>
<html>
<head>
<style>
#myDiv1, #myDiv2 {
  background-color: coral;
  padding: 50px;
}

#myP1, #myP2 {
  background-color: white; 
  font-size: 20px;
  border: 1px solid;
  padding: 20px;
}
</style>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body>

<h2>JavaScript addEventListener()</h2>

<div id="myDiv1">
  <h2>Bubbling:</h2>
  <p id="myP1">Bấm vào đây!</p>
</div><br>

<div id="myDiv2">
  <h2>Capturing:</h2>
  <p id="myP2">Bấm vào đây!</p>
</div>

<script>
document.getElementById("myP1").addEventListener("click", function() {
  alert("Bạn đã nhấp vào phần tử màu trắng!");
}, false);

document.getElementById("myDiv1").addEventListener("click", function() {
  alert("Bạn đã nhấp vào phần tử màu cam!");
}, false);

document.getElementById("myP2").addEventListener("click", function() {
  alert("Bạn đã nhấp vào phần tử màu trắng!");
}, true);

document.getElementById("myDiv2").addEventListener("click", function() {
  alert("Bạn đã nhấp vào phần tử màu cam!");
}, true);
</script>

</body>
</html>