DOM chuyển động (Bài trước)
(Bài tiếp) DOM image slider

Bắt sự kiện trực tiếp trên phần tử HTML

Bạn có thể viết code JavaScript thi hành một tác vụ nào đó có một sự kiện xảy ra trên DOM (các phần tử HTML), ví dụ khi người dùng bấm vào một phần tử cụ thể, khi di chuyển chuột trên phần tử, khi Submit Form ...

Trường hợp đầu tiên này, các sự kiện trên phần tử coi như thuộc tính của phần tử, thuộc tính sự kiện sẽ được gán bằng tên hàm được thi hành hoặc code JS.

Ví dụ, trên các phần tử HTML bất kỳ đều có thuộc tính onclick (sự kiện click vào phần tử), vậy tạo một phần tử p có thuộc tính onclick được gán bằng một hàm JS có tên myfunc thì khi click vào phần tử p đó, hàm myfunc được thực thi, viết trong HTML sẽ như sau:

<p onclick="myfunc()">some text</p>

<script>
    function myfunc()
    {
        //... các chỉ thị lệnh
    }
</script>

Bảng các sự kiện HTML hay dùng

Tên các thuộc tính sự kiện này được sử dụng theo cách trên cho bất kỳ phần tử HTML nào.

Sự kiện Mô tả
onclick xảy ra khi bấm chuột vào phần tử
onload xảy ra khi phần tử được tải
onunload xảy ra khi trang un load (phần tử body)
onchange xảy ra khi thay đổi nội dung phần tử trong form như khi chọn select, khi người dùng bấm radio, áp dụng cho các phần tử (input, select, textarea)
onmouseover xảy ra khi chuột di chuyển trên phần tử, hoặc phần tử con của phần tử
onmouseout khi chuột di chuyển ra khỏi phần tử
onmousedown xảy ra khi bấm chuột trên phần tử
onmouseup xảy ra khi nhả bấm chuột trên phần tử
onblur xảy ra phi phần tử mất focus
onfocus xảy ra khi phần tử nhận focus (phần tử đang kích hoạt nhận dữ liệu)

Ví dụ bắt sự kiện trên phần tử HTML

Sự kiện có thể được bắt bằng cách khai báo ngay từ thuộc tính trong HTML, ví dụ sau hiện thị popup khi người dùng bấm chuột vào phần tử

<button onclick="show()">Click Me</button>
<script>
    function show() {
        alert("Hi there");
    }
</script>

Sự kiện đã được bắt bằng đoạn mã: onclick="show()"

Bắt sự kiện trên phần tử DOM - HTMLElement

Cách để bắt sự kiện trên phần tử HTML là bạn bắt sự kiện bằng mã JavaScript, thông qua đối tượng HTMLElement tìm được trên DOM. Các phần tử HTML nó đều biểu diễn bởi lớp HTMLElement, khi có được một phần tử HTMElement thì có thể gán thuộc tính sự kiện ở trên bằng các phương thức.

Ví dụ:

<button id="demoClickEvent">Bấm - Xem thời gian hiện tại?</button>

<script>
    // Lấy phần tử HTMLElement có ID bằng demoClickEvent
    var htmlelement_nutbam = document.getElementById("demoClickEvent");

    // Gán onclick bằng biểu thức phương thức (phương thức có thể có
    // một tham số là đối tượng MouseEvent, vd  function (ev) {}
    htmlelement_nutbam.onclick = function () {
        // Gán ngày hiện tại vào nội dung nút bấm
        htmlelement_nutbam.innerText = Date();
    }
</script>

Sự kiện đã được bắt bằng đoạn mã: htmlelement_nutbam.onclick = function () { ... } hoặc bằng htmlelement_nutbam.onclick = functionname();

onload, onunload

onloadunload xảy ra khi người dùng mở trang và rời trang.

<body onload="doSomething()">

Tương tự window.onload có thể được dụng để bắt dự kiện khi trang được tải.

window.onload = function() {
   //mã 
}

onchange

onchange dùng phổ biến trong hộp nhập dữ liệu văn bản. Sự kiện xảy ra khi nội dung textbox thay đổi và mất focus

<input type="text" id="name" onchange="change()">

<script>
    function change() {
         var x = document.getElementById("name");
         x.value= x.value.toUpperCase();
    }
</script>

Lắng nghe sự kiện trên DOM với addEventListener

Phương thức addEventListener() sẽ gắn thêm hàm (Listener) vào một phần tử để lắng nghe sự kiện của phần tử mà không loại bỏ các hàm sự kiện đã gắn trước. Điều này giúp cho một sự kiện xảy ra có thể gọi nhiều hàm Listener gắn với sự kiện đó.

element.addEventListener(event, listener, useCapture);

Các tham số là:

  • event: tên sự kiện ví dụ "click", "mousedown", "load", "change", "mouseover", "blur" ...
  • listener: tham số thứ 2 là hàm do bạn định nghĩa, muốn thi hành khi sự kiện xảy ra. Hàm này có một tham số là đối tượng EventTarget nhận được, khai báo hàm này có dạng:
    (event) { .... }
  • useCapture: tham số thứ 3 là giá trị true, false đây là một tùy chọn sẽ giải thích sau

Chú ý không có tiền tố on ví dụ sử dụng "click" chứ không phải onclick như phần trên.

// Có phần tử element
element.addEventListener("click", myFunction);      // Gọi myFunction khi có sự kiện click
element.addEventListener("mouseover", myFunction);  // Gọi myFunction khi có sự kiện mouseover

function myFunction(event) {
  alert("Hello World!");
}

removeEventListener

Hàm dùng để loại bỏ hàm (listener) đã gắn vào sự kiện trên phần tử

element.removeEventListener(name_event, listener);

Ví dụ sau gắn một hàm (listener) vào phần tử để lắng nghe sự kiện click, khi sự kiện đó xảy ra thì loại bỏ listener đó (không lắng nghe nữa - chỉ bấm được 1 lần).

<button id="demo">Start</button>

<script>
    var btn = document.getElementById("demo");
    btn.addEventListener("click", myListener);
    
    function myListener(e) {
      alert(Math.random());
      // Loại bỏ myListener trên sự kiện click của phần tử btn
      btn.removeEventListener("click", myListener);
    }
</script>

Kiểu lan truyền sự kiện

Ở đây giải thích tham số thứ 3 trong hàm addEventListener, tham số useCapture

Có hai kiểu lan truyền sự kiện gọi với tên: bubblingcapturing

capturing (tham số useCapture = true) - sự kiện đi từ trên xuống dưới của DOM
bubbling (tham số useCapture = false mặc định) - sự kiện truyền từ dưới lên trên trong cây DOM

Để giải thích giả sử có phần tử div bên trong nó chứa phần tử p (cả hai phần tử này đều có listener lắng nghe sự kiện click). Khi bấm chuột vào p thì xảy ra sự kiện click, Vậy phần tử p hay phần tử div sẽ bắt được sự kiện trước?

Đây là phần tử div

Đây là phần tử p, nằm trong div.

Nếu là capturing nghĩa là tham số thứ 3 useCapturetrue thì phần tử div nhận được sự kiện trước, sau đó mới đến p (sự kiện lan truyền từ phần tử chứa đến các phần tử con)

Nếu là bubbling nghĩa là tham số thứ 3 useCapturefalse thì phần tử p nhận được sự kiện trước, sau đó mới đến div

Bạn có thể dừng việc lan truyền sự kiện khi một phần tử nào đó đã nhận được, băng cách sử dụng stopPropagation (xem ở dưới)

//Capturing - gốc đến ngọn
elem1.addEventListener("click", myFunction, true); 

//Bubbling - từ ngọn đến gốc
elem2.addEventListener("click", myFunction, false);

Listener khi bắt các sự kiện

Nói kỹ hơn về các hàm để gắn vào sự kiện mà ta gọi là các Listener. Các hàm này có giao diện triển khai từ giao diện eventListener.handleEvent(event);

Có nghĩa là một hàm Javascript có 1 tham số, tham số đó chứa thông tin sự kiện gửi đến, mọi trường hợp bạn có định nghĩa ra các hàm Listener với cấu trúc như sau:

/***
 *
 * @param event Event
 */
function myListener(event) {

}

Khi Listener của bạn bắt được một sự kiện nào đó, nó luôn nhận được tham số chứa thông tin sự kiên, ở ví dụ trên lưu trong tham số event, tham số này là đối tượng kiểu Event

Event có nhiều phương thức, có một số mà bạn tham khao luôn ở đây như:

preventDefault() Ngăn cản ứng xử thông thường xảy ra trên phần tử. Ví dụ bạn bấm vào link, gọi phương thực này sẽ ngăn trình duyệt chuyển đến trang chỉ ra bởi link đó.
function myListener(event) {
    event.preventDefault();
    //Các code khác ...
}
stopPropagation() Dừng lan truyền sự kiện, ví dụ nếu một sự kiến có nhiều sự kiện đang lắng nghe, bạn muốn sau khi Listener của bạn bắt được thì các Lister khác không còn nhận được nữa thì gọi phương thức này.

Tạo và phát sự kiện Event

Ngoài cách sử dụng các sử kiện có sẵn trong các API mặc định trong DOM, bạn cũng có thể tạo ra những loại sự kiện riêng, tên sự kiện do bạn đặt và một đối tượng có thể phát ra sự kiện đó để listener đăng ký sẽ nhận được khi có sự kiện.

Ở ví dụ này, ta tạo ra một sự kiện có tên eventxinchao, sự kiện đó có chứa dữ liệu là dòng chữ "Dữ liệu của sự kiện", sau đó đối tượng DOM document phát đi sự kiện đó.

Mặt khác ta cũng gắn vào document một Listener đang lắng nghe sự kiện có tên eventxinchao, để mỗi khi sự kiện này xảy ra thì Listener này được gọi

<script>
    //Tạo ra Listener ngồi nghe sự kiện eventxinchao
    document.addEventListener("eventxinchao", function (e) {
        alert('Bắt được sự kiện eventxinchao, dữ liệu là: ' + e.dulieu);
    });
    
    
    //Mỗi khi hàm này được gọi document sẽ phát đi sự kiện eventxinchao
    function guiEventXinchao() {
        var myevent = document.createEvent('Event');        // Tạo ra một đối tượng Event       
        myevent.initEvent('eventxinchao', true, true);      // Tạo ra một đối tượng Event
        myevent.dulieu = "Xin chào, tôi là XUANTHULAB";     // Tạo ra một đối tượng Event
        document.dispatchEvent(myevent);                    // Cho document phát đi sự kiện
    }

</script>

<button onclick="guiEventXinchao();">Cho document gửi Event có tên eventxinchao</button>

Đăng ký nhận bài viết mới
DOM chuyển động (Bài trước)
(Bài tiếp) DOM image slider