Hiểu sự kiện trong JavaScript
Trong Hiểu DOM loạt, ta đã thảo luận về cây DOM và làm thế nào để truy cập , traverse , add và remove , và sửa đổi các node và các yếu tố bằng cách sử dụng Công cụ nhà phát triển điều khiển .Mặc dù tại thời điểm này, ta có thể thực hiện hầu hết mọi thay đổi mà ta muốn đối với DOM, từ góc độ user , điều đó không hữu ích lắm vì ta chỉ kích hoạt các thay đổi theo cách thủ công. Bằng cách tìm hiểu về các sự kiện, ta sẽ hiểu cách liên kết mọi thứ lại với nhau để tạo các trang web tương tác.
Sự kiện là các hành động diễn ra trong trình duyệt mà user hoặc chính trình duyệt có thể bắt đầu. Dưới đây là một số ví dụ về các sự kiện phổ biến có thể xảy ra trên một trang web:
- Trang tải xong
- User nhấp vào một nút
- User di chuột qua menu thả xuống
- User gửi biểu mẫu
- User nhấn một phím trên bàn phím của họ
Bằng cách mã hóa các phản hồi JavaScript thực thi theo một sự kiện, nhà phát triển có thể hiển thị thông báo cho user , xác thực dữ liệu, phản ứng với một lần nhấp vào nút và nhiều hành động khác.
Trong bài viết này, ta sẽ xem xét trình xử lý sự kiện, trình xử lý sự kiện và đối tượng sự kiện. Ta cũng sẽ xem xét ba cách khác nhau để viết mã để xử lý các sự kiện và một số sự kiện phổ biến nhất. Bằng cách tìm hiểu về các sự kiện, bạn có thể tạo trải nghiệm web tương tác hơn cho user cuối.
Trình xử lý sự kiện và Trình xử lý sự kiện
Khi user nhấp vào một nút hoặc nhấn một phím, một sự kiện sẽ được kích hoạt. Chúng được gọi là sự kiện nhấp chuột hoặc sự kiện nhấn phím, tương ứng.
Trình xử lý sự kiện là một hàm JavaScript chạy khi một sự kiện kích hoạt.
Trình nghe sự kiện gắn một giao diện đáp ứng vào một phần tử, cho phép phần tử cụ thể đó đợi và "lắng nghe" sự kiện đã cho để kích hoạt.
Có ba cách để gán sự kiện cho các phần tử:
- Trình xử lý sự kiện nội tuyến
- Thuộc tính của trình xử lý sự kiện
- Người nghe sự kiện
Ta sẽ xem xét tất cả ba phương pháp đảm bảo rằng bạn đã quen thuộc với từng cách một sự kiện có thể được kích hoạt, sau đó thảo luận về ưu và nhược điểm của từng phương pháp.
Thuộc tính trình xử lý sự kiện nội tuyến
Để bắt đầu tìm hiểu về trình xử lý sự kiện, trước tiên ta sẽ xem xét trình xử lý sự kiện nội tuyến . Hãy bắt đầu với một ví dụ rất cơ bản bao gồm một phần tử button
và một phần tử p
. Ta muốn user nhấp vào button
để thay đổi nội dung văn bản của p
.
Hãy bắt đầu với một trang HTML với một nút trong nội dung. Ta sẽ tham chiếu đến một file JavaScript mà ta sẽ thêm mã vào sau một chút.
<!DOCTYPE html> <html lang="en-US"> <head> <title>Events</title> </head> <body> <!-- Add button --> <button>Click me</button> <p>Try to change me.</p> </body> <!-- Reference JavaScript file --> <script src="js/events.js"></script> </html>
Trực tiếp trên button
, ta sẽ thêm một thuộc tính gọi là onclick
. Giá trị thuộc tính sẽ là một hàm mà ta tạo ra được gọi là changeText()
.
<!DOCTYPE html> <html lang="en-US"> <head> <title>Events</title> </head> <body> <button onclick="changeText()">Click me</button> <p>Try to change me.</p> </body> <script src="js/events.js"></script> </html>
Hãy tạo file sự events.js
của ta , ta đã đặt trong folder js/
ở đây. Trong nó, ta sẽ tạo hàm changeText()
, hàm này sẽ sửa đổi textContent
của phần tử p
.
// Function to modify the text content of the paragraph const changeText = () => { const p = document.querySelector('p'); p.textContent = "I changed because of an inline event handler."; }
Khi bạn tải lần đầu tiên events.html
, bạn sẽ thấy một trang giống như sau:
Tuy nhiên, khi bạn hoặc user khác nhấp vào nút, văn bản của thẻ p
sẽ thay đổi từ Try to change me.
thành I changed because of an inline event handler.
:
Trình xử lý sự kiện nội tuyến là một cách đơn giản để bắt đầu hiểu các sự kiện, nhưng chúng thường không được sử dụng ngoài mục đích thử nghiệm và giáo dục.
Bạn có thể so sánh các trình xử lý sự kiện nội tuyến với các kiểu CSS nội tuyến trên một phần tử HTML. Thực tế hơn nhiều nếu duy trì một biểu định kiểu riêng biệt của các lớp hơn là tạo các kiểu nội tuyến trên mọi phần tử, cũng như việc duy trì JavaScript được xử lý hoàn toàn thông qua một file kịch bản riêng biệt sẽ khả thi hơn là thêm trình xử lý vào mọi phần tử.
Thuộc tính xử lý sự kiện
Bước tiếp theo từ trình xử lý sự kiện nội tuyến là thuộc tính trình xử lý sự kiện . Điều này hoạt động rất giống với trình xử lý nội tuyến, ngoại trừ ta đang đặt thuộc tính của một phần tử trong JavaScript thay vì thuộc tính trong HTML.
Việc cài đặt sẽ giống nhau ở đây, ngoại trừ việc ta không còn đưa onclick="changeText()"
vào đánh dấu:
... <body> <button>Click me</button> <p>I will change.</p> </body> ...
Chức năng của ta sẽ vẫn tương tự, ngoại trừ bây giờ ta cần truy cập vào phần tử button
trong JavaScript. Ta có thể chỉ cần truy cập onclick
giống như ta truy cập style
hoặc id
hoặc bất kỳ thuộc tính phần tử nào khác, sau đó gán tham chiếu hàm.
// Function to modify the text content of the paragraph const changeText = () => { const p = document.querySelector('p'); p.textContent = "I changed because of an event handler property."; } // Add event handler as a property of the button element const button = document.querySelector('button'); button.onclick = changeText;
Lưu ý: Các trình xử lý sự kiện không tuân theo quy ước camelCase mà hầu hết các mã JavaScript đều tuân theo. Lưu ý mã là onclick
, không phải onClick
.
Khi bạn tải trang lần đầu tiên, trình duyệt sẽ hiển thị như sau:
Bây giờ khi bạn nhấp vào nút, nó sẽ có hiệu ứng tương tự như trước:
Lưu ý khi chuyển một tham chiếu hàm đến thuộc tính onclick
, ta không bao gồm dấu ngoặc đơn, vì ta không gọi hàm trong thời điểm đó, mà chỉ chuyển một tham chiếu đến nó.
Thuộc tính trình xử lý sự kiện dễ bảo trì hơn một chút so với trình xử lý nội tuyến, nhưng nó vẫn gặp phải một số trở ngại tương tự. Ví dụ: cố gắng đặt nhiều thuộc tính onclick
riêng biệt sẽ khiến tất cả trừ thuộc tính cuối cùng bị overrides , như được minh họa bên dưới.
const p = document.querySelector('p'); const button = document.querySelector('button'); const changeText = () => { p.textContent = "Will I change?"; } const alertText = () => { alert('Will I alert?'); } // Events can be overwritten button.onclick = changeText; button.onclick = alertText;
Trong ví dụ trên, lần nhấp vào button
sẽ chỉ hiển thị một cảnh báo và không thay đổi văn bản p
, vì mã alert()
là mã cuối cùng được thêm vào thuộc tính.
Với sự hiểu biết về cả trình xử lý sự kiện nội tuyến và thuộc tính xử lý sự kiện, hãy chuyển sang trình xử lý sự kiện.
Người nghe sự kiện
Bổ sung mới nhất cho trình xử lý sự kiện JavaScript là trình xử lý sự kiện. Người nghe sự kiện theo dõi sự kiện trên một phần tử. Thay vì gán sự kiện trực tiếp cho một thuộc tính trên phần tử, ta sẽ sử dụng phương thức addEventListener()
để lắng nghe sự kiện.
addEventListener()
nhận hai tham số bắt buộc - sự kiện mà nó sẽ lắng nghe và hàm gọi lại của trình lắng nghe.
HTML cho trình xử lý sự kiện của ta sẽ giống như ví dụ trước.
... <button>Click me</button> <p>I will change.</p> ...
Ta sẽ vẫn sử dụng cùng một changeText()
như trước đây. Ta sẽ đính kèm phương thức addEventListener()
vào nút.
// Function to modify the text content of the paragraph const changeText = () => { const p = document.querySelector('p'); p.textContent = "I changed because of an event listener."; } // Listen for click event const button = document.querySelector('button'); button.addEventListener('click', changeText);
Lưu ý với hai phương pháp đầu tiên, một sự kiện nhấp chuột được gọi là onclick
, nhưng với trình xử lý sự kiện, nó được gọi là click
. Mọi người nghe sự kiện đều bỏ on
từ này. Trong phần tiếp theo, ta sẽ xem xét thêm các ví dụ về các loại sự kiện khác.
Khi bạn reload trang bằng mã JavaScript ở trên, bạn sẽ nhận được kết quả sau:
Thoạt nhìn, bộ xử lý sự kiện có vẻ rất giống với các thuộc tính của trình xử lý sự kiện, nhưng chúng có một vài ưu điểm. Ta có thể đặt nhiều trình nghe sự kiện trên cùng một phần tử, như được minh họa trong ví dụ bên dưới.
const p = document.querySelector('p'); const button = document.querySelector('button'); const changeText = () => { p.textContent = "Will I change?"; } const alertText = () => { alert('Will I alert?'); } // Multiple listeners can be added to the same event and element button.addEventListener('click', changeText); button.addEventListener('click', alertText);
Trong ví dụ này, cả hai sự kiện sẽ kích hoạt, cung cấp cho user cả cảnh báo và văn bản đã sửa đổi sau khi nhấp ra khỏi cảnh báo.
Thông thường, các hàm ẩn danh sẽ được sử dụng thay vì một tham chiếu hàm trên trình nghe sự kiện. Các hàm ẩn danh là các hàm không được đặt tên.
// An anonymous function on an event listener button.addEventListener('click', () => { p.textContent = "Will I change?"; });
Cũng có thể sử dụng hàm removeEventListener()
để xóa một hoặc tất cả các sự kiện khỏi một phần tử.
// Remove alert function from button element button.removeEventListener('click', alertText);
Hơn nữa, bạn có thể sử dụng addEventListener()
trên đối tượng document
và window
.
Trình xử lý sự kiện hiện là cách phổ biến và ưa thích nhất để xử lý các sự kiện trong JavaScript.
Sự kiện chung
Ta đã tìm hiểu về trình xử lý sự kiện nội tuyến, thuộc tính trình xử lý sự kiện và trình xử lý sự kiện bằng cách sử dụng sự kiện nhấp chuột, nhưng có nhiều sự kiện khác trong JavaScript. Ta sẽ điểm qua một vài sự kiện phổ biến nhất bên dưới.
Sự kiện chuột
Sự kiện chuột là một trong những sự kiện được sử dụng thường xuyên nhất. Chúng đề cập đến các sự kiện liên quan đến việc nhấp vào các node trên chuột hoặc di chuột và di chuyển con trỏ chuột. Các sự kiện này cũng tương ứng với hành động tương đương trên thiết bị cảm ứng.
Biến cố | Sự miêu tả |
---|---|
click | Kích hoạt khi nhấn và thả chuột trên một phần tử |
dblclick | Kích hoạt khi một phần tử được nhấp hai lần |
mouseenter | Kích hoạt khi một con trỏ đi vào một phần tử |
mouseleave | Kích hoạt khi con trỏ rời khỏi một phần tử |
mousemove | Kích hoạt mỗi khi con trỏ di chuyển bên trong một phần tử |
Một click
là một sự kiện hợp chất bao gồm kết hợp mousedown
và mouseup
sự kiện, mà lửa khi nút chuột được nhấn xuống hoặc nâng lên tương ứng.
Sử dụng mouseenter
và mouseleave
song song tái tạo một hiệu ứng di chuột kéo dài càng lâu càng một con trỏ chuột trên phần tử.
Sự kiện biểu mẫu
Sự kiện biểu mẫu là các hành động liên quan đến biểu mẫu, chẳng hạn như các yếu tố input
đang được chọn hoặc không được chọn và biểu mẫu đang được gửi.
Biến cố | Sự miêu tả |
---|---|
submit | Kích hoạt khi biểu mẫu được gửi |
focus | Kích hoạt khi một phần tử (chẳng hạn như đầu vào) nhận được tiêu điểm |
blur | Cháy khi một phần tử mất tiêu điểm |
Lấy nét khi một phần tử được chọn, ví dụ, thông qua một cú nhấp chuột hoặc chuyển đến phần tử đó qua TAB
.
JavaScript thường được sử dụng để gửi biểu mẫu và gửi các giá trị đến một ngôn ngữ backend . Ưu điểm của việc sử dụng JavaScript để gửi biểu mẫu là nó không yêu cầu reload trang để gửi biểu mẫu và JavaScript được dùng để xác thực các trường nhập bắt buộc.
Sự kiện bàn phím
Các sự kiện bàn phím được sử dụng để xử lý các thao tác trên bàn phím, chẳng hạn như nhấn một phím, nhấc một phím và giữ một phím.
Biến cố | Sự miêu tả |
---|---|
keydown | Kích hoạt một lần khi nhấn một phím |
keyup | Bắn một lần khi khóa được phát hành |
keypress | Bắn liên tục khi nhấn một phím |
Mặc dù họ trông giống như, keydown
và keypress
kiện không truy cập tất cả các phím cùng chính xác. Trong khi keydown
sẽ xác nhận mọi phím được nhấn, thao tác keypress
sẽ bỏ qua các phím không tạo ra ký tự, chẳng hạn như SHIFT
, ALT
hoặc DELETE
.
Sự kiện bàn phím có các thuộc tính cụ thể để truy cập các phím riêng lẻ.
Nếu một tham số, được gọi là đối tượng event
, được chuyển đến trình xử lý sự kiện, ta có thể truy cập thêm thông tin về hành động đã diễn ra. Ba thuộc tính liên quan đến đối tượng bàn phím bao gồm keyCode
, key
, và code
.
Ví dụ: nếu user nhấn phím chữ a
trên bàn phím của họ, các thuộc tính sau liên quan đến phím đó sẽ hiển thị:
Bất động sản | Sự miêu tả | Thí dụ |
---|---|---|
keyCode | Một số liên quan đến key | 65 |
key | Đại diện cho tên nhân vật | a |
code | Đại diện cho phím vật lý đang được nhấn | KeyA |
Để chỉ ra cách thu thập thông tin đó qua Control panel JavaScript, ta có thể viết các dòng mã sau.
// Test the keyCode, key, and code properties document.addEventListener('keydown', event => { console.log('key: ' + event.keyCode); console.log('key: ' + event.key); console.log('code: ' + event.code); });
Khi ta nhấn ENTER
trên Control panel , bây giờ ta có thể nhấn một phím trên bàn phím, trong ví dụ này, ta sẽ nhấn a
.
OutputkeyCode: 65 key: a code: KeyA
Thuộc tính keyCode
là một số liên quan đến phím đã được nhấn. Thuộc tính key
là tên của ký tự, có thể thay đổi - ví dụ: nhấn a
với SHIFT
sẽ dẫn đến key
là A
Thuộc tính code
đại diện cho phím vật lý trên bàn phím.
Lưu ý keyCode
đang trong quá trình không được dùng nữa và bạn nên sử dụng code
trong các dự án mới.
Để tìm hiểu thêm, bạn có thể xem danh sách đầy đủ các sự kiện trên Mạng nhà phát triển Mozilla .
Đối tượng sự kiện
Đối tượng Event
bao gồm các thuộc tính và phương thức mà tất cả các sự kiện đều có thể truy cập. Ngoài đối tượng Event
chung, mỗi loại sự kiện có các phần mở rộng riêng, chẳng hạn như KeyboardEvent
và MouseEvent
.
Đối tượng Event
được chuyển qua một hàm lắng nghe như một tham số. Nó thường được viết là event
hoặc e
. Ta có thể truy cập thuộc tính code
của sự kiện keydown
để tái tạo các điều khiển bàn phím của trò chơi PC.
Để dùng thử, hãy tạo một file HTML cơ bản với các <p>
và tải nó vào trình duyệt.
<!DOCTYPE html> <html lang="en-US"> <head> <title>Events</title> </head> <body> <p></p> </body> </html>
Sau đó, nhập mã JavaScript sau vào Control panel dành cho nhà phát triển của trình duyệt của bạn.
// Pass an event through to a listener document.addEventListener('keydown', event => { var element = document.querySelector('p'); // Set variables for keydown codes var a = 'KeyA'; var s = 'KeyS'; var d = 'KeyD'; var w = 'KeyW'; // Set a direction for each code switch (event.code) { case a: element.textContent = 'Left'; break; case s: element.textContent = 'Down'; break; case d: element.textContent = 'Right'; break; case w: element.textContent = 'Up'; break; } });
Khi bạn nhấn một trong các phím - a
, s
, d
hoặc w
- bạn sẽ thấy kết quả tương tự như sau:
Từ đây, bạn có thể tiếp tục phát triển cách trình duyệt sẽ phản hồi và user nhấn các phím đó, đồng thời có thể tạo một trang web năng động hơn.
Tiếp theo, ta sẽ xem xét một trong những thuộc tính sự kiện được sử dụng thường xuyên nhất: thuộc tính target
. Trong ví dụ sau, ta có ba phần tử div
bên trong một section
.
<!DOCTYPE html> <html lang="en-US"> <head> <title>Events</title> </head> <body> <section> <div id="one">One</div> <div id="two">Two</div> <div id="three">Three</div> </section> </body> </html>
Sử dụng event.target
với JavaScript trong Control panel dành cho nhà phát triển của trình duyệt, ta có thể đặt một trình xử lý sự kiện trên section
tử section
bên ngoài và nhận section
tử được lồng sâu nhất.
const section = document.querySelector('section'); // Print the selected target section.addEventListener('click', event => { console.log(event.target); });
Nhấp vào bất kỳ một trong những phần tử đó sẽ trả về kết quả của phần tử cụ thể có liên quan cho Control panel bằng cách sử dụng event.target
. Điều này cực kỳ hữu ích, vì nó cho phép bạn chỉ đặt một bộ xử lý sự kiện được dùng để truy cập nhiều phần tử lồng nhau.
Với đối tượng Event
, ta có thể cài đặt phản hồi liên quan đến tất cả các sự kiện, bao gồm các sự kiện chung và các phần mở rộng cụ thể hơn.
Kết luận
Sự kiện là những hành động diễn ra trên một trang web, chẳng hạn như nhấp, di chuột, gửi biểu mẫu, tải trang hoặc nhấn một phím trên bàn phím. JavaScript trở nên thực sự tương tác và năng động khi ta có thể làm cho các trang web phản hồi lại các hành động mà user đã thực hiện.
Trong hướng dẫn này, ta đã tìm hiểu sự kiện là gì, ví dụ về các sự kiện phổ biến, sự khác biệt giữa trình xử lý sự kiện và trình xử lý sự kiện cũng như cách truy cập đối tượng Event
. Sử dụng kiến thức này, bạn có thể bắt đầu tạo các trang web và ứng dụng động.
Các tin liên quan
Lập lịch tác vụ trong JavaScript Sử dụng setTimeout & setInterval2018-06-12
Hiểu các lớp trong JavaScript
2018-05-04
Truy cập API Rails trong ứng dụng khách JavaScript bằng Rails Ranger
2018-03-15
Hiểu các biến, phạm vi và lưu trữ trong JavaScript
2018-02-20
Tìm hiểu Nguyên mẫu và Kế thừa trong JavaScript
2018-01-12
Khám phá đối tượng ngày JavaScript
2017-12-06
chuỗi con so với chuỗi con trong JavaScript
2017-11-06
Hiểu Ngày và Giờ trong JavaScript
2017-10-19
Cách xác định các hàm trong JavaScript
2017-10-09
Vòng lặp Đối với, Đối với ... Trong vòng lặp và Đối với ... Trong Vòng lặp trong JavaScript
2017-10-02