Có hai cách để thêm sự kiện vào một element, cách đầu tiên là thông qua attribute của element. Cách thứ hai là sử dụng JS: lấy ra element node cần thêm sự kiện và gọi sử dụng thuộc tính sự kiện của element node đó.

Các thuộc tính sự kiện thuộc lớp đối tượng Element, là một phần của Browser API. Do đó, các lời gọi hàm của các sự kiện này sẽ được lưu trên stack của Web API và chỉ được thực thi khi stack của JS trống1.

Common Events

onclick

In HTML

Giả sử có đoạn code dưới đây:

<button type="submit" class="box" onclick='console.log("Hello Wibu")'>Click me</button>

Khi click chuột vào nút “Click me” thì console sẽ xuất ra dòng chữ “Hello Wibu” ở trên console.

Info

Code ở trong attribute của element có thể dùng từ khóa this, chính là bản thân element.

In JavaScript

Gọi ra thuộc tính onclick của element node và gán bằng một hàm.

const boxElement = document.querySelector('#box')
 
divElement.onclick = function(event) {
	console.log(event) // PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
}

Khi sự kiện click chuột được thực thi thì JS sẽ gọi hàm được gán cho onclick và truyền vào đối số event, là một đối tượng đại diện cho sự kiện đã thực thi.

Info

Đối tượng event có một thuộc tính là event.target, chính là bản thân element.

const boxElement = document.querySelector('#box')
 
divElement.onclick = function(event) {
    console.log(event.target) // <button type="submit" class="box">Click me</button>
}

Muốn hủy bỏ lắng nghe thì chỉ cần gán thuộc tính onclick bằng một hàm rỗng.

onchange

Thuộc tính onchange bắt sự kiện khi có sự thay đổi về nội dung của thẻ <input> hoặc <select>. Sự kiện kết thúc khi người dùng không còn focus vào khung nhập dữ liệu (chẳng hạn click vào ra bên ngoài hoặc click vào một nút nào đó khác).

Info

Để lấy giá trị nhập vào thông qua JS thì gọi thuộc tính target.value của đối tượng event.

Ví dụ ta có thẻ <input> như sau

<input type="text" placeholder="Enter here" class="input"/>

In ra giá trị mà người dùng đã nhập vào ô của thẻ <input>

const inputElement = document.querySelector('input')
 
inputElement.onchange = function(event) {
	console.log("User input: ", event.target.value)
}

Tip

Nếu muốn lấy từng ký tự thì dùng oninput thay vì onchange.

onkeyup/onkeydown

Thuộc tính onkeyup bắt sự kiện thả phím, onkeydown bắt sự kiện nhấn phím.

Để lấy giá trị của phím được nhấn thì dùng thuộc tính key hoặc code thuộc đối tượng event.

Ví dụ, đoạn code sau sẽ in ra tất cả các phím mà người dùng đã và đang bấm:

const bodyElement = document.querySelector('body')
 
bodyElement.onkeydown = function(event) {
	console.log(event.key)
	console.log(event.code)
}

Giả sử chúng ta nhấn phím f, kết quả xuất ra console là:

f
KeyF

oninput Vs onchange

Hai sự kiện này có một chút khác biệt như sau:

  • oninput: xảy ra ngay lập tức khi giá trị của một thẻ HTML bị thay đổi.
  • onchange: xảy ra lúc element mất focus (như khi ta click vào thẻ <input> rồi click ra ngoài), sau khi nội dung của element bị thay đổi.
  • Ngoài ra, onchange còn có thể hoạt động trên thẻ <select>, trong khi oninput thì không.

Instance Methods

preventDefault

Phương thức preventDefault thuộc về lớp đối tượng Event dùng để ngăn chặn sự kiện thực hiện một hành vi mặc định nào đó. Các hành vi mặc định là các hành vi mà các thẻ HTML sẽ thực thi khi người dùng thao tác.

Chẳng hạn khi có sự kiện click vào thẻ <a> (chứa link), hành vi mặc định (chuyển trang) của thẻ này sẽ bị ngăn chặn.

<a href="https://www.google.com/" class="google">Google it!</a>
const anchorElement = document.querySelector('.google')
 
anchorElement.onclick = function(event) {
	event.preventDefault()
}

stopPropagation

Xét đoạn code:

<div id="box" class="box" onclick="console.log(this.innerText)">
	<span> Click me </span>
</div>

Khi ta nhấn vào dòng chữ “Click me” thì nó sẽ xét xem thẻ <span> có thuộc tính sự kiện hay không. Nếu không có thì nó sẽ “nổi bọt” lên element cha của nó. Element cha của thẻ <span><div>, sự kiện được bắt và console sẽ in chuỗi “Click me”:

Nếu như bản thân thẻ <span> cũng có thuộc tính sự kiện, thì sẽ có hai lần in ra chuỗi “Click me”.

<div id="box" class="box" onclick="console.log(this.innerText)">
	<span onclick="console.log(this.innerText)"> Click me </span>
</div>

Phương thức stopPropagation thuộc về lớp đối tượng Event dùng để ngăn chặn sự kiện “nổi bọt” ra các element bên ngoài.

Ta có thể gọi phương thức này trong các hàm sự kiện, chẳng hạn như hàm onclick:

const boxDivElement = document.querySelector("#box")
 
boxDivElement.onclick = function(event) {
	event.stopPropagation()
}

Attention

Lưu ý, ta cần bắt sự kiện cho tag <div> thay vì tag <span> thì mới dùng được stopPropagation.

Event Listeners

Ngoài dùng các thuộc tính sự kiện, ta cũng có thể dùng các hàm event listener để lắng nghe và xử lý sự kiện.

Để thêm một event listener, ta sử dụng phương thức addEventListener thuộc class EventTarget (là lớp cha của Element). Phương thức này có cú pháp:

element.addEventListener("event", function () {
	// Task goes here
})

Đối số đầu tiên là tên sự kiện không có chữ “on”, đối số thứ hai là callback được gọi khi sự kiện xảy ra. Với cách này, ta có thể lắng nghe sự kiện nhiều lần.

<div>
	<span class="event-listener">Click me senpai</span>
</div>
const spanElement = document.querySelector('.event-listener')
 
function task1() {
	console.log("This is task 1")
}
 
spanElement.addEventListener("click", task1)

Để hủy bỏ lắng nghe thì ta cần sử dụng phương thức removeEventListener theo một cách tương tự như khi tạo event listener. Tuy nhiên, callback nên được tách ra để có thể truyền vào phương thức này:

spanElement.removeEventListener("click", task1)

Sử dụng DOM event hay event listener?

  • Khi chỉ muốn lắng nghe sự kiện và không muốn hủy lắng nghe thì sử dụng DOM Event.

  • Còn nếu muốn hủy lắng nghe trong trường hợp cụ thể thì sử dụng event listener.

  • Hoặc nếu như có quá nhiều tác vụ cần được thực thi cho duy nhất một loại sự kiện thì cũng nên dùng event listener. Ví dụ:

    element.addEventListener("click", task1)
    element.addEventListener("click", task2)
    element.addEventListener("click", task3)
table tags as Tags, file.cday as Created
from [[JS Event]]
sort file.ctime asc

Footnotes

  1. Tham khảo thêm: Event loop.