fbpx

Bài 8: Tìm hiểu sự kiện trong Javascript

Ở bài học trước chúng ta đã tìm hiểu về Javascript và HTML DOM, các bạn cũng đã biết qua về cách có thể can thiệp vào dữ liệu cũng như thực hiện thay đổi giá trị và lấy giá trị. Trong bài này, các bạn cũng sẽ được tìm hiểu đến phần quan trọng cũng như là phần thú vị nhất trong Javascript. Đó chính là sự kiện trong Javascript (JS).

Tìm hiểu sự kiện trong Javascript

Sự kiện trong Javascript (JS) có thể hiểu đơn giản là “điều gì đó sẽ xảy ra và khi đó chúng ta sẽ thực hiện hành động nào đó tương ứng với điều sẽ xảy ra”, hay có một ví dụ thực tế hơn “Khi có một thiên thạch rơi (sự kiện “rơi”) gần đến chỗ bạn, thì hành động của bạn lúc đó sẽ là…chạy và chạy” có đúng không nào.

Vì thế, Javascript xử lý các sự kiện cũng như cách mà chúng ta hiểu, mà ở trong những phần trước, nếu các bạn để ý là khi chúng ta “click” vào một “button” hay một “đối tượng” (element) nào đó trong HTML, thì chúng ta thường thấy có sự kiện “onclick” hay lúc “rê chuột” (hover) thì có sự kiện “onmouseover” và lúc đó chúng ta sẽ thực hiện hàm nào đó hay các câu lệnh mà chúng ta viết trực tiếp ở HTML.

Các bạn có thể tìm hiểu về danh sách các sự kiện trong HTML tại đây http://www.w3schools.com/tags/ref_eventattributes.asp.

Ví dụ

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
	<style type="text/css">
		p.hover-me {
			display: inline-block;
			width: 200px;
			height: 50px;
			background: #d5d5d5;
		}
	</style>	
</head>
<body onload="loadMe();">
	<a href="#" title="Click vào tôi" onclick="clickMe();">Click vào tôi</a><br/>
	<p class="hover-me" onmouseover="hoverMe();">Hãy rê chuột vào tôi</p><br/>
	<select onchange="changeMe();">
		<option value="">Hãy thay đổi tôi đi</option>
		<option value="">Tôi thay đổi</option>
	</select>
	<script type="text/javascript" charset="utf-8">
		function clickMe() {
			alert('Đã nhấn');
		}

		function changeMe() {
			alert('Đã thay đổi');
		}

		function hoverMe() {
			alert('Đã rê chuột vào');
		}

		function loadMe() {
			alert('Đã Load thành công toàn bộ');
		}
	</script>		
</body>
</html>
  • Sau khi các bạn chạy ví dụ này, các bạn sẽ thấy rõ ràng khi các bạn nhấp vào đường link “Click vào tôi” thì sự kiện “onclick” gọi đến hàm “clickMe();” và thực thi hàm đó. Tương tự với các sự kiện “onmouseover”(Rê chuột) và “onchange”(Thay đổi giá trị) sẽ gọi các hàm tương ứng khi các bạn sử dụng các hành động phù hợp với sự kiện.Và như vậy các bạn đã phần nào biết cách sử dụng Event để gọi trong Javascript thông qua các thuộc tính trong HTML rồi.

Câu hỏi: Vậy liệu có cách nào mà không cần dùng đến thuộc tính trong HTML mà trong chúng ta có thể viết thẳng bên trong Javascript không? Giống như cách mà jQuery đã làm.

Trả lời: Xin thưa các bạn là còn, và chúng ta sẽ cùng tìm hiểu đến với hàm “addEventListener()” nhé.

Tìm hiểu “addEventListener()”

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
	<style type="text/css">
		p.hover-me {
			display: inline-block;
			width: 200px;
			height: 50px;
			background: #d5d5d5;
		}
	</style>	
	<script type="text/javascript">
		window.addEventListener('load', function() {
			alert('Đã Load thành công toàn bộ');
		});
	</script>
