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.
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.
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.
Giả sử chúng ta nhấn phím f, kết quả xuất ra console là:
fKeyF
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.
<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> là <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:
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>
Để 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ụ: