Tìm hiểu về DOM - Document Object Model (p7-Hiểu events trong JavaScript)

  • 26/11/2018
  • Bởi
  • trong

Giới thiệu

Trong phần Hiểu chuỗi DOM, chúng ta đã thảo luận về cây DOM và cách truy cập, duyệt, thêm và loại bỏ, và sửa đổi các nút và các phần tử bằng cách sử dụng Developer Tools Console. Mặc dù tại thời điểm này, chúng tôi giờ đây có thể thực hiện hầu hết mọi thay đổi mà chúng tôi muốn với DOM, từ góc độ người dùng, điều này không hữu ích vì chúng tôi 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, chúng tôi sẽ hiểu cách kết hợp mọi thứ lại với nhau để tạo ra các trang web tương tác.

Events là các hành động diễn ra trong trình duyệt có thể được khởi tạo bởi chính người dùng hoặc chính trình duyệt đó. 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 trang web:

  • Trang kết thúc tải
  • Người dùng nhấp vào nút
  • Người dùng di chuột qua menu thả xuống
  • Người dùng gửi biểu mẫu
  • Người dùng 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 khi một event, các nhà phát triển có thể hiển thị thông báo cho người dùng, xác thực dữ liệu, phản ứng với một lần nhấp nút và nhiều hành động khác. Trong bài viết này, chúng ta sẽ xem xét các trình xử lý event, trình lắng nghe event và các đối tượng event. Chúng tôi cũng sẽ đi qua ba cách khác nhau để viết mã để xử lý các event và một số eventn phổ biến nhất. Bằng cách tìm hiểu về các event, bạn sẽ có thể tạo trải nghiệm web tương tác hơn cho người dùng cuối.

Event Handlers và Event Listeners

Khi người dùng 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. Đây được gọi là sự kiện nhấp chuột hoặc sự kiện nhấn phím, tương ứng. Event handler là một hàm JavaScript chạy khi một sự kiện kích hoạt. Event listener gắn một giao diện đáp ứng vào một phần tử, cho phép yếu tố cụ thể đó chờ và "nghe" cho sự kiện đã cho kích hoạt. Có ba cách để gán các sự kiện cho các phần tử:
  • Event handlers nội dòng
  • Thuộc tính Event handler
  • Event listeners

Chúng tôi sẽ đi qua tất cả ba phương pháp để đảm bảo rằng bạn đã quen thuộc với mỗi 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 Event Handler nội tuyến

Để bắt đầu tìm hiểu về các trình xử lý sự kiện, trước tiên chúng ta sẽ xem xét trình event handler trên dòng. Hãy bắt đầu với một ví dụ rất cơ bản bao gồm một phần tử nút và một phần tử p. Chúng tôi muốn người dùng nhấp vào nút để 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 cơ thể. Chúng tôi sẽ giới thiệu một tệp JavaScript mà chúng tôi sẽ thêm mã vào một chút.

events.html
<!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 nút, chúng tôi sẽ thêm một thuộc tính được gọi là onclick. Giá trị thuộc tính sẽ là một hàm mà chúng ta tạo ra có tên là changeText ().
events.html
<!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 tệp events.js của chúng ta, mà chúng ta đã đặt trong thư mục js / ở đây. Trong đó, chúng ta sẽ tạo hàm changeText (), nó sẽ sửa đổi textContent của phần tử p.

js/events.js
// 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.";
}

Tuy nhiên, khi bạn hoặc người dùng khác nhấp vào nút, văn bản của thẻ p sẽ thay đổi từ Try to change me. để tôi thay đổi vì trình xử lý sự kiện trên dòng:

 Event handlers trên dòng 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 trình xử lý sự kiện trên dòng với các kiểu CSS trên dòng trên một phần tử HTML. Thực tế hơn là duy trì một biểu định kiểu riêng biệt của các lớp hơn là tạo kiểu nội tuyến trên mọi phần tử, cũng giống như khả thi hơn để duy trì JavaScript được xử lý hoàn toàn thông qua tệp tập lệnh riêng biệt hơn là thêm trình xử lý vào mọi phần tử.

Thuộc tính Event Handler 

Bước tiếp theo từ event handler nội tuyến là thuộc tính event handler. Điều này làm việc rất giống với một handler nội tuyến, ngoại trừ chúng tôi đang thiết lập thuộc tính của một phần tử trong JavaScript thay vì thuộc tính trong HTML. Thiết lập sẽ giống nhau ở đây, ngoại trừ chúng tôi không còn bao gồm onclick = "changeText ()" trong đánh dấu:
events.html
...
<body>

    <button>Click me</button>

    <p>I will change.</p>