</head>
<body>
	<a href="#" title="Click vào tôi" id="click_me">Click vào tôi</a><br/>
	<p class="hover-me" id="hover_me">Hãy rê chuột vào tôi</p><br/>
	<select id="change_me">
		<option value="">Hãy thay đổi tôi đi</option>
		<option value="">Tôi thay đổi</option>
	</select>
	<script type="text/javascript" charset="utf-8">
		document.getElementById('click_me').addEventListener('click', function() {
			alert('Đã nhấn');
		});

		document.getElementById('hover_me').addEventListener('mouseover', function() {
			alert('Đã rê chuột vào');
		});

		document.getElementById('change_me').addEventListener('change', function() {
			alert('Đã thay đổi');
		});
	</script>		
</body>
</html>
  • Ví dụ trên cho các bạn thấy rằng, khi các bạn dùng đến “addEventListener()” sẽ giúp cho trang HTML của các bạn nhìn rõ ràng và dễ hiểu hơn, thay vì chúng ta phải viết thêm các thuộc tính “onsubmit, onclick, onload…” thì nay chúng ta chỉ cần dùng đến “addEventListener()” kết hợp với “document.getElementById()” để tìm đích danh đối tượng mà chúng ta chỉ định.
  • Ngoài ra, tên sự kiện của chúng ta sẽ bị loại bỏ mất chữ “on” ở đầu khi các bạn truyền vào đối số đầu tiên trong “addEventListener()” và các sự kiện các bạn có thể tham khảo thêm tại đây http://www.w3schools.com/tags/ref_eventattributes.asp.

Tuy nhiên, ví dụ trên chỉ là một nửa của vấn đề bởi vì chúng ta sẽ còn 1 đối số cuối cùng nữa của “addEventListener()” mà tôi chưa đề cập ở ví dụ trên có tên gọi là “useCapture”. Các bạn hãy xem qua ví dụ dưới đây nhé.

Event Listener

1. Chưa có đối số thứ 3 (Mặc định đối số thứ 3 có giá trị là “false” nếu không tồn tại)

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
	<style type="text/css">
		#div_click {
			width: 400px;
			height: 300px;
			background: green;
		}

		#p_click {
			width: 200px;
			height: 150px;
			background: #d5d5d5;
		}

	</style>	
</head>
<body>
	<div id="div_click">
		<p id="p_click">
			<a href="#" id="a_click">Click tôi đi</a>
		</p>
	</div>
	<script type="text/javascript" charset="utf-8">
		document.getElementById('a_click').addEventListener('click', function() {
			alert('Thẻ a được click');
		});

		document.getElementById('p_click').addEventListener('click', function() {
			alert('Thẻ p được click');
		});

		document.getElementById('div_click').addEventListener('click', function() {
			alert('Thẻ div được click');
		});
	</script>		
</body>
</html>
  • Kết quả ở ví dụ trên khi các bạn click vào “Click tôi đi” các bạn sẽ nhận được 3 thông báo theo thứ tự “Thẻ a được click” => “Thẻ p được click” => “Thẻ div được click”. Bởi vì cả 3 vùng này đều được gán sự kiện (event) “click” và cách gọi của nó nếu các bạn để ý thì nó sẽ gọi từ thẻ “a” mà chúng ta đã click vào “Click tôi đi” cho đến tới vùng “div” cũng có sự kiện click bao quanh thẻ “a”. Và tương tự nếu chúng ta click vào thẻ “p” thì cũng sẽ được thông báo theo thứ tự “Thẻ p được click” => “Thẻ div được click”, và cuối cùng là nếu chúng ta click vào vùng “div” thì chỉ có thông báo “Thẻ div được click” mà thôi.

Kết luận ở trường hợp này, khi chúng ta click vào một đối tượng nào đó có sự kiện trùng với đối tượng cha hoặc lớn hơn nữa như ông nội, ông ngoại gì đấy cũng có sự kiện tương tự thì sẽ chạy theo thứ tự “từ nhỏ đến lớn hay từ trong ra ngoài”.

2. Có đối số thứ 3

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
	<style type="text/css">
		#div_click {
			width: 400px;
			height: 300px;
			background: green;
		}

		#p_click {
			width: 200px;
			height: 150px;
			background: #d5d5d5;
		}

	</style>	
</head>
<body>
	<div id="div_click">
		<p id="p_click">
			<a href="#" id="a_click">Click tôi đi</a>
		</p>
	</div>
	<script type="text/javascript" charset="utf-8">
		document.getElementById('a_click').addEventListener('click', function() {
			alert('Thẻ a được click');
		}, true);

		document.getElementById('p_click').addEventListener('click', function() {
			alert('Thẻ p được click');
		}, true);

		document.getElementById('div_click').addEventListener('click', function() {
			alert('Thẻ div được click');
		}, true);
	</script>		
