+20

Bubbling và Capturing Event trong javascript (Phần 1)

Như các bạn đã biết khi làm việc với javascirpt thì đa phần các bạn làm việc với event , việc nắm bắt khái niệm event là vô cùng quan trọng. Các bạn đã bao giờ nghe 2 khái niệm bubbling và capturing event trong javascript chưa. Nếu các bạn chưa biết về nó, thì hãy cùng mình khám phá 2 khái niệm thú vị và "wired" này nhé

Bubbling and capturing

Trước khi hiểu được 2 khái niệm này, chúng ta cùng tìm hiểu ví dụ này nhé:

<div onclick="alert('The handler !')">
  <em>If you click on <code>EM</code>, the handler on <code>DIV</code> runs.</em>
</div>

Ta có gán thẻ

với sự kiện onclick, và bên trong thẻ div là thẻ <em> và <code>. Khi ta click đến thẻ <em> thì sự kiện onclick trên thẻ <div> sẽ được kích hoạt (trigger) và xuất ra dòng alert là "The handler". Các bạn có thấy điều quái dị ở đây không. Tại sao event của javascirpt lại làm được điều này nhé =))

Bubbling

Bubbling là khái niệm vô cùng đơn giản, bubbling giống như nổi bọt trong nước vậy =)) Đây là khái niệm đầy đủ nhất mà tiki định nghĩa về bubbling

When an event happens on an element, it first runs the handlers on it, then on its parent, then all the way up on other ancestors.

<style>
  body * {
    margin: 10px;
    border: 1px solid blue;
  }
</style>

<form onclick="alert('form')">FORM
  <div onclick="alert('div')">DIV
    <p onclick="alert('p')">P</p>
  </div>
</form>

Ở ví dụ này, có 3 thẻ element như sau FORM > DIV > P. Mỗi phần tử sẽ có sự kiện onclick + xuất ra alert với text tương ứng với element đó Khi chúng ta click vào thẻ

thì điều gì sẽ xãy ra nhé

  1. Thẻ p sẽ kích hoạt sự kiện và alert ra text "p"
  2. Và tiếp tục bubbling lên thẻ <div> và alert ra text "div"
  3. Và tiếp tục bubbling lên thẻ <form> và alert ra text "form"
  4. Và thậm chí nó còn bubbling lên document, và nó sự kích hoạt sự kiện của document, nếu document có sự kiện

Thật "wired" phải không các bạn, Quy trình này được gọi là "bubbling". các phần tử con sẽ "up through" đến phần tử cha. Các này rất giống với nổi bọt trong nước 😃

Almost all events bubble. The key word in this phrase is “almost”.

For instance, a focus event does not bubble. There are other examples too, we’ll meet them. But still it’s an exception, rather then a rule, most events do bubble. Và một lưu ý nhỏ đó là event focus không có cơ chế

event.target

Chúng ta hãy quay lên ví dụ ở trên

<form>FORM
  <div>DIV
    <p>P</p>
  </div>
</form>
<script>
form.onclick = function(event) {
  event.target.style.backgroundColor = 'yellow';

  alert("target = " + event.target.tagName + ", this=" + this.tagName);

  event.target.style.backgroundColor = '';
};
</script>

Ở ví dụ trên các bạn thấy event.target.tagNamethis.tagName nó khác nhau như thế nào nhé Đây là khái niệm event.target đầy đủ nhất

The most deeply nested element that caused the event is called a target element, accessible as event.target.

Hay nói cách khác cho dễ hiểu là khi chúng ta kích hoạt lên 1 element <html> nào có event, thì event.target = element (<div>, <p,> <em>) được kích hoạt Một điều lưu ý cực kì quan trọng đó là this trong function callback khi tạo event. this = event.currentTarget Chúng ta cùng mổ xẻ đoạn code ở trên nhé

  1. event.target là phần tử sẽ tạo ra khi mà kích hoạt event lên element tương ứng, hay nói cách khác là khi click lên thẻ <p> => event.target == <p>, và thẻ <form>, <div> cũng như vậy. Và một điểm lưu ý nhỏ là nó sẽ không thay đổi element trong quy trình bubbling nha =))
  2. this == event.currentTarget: là element html mà khai báo event trên nó, hay nói cách khác cho dễ hiểu là this <=> element khai báo event, ở ví dụ trên thì thẻ form khai báo event, và các phần con thì không có event, mà khi ta click đến các phần tử con thì nó sẽ bubble lên phần cha nó có event rồi nó sẽ kích hoạt event đó. Ở trên this chính là <form>

Vậy khi ta khai báo event trên phần tử nào thì sẽ this (event.currentTarget) sẽ tương ứng với element đó. Mình nghĩ đây là khái niệm khá là quan trọng, nếu mà chúng ta không hiểu khái niệm này thì các bạn sẽ vô cùng lúng túng cho việc thao tác với DOM (document Object Model) đó

Stopping bubbling

Khi chúng ta làm việc thực tế, ví dụ như là trong thẻ div có rất nhiều phần thử con có event, nhưng mà ta chỉ muốn click hoạt phần tử con mà ta target thôi, có bubbling đến các phần tử parent của đó thì chúng ta dùng event.stopPropagation() thì nó sẽ ngăn chặn bubbling. Chúng ta đến ví dụ này sẽ hiểu hơn

body onclick="alert(`the bubbling doesn't reach here`)">```
    <button onclick="event.stopPropagation()">Click me</button>
</body>

Khi chúng ta click và button Click me thì nó sẽ không bubbling đến event của <body>. Thật tuyệt vời phải không nào Tới đây các bạn cũng hiểu một phần nào đó về bubbling event trong javaiscript, khái niệm này theo mình khá thú vị á chứ. Và như title bubbling và capturing event. Bài viết cũng khá dài rồi. Mình sẽ hẹn các bạn ở bài sau nhé (phần 2) (seeyou)


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.