</body>
...

Chức năng của chúng tôi sẽ vẫn tương tự, ngoại trừ bây giờ chúng tôi cần truy cập vào phần tử nút trong JavaScript. Chúng ta chỉ có thể truy cập onclick giống như chúng ta sẽ 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.

js/events.js
// 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 ý:  Event handlers không tuân theo quy ước camelCase mà hầu hết mã JavaScript
tuân thủ.Lưu ý rằng mã được onclick, không 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 ý rằng khi chuyển một tham chiếu hàm tới thuộc tính onclick, chúng ta không bao gồm các dấu ngoặc đơn, vì chúng 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 event handler có thể duy trì được nhiều hơn một chút so với trình xử lý nội tuyến, nhưng nó vẫn bị một số trở ngại tương tự. Ví dụ: cố gắng đặt nhiều, các thuộc tính onclick riêng biệt sẽ gây ra tất cả trừ thuộc tính cuối cùng sẽ bị ghi đè, như được minh họa bên dưới.
js/events.js
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, nút bấm sẽ chỉ hiển thị một alert, 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ả event handlers nội tuyến và các thuộc tính event handlers, hãy di chuyển đến các event listeners.

Event Listeners

Bổ sung mới nhất cho  event handlers JavaScript là event listeners.1 event listeners cho một sự kiện trên một phần tử. Thay vì gán trực tiếp sự kiện cho một thuộc tính trên phần tử, chúng 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 nó được lắng nghe, và hàm gọi lại của người nghe.

HTML cho trình xử lý sự kiện của chúng tôi sẽ giống như ví dụ trước.

events.html
...
    <button>Click me</button>

    <p>I will change.</p>
...

Chúng ta sẽ vẫn sử dụng hàm changeText () giống như trước đây. Chúng ta sẽ gắn phương thức addEventListener () vào button.

js/events.js
// 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 ý rằng với hai phương thức đầu tiên, một sự kiện nhấp chuột được gọi là onclick, nhưng với event listeners, nó được gọi là bấm. Mỗievent listeners sẽ giảm dần từ đó. Trong phần tiếp theo, chúng ta sẽ xem xét thêm các ví dụ về các loại sự kiện khác. Khi bạn tải lại trang có mã JavaScript ở trên, bạn sẽ nhận được kết quả sau:

Thoạt nhìn,event listeners có vẻ rất giống với các đặc tính event handler, nhưng chúng có một vài ưu điểm. Chúng tôi có thể đặt nhiều event listeners trên cùng một phần tử, như được minh họa trong ví dụ bên dưới.
js/events.js
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 người dùng cả văn bản cảnh báo và sửa đổi khi nhấp vào cảnh báo. Thông thường, các hàm ẩn danh sẽ được sử dụng thay vì tham chiếu hàm trên tevent listener. 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 () để loại bỏ một hoặc tất cả các sự kiện từ 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 tài liệu và cửa sổ. Event listeners hiện là cách phổ biến và được ưa thích nhất để xử lý các sự kiện trong JavaScript.

Events chung

Chúng ta đã học về các event handlers nội tuyến, các thuộc tính event handlervà event listeners bằng cách sử dụng sự kiện nhấn, nhưng có nhiều sự kiện trong JavaScript. Chúng tôi sẽ xem xét một số sự kiện phổ biến nhất bên dưới.

Mouse Events

Các sự kiện chuột nằm trong số các 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 nút trên chuột hoặc di chuột và di chuyển con trỏ chuột. Những 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.

Nhấp chuột là sự kiện kết hợp bao gồm các sự kiện kết hợp chuột xuống và lên, sẽ kích hoạt khi nút chuột được nhấn hoặc nâng lên tương ứng. Sử dụng chuột và mouseleave song song tái tạo một hiệu ứng di chuột kéo dài miễn là con trỏ chuột trên phần tử.

Form Events

Form events là những hành động liên quan đến form, chẳng hạn như các yếu tố đầu vào được chọn hoặc không được chọn và các biểu mẫu được gửi.