</body>
</html>
  • Kết quả, các bạn sẽ thấy rằng nó sẽ bị ngược so với ví dụ không có đối số thứ 3 ở trên. Nó sẽ có thứ tự ngược lại “Thẻ div được click” => “Thẻ p được click” => “Thẻ a được click”.

Vậy các bạn phần nào hiểu được đối số thứ 3 rồi phải không. Nó giúp chúng ta đảo ngược lại bằng cách sẽ gọi “từ lớn về nhỏ hay từ cao xuống thấp”. Tuy nhiên, các bạn vẫn chưa hiểu đúng về nó đâu nhé. Hãy xem qua ví dụ cuối.

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
	<style type="text/css">
		#div_click {
			width: 400px;
			height: 300px;
			background: green;
		}

		#p_click {
			width: 200px;
			height: 150px;
			background: #d5d5d5;
		}

	</style>	
</head>
<body>
	<div id="div_click">
		<p id="p_click">
			<a href="#" id="a_click">Click tôi đi</a>
		</p>
	</div>
	<script type="text/javascript" charset="utf-8">
		document.getElementById('a_click').addEventListener('click', function() {
			alert('Thẻ a được click');
		}, false);

		document.getElementById('p_click').addEventListener('click', function() {
			alert('Thẻ p được click');
		}, true);

		document.getElementById('div_click').addEventListener('click', function() {
			alert('Thẻ div được click');
		}, false);
	</script>		
</body>
</html>
  • Kết quả thật bất ngờ khi các bạn click vào “Click tôi đi”. Thứ tự dường như chạy loạn xạ “Thẻ p được click” => “Thẻ a được click” => “Thẻ div được click”.

Nhưng sự thật là nó đã chạy đúng rồi đấy các bạn ạ. Thẻ “p” được gán giá trị “true” cho đối số thứ 3, giúp nó sẽ trở thành đối tượng ưu tiên. Nghe qua thật khó hiểu nhưng tôi sẽ có một bảng nho nhỏ ở đây để các bạn hiểu được nó rõ ràng hơn.

Cho thẻ “a” là (1), thẻ “p” là (2) và thẻ “div” là (3)

Giá trị đối số thứ 3 Ưu tiên khi chạy Sự kiện trùng nhau
(1) True

(2) False

(3) False

(1) a

(2) p

(3) div

(1) False

(2) True

(3) False

(2) p

(1) a

(3) div

(1) False

(2) False

(3) True

(3) div

(1) a

(2) p

(1) False

(2) True

(3) True

(3) div

(2) p

(1) a

(1) True

(2) False

(3) True

(3) div

(1) a

(2) p

Bảng tóm tắt các trường hợp xảy có thể xảy ra khi các bạn dùng giá trị “true”, “false” lẫn lộn mà cách chạy của nó sẽ có phần khác nhau. Các bạn sẽ rút ra được kết luận là “Tác dụng của đối số thứ 3 chính là thay đổi sự ưu tiên thành “từ lớn xuống nhỏ hay từ ngoài vào trong” khi trùng sự kiện với nhau.”

Ghi chú

  • Hàm: addEventListener(‘event’, function, useCapture)
  • Đối số:
  1.             ‘event’: tên của event, giống với khi dùng thuộc tính HTML nhưng bỏ chữ “on” ở đầu sự kiện như “onclick => click”, “onload => load”.
  2.             Function: hàm thực thi khi sự kiện được gọi.
  3.             useCapture: thay đổi độ ưu tiên khi trùng sự kiện.
  • Mức độ phổ biến: rất thông dụng
  • Thực tế: được dùng rất nhiều để bắt sự kiện mà không cần viết thuộc tính trong HTML, giúp HTML dễ đọc và gọn gàng hơn. Javascript viết cũng khoa học và dễ điều chỉnh hơn.

Trong bài này, chúng ta cũng đã kết thúc phần tìm hiểu Javascript Cơ bản tại đây. Ở các bài viết sau, tôi sẽ hướng dẫn các bạn về các hàm thông dụng trong Javascript và các thủ thuật trong Javascript và cách ứng dụng của nó vào trong thực tế như thế nào.