Focus đạt được khi một phần tử được chọn, ví dụ, thông qua một cú click chuột hoặc điều hướng đến nó thông qua phím TAB.
JavaScript thường được sử dụng để send form và gửi các giá trị thông qua ngôn ngữ backend. Lợi thế của việc sử dụng JavaScript để send form là nó không yêu cầu tải lại trang để send form và JavaScript có thể được sử dụng để xác thực các trường nhập bắt buộc.

Keyboard Events

Keyboard events được sử dụng để xử lý các thao tác bàn phím, chẳng hạn như bấm phím, nhấc phím và giữ phím.

Mặc dù chúng trông giống nhau, các sự kiện nhấn phím và bấm phím không truy cập tất cả các khóa giống nhau. Trong khi phím tắt sẽ xác nhận mọi phím được nhấn, nhấn phím sẽ bỏ qua các phím không tạo ra ký tự, chẳng hạn như SHIFT, ALT hoặc DELETE.

Keyboard events có các thuộc tính cụ thể để truy cập các khóa riêng lẻ.

Nếu một tham số, được gọi là một event object, được chuyển qua cho event listener, chúng 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 các đối tượng bàn phím bao gồm keyCodekey, và code..

Ví dụ: nếu người dùng nhấn chữ cái trên bàn phím của họ, các thuộc tính sau liên quan đến khóa đó sẽ hiển thị:

Để hiển thị cách thu thập thông tin đó thông qua Bảng điều khiển JavaScript, chúng tôi có thể viết các dòng mã sau đây.
// 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 chúng ta nhấn ENTER trên bàn điều khiển, bây giờ chúng ta có thể nhấn một phím trên bàn phím, trong ví dụ này, chúng ta sẽ nhấn a.
Output
keyCode: 65
key: a
code: KeyA
Thuộc tính keyCode là một số liên quan đến khóa đã được nhấn. Thuộc tính khóa là tên của ký tự, có thể thay đổi - ví dụ, nhấn phím SHIFT sẽ dẫn đến khóa A. Thuộc tính mã đại diện cho khóa vật lý trên bàn phím.
Lưu ý rằng keyCode đang trong quá trình không được chấp nhận và nên sử dụng mã trong các project new.
Để 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.

Event Objects

Event object bao gồm các thuộc tính và phương thức mà tất cả các sự kiện có thể truy cập. NgoàiEvent object chung, mỗi loại sự kiện có các phần mở rộng riêng của nó, chẳng hạn như KeyboardEvent và MouseEvent.

Event object được truyền qua một hàm listener như một tham số. Nó thường được viết dưới dạng event hoặc e. Chúng ta có thể truy cập thuộc tính mã của sự kiện keydown để tái tạo các điều khiển bàn phím của một game PC. Để dùng thử, hãy tạo một tệp HTML cơ bản với các thẻ <p> và tải nó vào trình duyệt.

event-test-p.html
<!DOCTYPE html>
<html lang="en-US">
<head>
    <title>Events</title>
</head>
<body>

  <p></p>

</body>
</html>
Sau đó, nhập mã JavaScript sau vào Bảng điều khiển 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à cho người dùng nhấn các phím đó và có thể tạo một trang web động hơn.

Tiếp theo, chúng ta sẽ đi qua một trong những thuộc tính sự kiện thường được sử dụng nhất: thuộc tính target. Trong ví dụ sau, chúng tôi có ba phần tử div bên trong một section.

 

event-test-div.html
<!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 Developer Console của trình duyệt, chúng tôi có thể đặt một event listener  trên phần tử phần bên ngoài section và nhận phần tử lồng nhau sâu sắc 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 yếu tố đó sẽ trả về kết quả của phần tử cụ thể có liên quan đến Bảng điều khiển bằng event.target. Điều này cực kỳ hữu ích, vì nó cho phép bạn chỉ đặt một event listener có thể được sử dụng để truy cập vào nhiều phần tử lồng nhau.

Với Event object, chúng tôi có thể thiết lập các câu trả lờ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 tiện ích mở rộng cụ thể hơn.

Phần kết luận

Event là các 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 chúng tôi có thể làm cho trang web phản hồi các hành động mà người dùng đã thực hiện. Trong hướng dẫn này, chúng 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 event handlers và event listenersvà cách truy cập Event object. Sử dụng kiến ​​thức này, bạn sẽ có thể bắt đầu tạo trang web và ứng dụng động.

 Bài dịch từ nguồn https://www.digitalocean.com/community/tutorials/understanding-events-in-javascript

 Xin cảm ơn các bạn đã theo dõi bài viết của Nguyên Vũ.