fbpx

Hướng dẫn sử dụng jQuery Lazy Load

Chắc hẳn trong quá trình xây dựng Website, ít nhiều các bạn cũng từng nghĩ làm cách nào để có thể giảm tải bớt băng thông cho việc load hình ảnh trên Website, nhất là những trang người dùng chỉ load vào xem nội dung rồi vội vàng ra đi. Như thế thì chúng ta vô tình lại tốn băng thông nhưng lại không giúp ích gì được cho chúng ta. Vậy làm sao để hạn chế điều này? Có cách nào có thể giúp người dùng cuộn trang tới đâu, hình ảnh load tới đó không? Câu trả lời là có và tôi sẽ giới thiệu với các bạn đến với jQuery Lazy Load Plugin để có thể thực hiện được việc này.

Giới thiệu và cài đặt

Tác giả: Mika Tuupola

Website: http://www.appelsiini.net/projects/lazyload

jQuery Lazy Load được xây dựng giúp người dùng cuộn tới đâu, load hình tới đó giúp cho việc giảm tải băng thông cho Website.

Để có thể cài đặt jQuery Lazy Load các bạn cần thực hiện các bước sau:

  1. Truy cập vào https://github.com/tuupola/jquery_lazyload và nhấn vào nút “Download ZIP”.
  2. Giải nén file vừa tải về, chúng ta sẽ được cấu trúc thư mục như sau:

Cấu trúc thư mục

  1. Các bạn hãy vào folder “jquery_lazyload-master” và sau đó copy file “jquery.lazyload.min.js”.
  2. Sau đó, các bạn hãy bỏ vào folder chứa website mà chúng ta xây dựng.
  3. Tiến hành thêm thư viện vào trong website của chúng ta, nhưng các bạn cũng cần phải tải thư viện jQuery tại http://jquery.com về trước nhé:

Chèn jQuery Lazy Load

  1. Cài đặt hoàn tất

Sử dụng

Đầu tiên, để sử dụng thư viện này, các bạn hãy chuẩn bị cho tôi 1,2 hoặc nhiều tấm hình trở lên. Cụ thể ở đây tôi sẽ có tấm hình “demo.gif”:

Tiếp theo, chúng ta sẽ load tấm hình đó vào HTML và hãy nhân bản lên thành nhiều tấm để tiện cho việc chúng ta tập cách sử dụng:

	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />

Ở đoạn code trên, nếu các bạn để ý thì thay vì chúng ta dùng thẻ “<img>” và có thuộc tính “src” để chỉ rõ đường dẫn của tấm hình thì nay nó đã được thay thế bằng “data-original” và cách gán đường dẫn giống với thuộc tínhsrc”:

4

Các bạn cũng nên định nghĩa một tên class để tiện cho việc tìm đến những tấm ảnh này thông qua jQuery. Sau đó, các bạn hãy dùng thẻ “<script>” để tiến hành sử dụng thư viện jQuery Lazy Load:

	<script type="text/javascript">
		$(function() {
		    $("img.ten-lop-ban-tu-dat").lazyload({
		    	effect : "fadeIn"
		    });
		});
	</script>

Sau khi thực hiện đoạn code này, chúng ta đã thành công trong việc sử dụng thư viện rồi đấy. Thông qua việc sử dụng phương thức “lazyload()” ở thẻ “<img>” mà bạn chỉ định. Và đối số trong phương thức “lazyload()” chính là một đối tượng chứa các tính năng mà bạn có thể tùy biến theo hướng dẫn của tác giả Plugin jQuery Lazy Load.

Và đoạn code đầy đủ của nó sẽ như sau:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Test</title>	
	<style type="text/css">
	img {
		float:left;
		width: 500px;
		height: 500px;
	}
	</style>
	<script type="text/javascript" src="jquery-1.11.3.min.js"></script>	
	<script type="text/javascript" src="jquery.lazyload.min.js"></script>
</head>
<body>
	<img src="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />
	<img data-original="demo.gif" class="ten-lop-ban-tu-dat" />	
	<script type="text/javascript">
		$(function() {
		    $("img.ten-lop-ban-tu-dat").lazyload({
		    	effect : "fadeIn"
		    });
		});
	</script>
</body>
</html>

Một số tính năng có thể sử dụng trong jQuery Lazy Load

threshold Load trước số pixel chỉ định
event Thực hiện load hình ảnh khi sự kiện chỉ định được gọi
effect Hiệu ứng load hình ảnh
skip_invisible Bỏ qua các hình ảnh không được hiển thị trong viewport
failure_limit Chạy vòng lặp kiểm tra hình ảnh load bị lỗi với số lần quy định

Demo cách sử dụng gộp các tính năng:

	<script type="text/javascript">
		$(function() {
		    $("img.ten-lop-ban-tu-dat").lazyload({
		    	effect : "fadeIn",
		    	threshold: 100,
		    	event : "mouseover"
		    });
		});
	</script>

Trên đây chỉ thống kê ngắn gọn các tính năng của jQuery Lazy Load, chắc chắn vẫn chưa đầy đủ ở Website của tác giả, mong bạn đọc thông cảm. Bạn có thể tải file demo-jquery-lazy-load tại đây.

 

Hướng dẫn sử dụng jQuery Validation

I. Giới thiệu và Cài đặt

Tác giả: Jörn Zaefferer

Website: http://jqueryvalidation.org

logo

jQuery Validation được xây dựng giúp các lập trình viên có thể xác thực được những thông tin người dùng nhập vào Form một cách nhanh chóng và dễ dàng.

Để có thể cài đặt jQuery Validate các bạn cần thực hiện các bước sau:

  1. Truy cập vào https://github.com/jzaefferer/jquery-validation và nhấn vào nút “Download ZIP”.
  2. Giải nén file vừa tải về, chúng ta sẽ được cấu trúc thư mục như sau:

1. Cau truc folder

  1. Các bạn hãy vào folder “dist” và sau đó copy file “jquery.validate.min.js”.
  2. Sau đó, các bạn hãy bỏ vào folder chứa website mà chúng ta xây dựng.
  3. Tiến hành thêm thư viện vào trong website của chúng ta, nhưng các bạn cũng cần phải tải thư viện jQuery tại http://jquery.com về trước nhé:

Thêm thư viện vào HTML

  1. (Tùy chọn) Nếu như các bạn không thích tải về thư viện jQuery Validation hoặc kể cả jQuery, các bạn có thể dùng các đường link CDN sau đây:
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.1/jquery.validate.min.js"></script>
  1. Cài đặt hoàn tất.

II. Sử dụng

Để sử dụng jQuery Validation các bạn cần phải biết qua phương thức “$(‘#id_cua_form’).validate()” (Nếu dùng class thì các bạn hãy tự thay thế). Chúng ta sẽ có cấu trúc HTML đơn giản như sau:

<form method="get" accept-charset="utf-8" style="width:600px;margin: 0px auto;" id="formDemo">
		<fieldset>
			<legend>Demo jQuery Validation - ThienAnBlog.com</legend>
			<div>
				<label>Họ</label>
				<input name="ho" type="text" placeholder="Vui lòng nhập họ" required>
			</div>
			<div>
				<label>Tên</label>
				<input name="ten" type="text" placeholder="Vui lòng nhập tên" required>
			</div>
			<div>
				<label>Địa chỉ</label>
				<input name="diachi" type="text" placeholder="Vui lòng nhập địa chỉ" required>
			</div>
			<button type="submit">Gửi</button>
		</fieldset>
	</form>

Và cấu trúc thẻ <script>:

$(document).ready(function() {

		//Khi bàn phím được nhấn và thả ra thì sẽ chạy phương thức này
		$("#formDemo").validate({
			rules: {
				ho: "required",
				ten: "required",
				diachi: {
					required: true,
					minlength: 2
				}
			},
			messages: {
				ho: "Vui lòng nhập họ",
				ten: "Vui lòng nhập tên",
				diachi: {
					required: "Vui lòng nhập địa chỉ",
					minlength: "Địa chỉ ngắn vậy, chém gió ah?"
				}
			}
		});
	});

Khi chạy nó, các bạn sẽ thấy thư viện của chúng ta sẽ thực hiện “Xác thực” (Validate) khi chúng ta nhấn vào nút “Submit” thì ở đây nó chính là nút “Gửi”. Hoặc các bạn có thể gõ vài dòng chữ vào và nhận ra sự khác biệt khi xóa đi. Đó chính là những đoạn thông báo nhỏ như sau:

Form Validate - Simple

Rất là đẹp mắt phải không các bạn? Nhưng thật ra để được vậy thì các bạn phải có CSS vào nữa đấy chứ thật ra Form này khi không có CSS thì các bạn sẽ thấy nó chạy lung tung.

Tôi sẽ giải thích một tí về đoạn script mà chúng ta viết:

  1. Phương thức “validate()” chấp nhận 1 đối số là một đối tượng2 thuộc tính chính là “rules” và “messages”.
  2. Trong đó, “rules” đại diện cho điều kiện xác thực như “required”(Không bỏ trống), “minlength”(Độ dài tối thiểu)…và “messages” đại diện cho các thông báo lỗi mà chúng ta đã thấy ở ví dụ trên.
  3. Và thuộc tính “rules” của chúng ta sẽ lại bao gồm các phần tử con cũng là một đối tượng với các thuộc tính bên trong nó chính là thuộc tính “name” bên trong các thẻ “input” của chúng ta. Các bạn có thể xem qua hình ảnh sau:

So sanh HTML va Code

  1. Rất đơn giản phải không nào? “messages” cũng sẽ tương tựrules” và nếu bạn tinh ý sẽ nhận ra là kể cả điều kiện bên trong nó như “required”, “minlength” cũng sẽ tương đồng với bên “messages”. Hai cái chỉ khác nhau về công việc mà thôi.
  2. Như vậy, chúng ta đã hoàn tất được công việc “Validate” rồi đấy.

Chúng ta sẽ có cấu trúc hoàn chỉnh như sau:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>jQuery Validation - ThienAnBlog.com</title>	
	<style type="text/css">
	label {
		display: inline-block;
		width: 150px;
	}
	input[type="text"], input[type="password"] {
		display: inline-block;
		width: 200px;
	}
	label.error {
		display: inline-block;
		color:red;
		width: 200px;
	}
	</style>
	<!-- Load Thư viện jQuery vào trước khi load jQuery Validate-->
	<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
	<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.1/jquery.validate.min.js"></script>
</head>
<body>
	<form method="get" accept-charset="utf-8" style="width:600px;margin: 0px auto;" id="formDemo">
		<fieldset>
			<legend>Demo jQuery Validate - ThienAnBlog.com</legend>
			<div>
				<label>Họ</label>
				<input name="ho" type="text" placeholder="Vui lòng nhập họ" required>
			</div>
			<div>
				<label>Tên</label>
				<input name="ten" type="text" placeholder="Vui lòng nhập tên" required>
			</div>
			<div>
				<label>Địa chỉ</label>
				<input name="diachi" type="text" placeholder="Vui lòng nhập địa chỉ" required>
			</div>
			<button type="submit">Gửi</button>
		</fieldset>
	</form>
	<script type="text/javascript">

	$(document).ready(function() {

		//Khi bàn phím được nhấn và thả ra thì sẽ chạy phương thức này
		$("#formDemo").validate({
			rules: {
				ho: "required",
				ten: "required",
				diachi: {
					required: true,
					minlength: 2
				}
			},
			messages: {
				ho: "Vui lòng nhập họ",
				ten: "Vui lòng nhập tên",
				diachi: {
					required: "Vui lòng nhập địa chỉ",
					minlength: "Địa chỉ ngắn vậy, chém gió ah?"
				}
			}
		});
	});
	</script>
</body>
</html>

Ngoài ra, tôi sẽ gửi thêm cho các bạn một file demo khác để giúp các bạn hình dung rõ ràng hơn như sau:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>jQuery Validate - ThienAnBlog.com</title>	
	<style type="text/css">
	label {
		display: inline-block;
		width: 150px;
	}
	input[type="text"], input[type="password"] {
		display: inline-block;
		width: 200px;
	}
	label.error {
		display: inline-block;
		color:red;
		width: 200px;
	}
	</style>
	<!-- Load Thư viện jQuery vào trước khi load jQuery Validate-->
	<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
	<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.1/jquery.validate.min.js"></script>
</head>
<body>
	<form method="get" accept-charset="utf-8" style="width:600px;margin: 0px auto;" id="formDemo">
		<fieldset>
			<legend>Demo jQuery Validate - ThienAnBlog.com</legend>
			<div>
				<label>Họ</label>
				<input name="ho" type="text" placeholder="Vui lòng nhập họ" required>
			</div>
			<div>
				<label>Tên</label>
				<input name="ten" type="text" placeholder="Vui lòng nhập tên" required>
			</div>
			<div>
				<label>Địa chỉ</label>
				<input name="diachi" type="text" placeholder="Vui lòng nhập địa chỉ" required>
			</div>
			<div>
				<label>Số điện thoại</label>
				<input name="sodienthoai" type="text" placeholder="Vui lòng nhập số điện thoại" required>
			</div>
			<div>
				<label>Email</label>
				<input name="email" type="text" placeholder="Vui lòng nhập Email" required>
			</div>
			<div>
				<label>Mật khẩu</label>
				<input id="password" name="password" type="password" placeholder="Vui lòng nhập Password" required>
			</div>
			<div>
				<label>Nhập lại mật khẩu</label>
				<input name="confirm_password" type="password" placeholder="Vui lòng nhập lại Password" required>
			</div>
			<div>
				<label>Điều khoản</label>
				<input name="dieukhoan" type="checkbox">
			</div>
			<div>
				<label>Thông tin thêm</label>
				<input name="thongtinthem" type="text" placeholder="Tùy chọn...">
			</div>
			<button type="submit">Gửi</button>
		</fieldset>
	</form>
	<script type="text/javascript">

	$(document).ready(function() {

		//Khi bàn phím được nhấn và thả ra thì sẽ chạy phương thức này
		$("#formDemo").validate({
					rules: {
						ho: "required",
						ten: "required",
						diachi: {
							required: true,
							minlength: 2
						},
						sodienthoai: {
							required: true,
							minlength: 5
						},
						password: {
							required: true,
							minlength: 5
						},
						confirm_password: {
							required: true,
							minlength: 5,
							equalTo: "#password"
						},
						email: {
							required: true,
							email: true
						},
						dieukhoan: "required"
					},
					messages: {
						ho: "Vui lòng nhập họ",
						ten: "Vui lòng nhập tên",
						diachi: {
							required: "Vui lòng nhập địa chỉ",
							minlength: "Địa chỉ ngắn vậy, chém gió ah?"
						},
						sodienthoai: {
							required: "Vui lòng nhập số điện thoại",
							minlength: "Số máy quý khách vừa nhập là số không có thực"
						},
						password: {
							required: 'Vui lòng nhập mật khẩu',
							minlength: 'Vui lòng nhập ít nhất 5 kí tự'
						},
						confirm_password: {
							required: 'Vui lòng nhập mật khẩu',
							minlength: 'Vui lòng nhập ít nhất 5 kí tự',
							equalTo: 'Mật khẩu không trùng'
						},
						email: {
							required: "Please provide a password",
							minlength: "Your password must be at least 5 characters long",
							equalTo: "Please enter the same password as above"
						},
						email: "Vui lòng nhập Email",
						agree: "Vui lòng đồng ý các điều khoản"
					}
				});
	});
	</script>
</body>
</html>

Các bạn có thể tải các Demo trên tại đây.

Một số điều kiện bên trong jQuery Validation

required Không được bỏ trống
remote Gửi yêu cầu về Web Server để xác thực
minlength Độ dài tối thiểu
maxlength Độ dài tối đa
rangelength Độ dài tối thiểu từ x tới y
min Số tối thiểu
max Số tối đa
range Số tối thiểu từ x tới y
email Xác thực định dạng Email
url Xác thực định dạng URL
date Xác thực định dạng ngày tháng
dateISO Xác thực định dạng ngày tháng theo chuẩn ISO
number Phải là số, bao gồm số thập phân
digits Chỉ chấp nhận số nguyên dương
creditcard Xác thực số thẻ tín dụng
equalTo Phải trùng với phần tử nào đó

Ngoài ra, các bạn có thể tham khảo tại đây http://jqueryvalidation.org/documentation để có thể tìm hiểu thêm về thư viện này.

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.

Bài 7: Javascript và HTML DOM

Ở những bài trước, chúng ta đã tìm hiểu về kiểu dữ liệu, phạm vi hoạt động của biến trong Javascript (JS) cũng như các nền tảng kiến thức mà các bạn cần có ở các bài trước. Trong bài học này, chúng ta sẽ tìm hiểu về Javascript và HTML DOM.

Javascript và HTML DOM

DOM được viết tắt của “Document Object Model” (DOM – Mô hình đối tượng tài liệu), giúp chúng ta khi sử dụng Javascript có thể can thiệp vào các thành phần trong HTML để lấy dữ liệu cũng như có thể can thiệp về cấu trúc hoặc giao diện (CSS).

Vậy làm thế nào để có thể đọc được DOM cũng như các thành phần trong HTML? Các bạn hãy xem qua các ví dụ sau đây:

(Vui lòng bật F12 trên Chrome/Firefox và chuyển sang Tab Console để thấy kết quả)

1. Lấy giá trị của thẻ HTML chỉ định

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
</head>
<body>
	<div>
		<p id="id_cua_toi">Hãy đọc tôi đi.</p>
	</div>
	<script type="text/javascript">
	var element = document.getElementById('id_cua_toi');
	console.log(element);
	console.log(element.innerHTML);
	</script>
</body>
</html>

Kết quả:

<p id="id_cua_toi">Hãy đọc tôi đi.</p>
Hãy đọc tôi đi.
  • Qua ví dụ trên, để có thể đọc dữ liệu của thẻ “p” bên trong thẻ “div” hay bất cứ thẻ nào bao quanh nó. Chúng ta cần đặt cho nó một “id” không được trùng lắp trong Website. Giống như việc bạn dùng số CMND thì chỉ có 1 mình bạn có số đó mà thôi.
  • Và khi tôi dùng hàm “document.getElementById()” và truyền vào cho nó “id” của vùng cần lấy, các bạn sẽ thấy tôi đã lấy được cả dữ liệu toàn bộ thẻ “p” mà chúng ta đã định nghĩa “id”. Và để lấy giá trị bên trong thẻ “p” thì chúng ta chỉ cần truy cập tới phương thức “innerHTML” là có thể lấy được dữ liệu như mong muốn.

Ghi chú

  • Hàm: document.getElementById(id)
  • Đối số:
  1.             Id: tên của thẻ HTML được ấn định HTML
  • Mức độ phổ biến: rất thông dụng
  • Thực tế: được dùng rất nhiều để có thể bắt được dữ liệu như mong muốn trong tài liệu HTML.

2. Thay đổi giá trị của thẻ HTML chỉ định

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
</head>
<body>
	<div>
		<p id="id_cua_toi">Hãy đọc tôi đi.</p>
	</div>
	<script type="text/javascript">
	var element = document.getElementById('id_cua_toi');
	element.innerHTML = '<strong>Tôi đã bị ghi đè.</strong>';
	console.log(element);
	console.log(element.innerHTML);
	</script>
</body>
</html>

Kết quả:

<p id="id_cua_toi"><strong>Tôi đã bị ghi đè.</strong></p>
<strong>Tôi đã bị ghi đè.</strong>
  • Sau khi thực nghiệm ví dụ trên, các bạn đã thấy chuỗi “Hãy đọc tôi đi” đã bị ghi đè thành “<strong>Tôi đã bị ghi đè.</strong>” thông qua phương thức “innerHTML” mà chúng ta đã dùng ở ví dụ trước đó và gán cho nó giá trị mới giúp thay đổi dữ liệu của thẻ do chúng ta định nghĩa “id” cho nó trong HTML.
  • Đồng thời, chuỗi “Tôi đã bị ghi đè” do ảnh hưởng của thẻ HTML và cụ thể ở đây là “<strong>” giúp cho chuỗi của chúng ta in đậm bên ngoài màn hình. Nhưng khi chúng ta nhận dữ liệu từ Console thì nó cũng sẽ bao gồm luôn thẻ HTML của chúng ta.

3. Hiển thị thời gian máy tính

Trong ví dụ này, chúng ta sẽ cùng xem cách hiển thị thời gian bằng JS được thực hiện như thế nào nhé.

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
</head>
<body>
	<div id="dongho"></div>
	<script type="text/javascript" charset="utf-8">
		var date = new Date();
		var gio = date.getHours();
		var phut = date.getMinutes();
		var giay = date.getSeconds();
		//Lấy giờ hệ thống hiện tại
		document.getElementById('dongho').innerHTML = gio + ':' + phut + ':' + giay;
	</script>		
</body>
</html>

Kết quả:

14:36:46
  • Để có thể hiển thị thời gian, chúng ta cần khởi tạo đối tượng “Date” để có thể sử dụng được những phương thức lấy thời gian như “getHours(), getMinutes(), getSeconds()…”. Sau đó, chúng ta sẽ tìm thẻ có “id” chỉ định để hiển thị vào đúng nơi chúng ta cần.

Tuy nhiên khi các bạn chạy thử ví dụ này, các bạn sẽ thấy rằng thời gian chúng ta bắt được chỉ là thời gian tĩnh và được chạy lúc ta khởi chạy website, nó không tự động chạy như thời gian trên hệ thống của chúng ta. Vậy làm sao để có thể làm được điều đó? Hãy theo dõi cách sau:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
</head>
<body>
	<div id="dongho"></div>
	<script type="text/javascript" charset="utf-8">
		//Lấy giờ hệ thống liên tục
		setInterval(function() {
			var date = new Date();
			var gio = date.getHours();
			var phut = date.getMinutes();
			var giay = date.getSeconds();
			document.getElementById('dongho').innerHTML = gio + ':' + phut + ':' + giay;
		}, 1000);
	</script>		
</body
</html>
  • Kết quả sẽ không khác ví dụ trên, nhưng các bạn sẽ thấy thời gian của chúng ta được cập nhật liên tục theo hệ thống cứ mỗi “1000ms” (1 giây) thông qua hàm “setInterval()” mà chúng ta được học trong Ví dụ này. Và hàm này có cách viết rất giống bài học Anonymous Function và Closure mà chúng ta đã được học trước đó. Đồng thời đối số thứ 2 của hàm “setInterval()” đó chính là thời gian hàm được gọi lại mỗi lần.
  • Tuy nhiên nếu như các bạn tinh mắt, có thể sẽ thấy khi chúng ta vừa vào website thì chúng ta sẽ thấy nó có một khoảng thời gian bị trì hoãn trước khi website có thể cập nhật thời gian cho chúng ta. Đó là bởi vì hàm “setInterval()” chỉ gọi hàm dùng để cập nhật thời gian của chúng ta sau một thời gian mà ta đã ấn định trước đó.

 

Ngoài ra, chúng ta còn có cách ghi khác và cách truyền đối số vào trong hàm khi được gọi bởi hàm “setInterval()”. Nhưng phạm vi của biến khi được truyền vào trong hàm chắc hẳn sẽ khiến nhiều bạn bỡ ngỡ:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
</head>
<body>
	<div id="dongho"></div>
	<script type="text/javascript" charset="utf-8">
		//Lấy giờ hệ thống liên tục
		var so_lan_goi = 0;
		var bien_ben_ngoai = 0;
		function dong_ho(ten_bat_ky, so_lan_goi) {
			so_lan_goi++;
			bien_ben_ngoai++;
			var date = new Date();
			var gio = date.getHours();
			var phut = date.getMinutes();
			var giay = date.getSeconds();
			document.getElementById('dongho').innerHTML = gio + ':' + phut + ':' + giay;
			console.log(ten_bat_ky);
			console.log('Số lần gọi: ' + so_lan_goi);
			console.log('Biến bên ngoài: ' + bien_ben_ngoai);

		}
		setInterval(dong_ho, 1000, 'Các bạn có thể đặt tên biến bất kỳ', so_lan_goi);
	</script>		
</body>
</html>

Hãy chạy thử và cảm nhận, các bạn sẽ thấy rất bất ngờ đấy. Bởi vì kết quả trả về cho chúng ta sẽ có nội dung như sau:

Các bạn có thể đặt tên biến bất kỳ
Số lần gọi: 1
Biến bên ngoài: 1
Các bạn có thể đặt tên biến bất kỳ
Số lần gọi: 1
Biến bên ngoài: 2
…
  • Như các bạn thấy, việc truyền đối số vào bên trong hàm được gọi bởi hàm “setInterval()” rất đơn giản và chúng ta chỉ cần đặt tên biến bất kỳ bên trong hàm được gọi theo thứ tự được truyền vào. Nhưng khi sử dụng các biến thì chỉ có biến “bien_ben_ngoai” là bị tác động khi hàm “dong_ho()” được gọi bởi hàm “setInterval()”, còn số lần gọi, bởi vì cứ sau một thời gian thì hàm “setInterval” lại lấy giá trị như ban đầu để truyền vào vì thế giá trị hoàn toàn không thay đổi. Nếu như các bạn không nhớ rõ, hãy xem lại bài viết Phạm vi hoạt động của biến và Anonymous Function và Closure để nắm rõ kiến thức hơn.
  • So với “bien_ben_ngoai” do được định nghĩa là biến toàn cục và được sử dụng trực tiếp bên trong hàm “setInterval()” nên hoàn toàn có thể tác động.

Ghi chú

  • Hàm: setInterval(function, timer, params…)
  • Đối số:
  1.       function: tên của hàm(Không bọc trong nháy như thế này “day_la_ten_ham” và nên nhớ không có 2 dấu “()” ở sau tên hàm) hoặc anonymous function/closure.
  2.       timer: thời gian thực thi lại hàm.
  3.       params: đối số cần truyền vào hàm theo thứ tự và sẽ nhận lại bên trong hàm cũng theo thứ tự như ta đã truyền vào.
  • Mức độ phổ biến: Ít
  • Thực tế: thường sử dụng khi cập nhật thời gian hoặc các chức năng cần thời gian để thực hiện lại như reload chatbox, refresh top bài viết bằng AJAX.

4. Tìm hiểu hàm “setTimeout()”

Ở phần trước, chúng ta đã tìm hiểu về hàm “setInterval()”, dùng để thực hiện công việc nào đó cần lặp lại liên tục trong một khoảng thời gian được chỉ định. Vậy một câu hỏi đặt ra là “chúng ta có thể thực hiện công việc nào đó trong thời gian chỉ định và thực hiện chỉ một lần duy nhất hay không?” thì câu trả lời sẽ là “Có!” và đó chính làm hàm “setTimeout()” bên trong Javascript (JS).

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>Demo Javascript</title>
</head>
<body>
	<button type="button" onclick="hen_gio();">Hẹn giờ</button>
	<input type="text" id="thoi_gian" value="3000" placeholder="Nhập thời gian mili-giây">mili-giây
	<script type="text/javascript" charset="utf-8">
		function hen_gio() {
			var thoi_gian = document.getElementById('thoi_gian');
			setTimeout(function() {
				alert('Hello World!');
			}, thoi_gian.value);
		}
	</script>		
</body>
</html>

Như vậy, chắc phần nào các bạn đã hiểu được công dụng của nó đúng không nào. Nó chỉ thực hiện một công việc nào đó sau khoảng thời gian được ấn định trước đó và chỉ thực hiện một lần. Và cách dùng nó hoàn toàn giống với phần trước mà chúng ta đã xem, nên các bạn có thể thử truyền đối số hoặc sử dụng các cách gọi hàm mà trước đó chúng ta đã làm với “setInterval()”.Ví dụ trên khi các bạn chạy, các bạn sẽ thấy có một nút nhấn “Hẹn giờ”. Và khi các bạn nhấn vào nút này, sau một khoảng thời gian đã ấn định trước đó. Các bạn sẽ thấy thông báo “Hello World!” được hiện lên và khi các bạn tắt đi thì hành động hiển thị thông báo không còn hiển thị nữa, nhưng nếu các bạn thay thế nó thành hàm “setInterval()” các bạn sẽ thấy nó được gọi mãi mãi cho đến khi các bạn tắt Website.

Ghi chú

  • Hàm: setTimeout(function, timer, params…)
  • Đối số:
  1.             function: tên của hàm(Không bọc trong nháy như thế này “day_la_ten_ham” và nên nhớ không có 2 dấu “()” ở sau tên hàm) hoặc anonymous function/closure.
  2.             Timer: thời gian thực thi lại hàm.
  3.             Params: đối số cần truyền vào hàm theo thứ tự và sẽ nhận lại bên trong hàm cũng theo thứ tự như ta đã truyền vào.
  • Mức độ phổ biến: Ít
  • Thực tế: thường sử dụng khi dùng để trì hoãn thời gian gọi AJAX mỗi lần ở các chức năng search, giúp giảm tải cho server khi cứ mỗi kí tự thêm vào thì chúng ta đều gửi lên server thì không được tối ưu.

Cuối cùng, chúng ta cũng đã kết thúc được bài học về Javascript và HTML DOM trong bài viết này. Ở bài học sau, chúng ta sẽ cùng Tìm hiểu sự kiện trong Javascript như thế nào nhé.

Bài 6: Anonymous Function và Closure

Trong bài viết trước, khi tìm hiểu về cách viết Hàm trong Javascript , các bạn sẽ thấy rằng nó hoàn toàn không khác gì các ngôn ngữ phổ biến như C++, C#, Java…nhưng trong nó còn hỗ trợ một cách viết khác cũng không kém phần thú vị và nó có tên gọi là Anonymous Function, tuy nhiên ở một số trường hợp nó lại trở thành khái niệm khác và có tên gọi là Closure. Vậy do đâu mà có sự khác biệt như vậy giữa Anonymous Function va Closure? Các bạn hãy cùng tìm hiểu với tôi nhé.

Anonymous Function và Closure

 

Bài viết đang củng cố lại học thuật, vì có kiến thức lúc tác giả viết bài này vẫn chưa chính xác. Độc giả vui lòng quay lại khi khác. Xin cám ơn các bạn độc giả đã quan tâm.

Để giải thích các khái niệm này và hiểu được nó sẽ mất rất nhiều thời gian của các bạn. Tuy nhiên, các bạn có thể hiểu đơn giản như sau:

Anonymous Function (Hàm vô danh)

<script type="text/javascript">
	var func = function() {
		alert("Hello");
	}
	func();
</script>

Kết quả:

Hello (Hiển thị hộp thoại)

Closure (Bao đóng)

(Vui lòng bật F12 trên Chrome/Firefox và chuyển sang Tab Console để thấy kết quả)

<script type="text/javascript">
	var action = 'Hello';
	var closure = function(name) {
		console.log(action + ' ' + name);
	}
	closure('Andy Vũ');
</script>

Kết quả:

Hello Andy Vũ

Khi đến với 2 kiểu dữ liệu cuối cùng, chắc hẳn các bạn sẽ có nhiều thắc mắc về nó rất nhiều. Vậy đâu là sự khác biệt giữa Anonymous Function và Closure?

Anonymous Function thực chất chỉ là một hàm không có tên gọi, thường được sử dụng khi xử lý các công việc có quy mô nhỏ, vì thế không cần thiết phải khởi tạo tên định danh cho hàm này. Giúp nó có tốc độ xử lý nhanh hơn hàm truyền thống phải có tên định danh.

Closure có các tính chất của Anonymous Function đó chính là không cần tên định danh cho nó. Nhưng để được gọi là Closure thì trong nó phải sử dụng ít nhất là một biến không phụ thuộc vào phạm vi hàm mà chúng ta định nghĩa.

Hãy xem qua 3 ví dụ chi tiết sau đây:

VD 1: Các trường hợp của Anonymous Function

<script type="text/javascript">
	//Anonymous Function có đối số
	var anonymous = function(a, b) {
		return a + b;
	};
	console.log(anonymous(5, 10));
	//Anonymous Function không có đối số
	var anonymous = function() {
		return "Hello World";
	};
	console.log(anonymous());
</script>

Kết quả:

15
Hello World!

Qua ví dụ trên, bạn đã phần nào hiểu rõ về Anonymous Function rồi có đúng không? Nó chỉ được gọi là Anonymous Function khi nó không sử dụng biến nào bên ngoài hàm hay nói cách khác là không được phép sử dụng biến toàn cục trong hàm này.

VD 2: Các trường hợp của Closure

1. Kết hợp Anonymous Function và Closure

<script type="text/javascript">
	//Kết hợp Anonymous Function và Closure
	var anonymous = function() {
		var a = 'A thuộc Anonymous Function';
		var closure = function() {
			var b = 'B thuộc Closure';
			console.log(a);
			return b;
		}	
		console.log(closure());
		b = 'B thuộc Anonymous Function';
		console.log(closure());
		console.log(b);
	};
	anonymous();
</script>

Kết quả:

A thuộc Anonymous Function
B thuộc Closure
A thuộc Anonymous Function
B thuộc Closure
B thuộc Anonymous Function
  • Biến “anonymous” được xem là Anonymous Function bởi vì chính nó không dùng biến bên ngoài hàm được định nghĩa.
  • Biến “closure” được xem là “Closure” bởi vì nó đã sử dụng biến “a” (Biến toàn cục trong hàm “anonymous”) thuộc “anonymous” có phạm vi ảnh hưởng rộng hơn trong “closure” cho phép “closure” có thể gọi giá trị bên ngoài và tác động đến giá trị đó, cụ thể ở đây là biến “a”.
  • Biến “b” trong “closure” được định nghĩa trong phạm vi của “closure” vì thế, nếu nó được dùng trong “anonymous” tức là bên ngoài “closure” sẽ không được phép truy cập vào hoặc tác động được vào giá trị của nó.
  • Biến “b” trong “anonymous” được định nghĩa là biến toàn cục (khi không có từ khóa “var”) có thể được truy xuất ở nơi không được định nghĩa lại biến “b” như trong “closure” đã định nghĩa biến “b” như trước đó. Và nó có thể cho phép truy xuất cả bên ngoài “anonymous” mà không gặp bất cứ lỗi nào. Đó là một trong những vấn đề rất quan trọng khi dùng từ khóa “var” và khi không dùng từ khóa “var”. Vì thế các bạn đã thấy biến “b” trong “closure” và biến “b” ở “anonymous” được định nghĩa lại hoàn toàn không tác động gì được trong phạm vi của “closure”. Các bạn có thể xem ví dụ về vấn đề này rõ hơn ở Ví dụ bên dưới.

2. Phạm vi của biến trong và ngoài Closure

<script type="text/javascript">
	//Closure
	var c = 'C là biến toàn cục';
	var closure = function() {
		c = 'C đã bị ảnh hưởng bởi Closure';
		var d = 'D thuộc Closure';
		var child_closure = function() {
			c = 'C đã bị ảnh hưởng bởi Child Closure';
			d = 'D đã bị ảnh hưởng bởi Child Closure';
			return c;
		}	
		console.log(child_closure());
		return d;		
	}
	console.log(closure());
	console.log(c);
	console.log(d);
</script>

Kết quả:

C đã bị ảnh hưởng bởi Child Closure
D đã bị ảnh hưởng bởi Child Closure
C đã bị ảnh hưởng bởi Child Closure	
Uncaught ReferenceError: d is not defined
  • Như ví dụ bên trên mà tôi đã viết, các bạn sẽ thấy được rõ ràng phạm vi của biến được sử dụng trong ví dụ này.
  • Trong đó, biến “c” được định nghĩa là biến toàn cục thay vì cục bộ trong một hàm cho dù nó có từ khóa “var” bởi vì nó đã được định nghĩa bên ngoài tất cả các hàm bao hàm lấy nó, nên nó cũng được xem là biến toàn cục trong trường hợp này.
  • Và khi biến “c” được tác động trong “closure”, nó cũng sẽ thay đổi giá trị của biến “c” bên ngoài nó bởi vì nó là biến toàn cục.
  • Biến “d” được khởi tạo trong “closure” chỉ được hiểu trong phạm vi của “closure” nên vì thế các bạn sẽ thấy lỗi khi chạy đoạn chương trình tôi cung cấp, vì nó không tìm thấy biến “d” ở phạm vi ngoài “closure”.
  • Tương tự với hàm “child_closure”, nó cũng đã sử dụng biến bên ngoài phạm vi của nó đó chính là biến “c” toàn cục và biến “d” ở “closure”. Và khi đó, biến “d” nằm trong phạm vi của “closure” và khi đó “child_closure” cũng nằm trong phạm vi của “closure” vì thế biến “d” hoàn toàn cũng được phép truy cập vào biến “d” của “closure” và thay đổi giá trị của nó.

Qua các ví dụ trên, chắc hẳn nếu bạn nào vẫn còn bối rối với phạm vi của biến có từ khóa “var” và không có từ khóa “var” hoặc với phạm vi của “Closure”. Tôi đề nghị các bạn nên thử cách viết và cách sử dụng biến trong Javascript để có thể hiểu rõ về nó hơn thay vì chỉ đọc và ngẫm. Như vậy bạn sẽ có trải nghiệm về nó một cách chính xác hơn.

Sau khi tìm hiểu về Anonymous Function và Closure trong Javascript (JS) chắc hẳn các bạn đã thấy được nhiều điều thú vị từ nó. Trong các bài viết sau, chúng ta sẽ tập trung vào tìm hiểu Javascript và HTML DOM cũng như các ví dụ thực tế và một số thủ thuật khi viết code trong Javascript và giải đáp thắc mắc một số cách ghi tắt trong Javascript.

Bài 5: Hàm trong Javascript

Như vậy, sau khi trải qua các bài học trước về Kiểu dữ liệuPhạm vi hoạt độngToán tử và Biểu thức trong Javascript (JS). Các bạn đã có những kiến thức nền tảng giúp cho việc lập trình sau này được bài bản và khoa học hơn. Đến với bài này, chúng ta cùng nhau tìm hiểu về Hàm trong Javascript.

Hàm trong Javascript

Hàm trong Javascript

Hàm hay chương trình con giúp chúng ta có thể thực hiện những công việc nào đó mà ta đã xây dựng sẵn, nó được dùng khi chúng ta xây dựng thư viện hay đệ quy. Giúp gói gọn những công việc mà chúng ta có nhu cầu sau này sử dụng lại.

Cú pháp

<script type="text/javascript">
	//Hàm không cần giá trị trả về 
	function tenFunction(doiSo1, doiSo2, ...) {
		//Công việc cần xử lý
	}

	//Hàm cần giá trị trả về
	function tenFunction(doiSo1, doiSo2, ...) {
		return giaTriTraVe;
	}
</script>
  • Khi định nghĩa hàm, chúng ta sẽ có hai lựa chọn đó là hàm trả về hay hàm không trả về giá trị.

 

Ví dụ

Trường hợp 1:

(Vui lòng bật F12 trên Chrome/Firefox và chuyển sang Tab Console để thấy kết quả)

<script type="text/javascript">
	var a = 5;
	var b = 10;
	function cong(a, b) {
		return a + b;
	}
	var c = cong(a,b);
	console.log(c);
</script>

Kết quả:

15

Trường hợp 2:

<script type="text/javascript">
	var a = 5;
	var b = 10;
	function cong(a, b) {
		c = a + b;
		console.log('Hello World!');
	}
	cong(a,b);
	console.log(c);
</script>

Kết quả:

Hello World!
15
  • Sau 2 trường hợp kể trên, các bạn thấy rằng trong trường hợp 1 chúng ta có thể dùng hàm “cong()” với 2 đối số là “a” và “b”. Và hàm này đơn giản là khi ta dùng hàm này và truyền các đối số vào tương ứng cho hàm “cong()” thì nó sẽ thực hiện phép cộng mà ta đã viết bên trong nó. Sau đó, để có thể lưu lại giá trị mà chúng ta đã cộng thì chúng ta cần dùng 1 biến khác bên ngoài hàm “cong()” và nó sẽ lưu lại giá trị từ hàm “cong()” của chúng ta trả về khi chúng ta dùng từ khóa “return”.
  • Với trường hợp 2, hàm “cong()” vẫn thực hiện việc cộng như trên và dùng biến “c” là biến toàn cục để lưu lại giá trị khi chúng ta sử dụng hàm “cong()”, sau đó chúng ta đơn giản chỉ hiển thị một chuỗi “Hello World!” ra ngoài màn hình. Như vậy các bạn thấy, rõ ràng chúng ta không cần giá trị trả về với hàm này. Vì chúng ta đã lưu giá trị cộng vào biến “c” toàn cục và chúng ta còn có thể hiển thị một chuỗi nào đó hoặc hành động bất kì mà không cần thiết phải có giá trị trả về.

Câu hỏi: Khi nào thì chúng ta nên dùng hàm trả về? Và khi nào dùng hàm không trả về?

Trả lời:

  • Tùy mục đích sử dụng của lập trình viên mà chúng ta sẽ quyết định nên viết hàm như thế nào. Ví dụ chúng ta muốn lập trình ra một hàm và nó có mục đích rõ ràng ví dụ như “cộng, trừ, nhân, chia” hay các mục đích xử lý dữ liệu được chỉ định rõ ràng nào khác thì lúc đó chúng ta cần giá trị trả về.
  • Còn khi chúng ta muốn viết một hàm có khả năng thực hiện nhiều công việc bên trong nó, giống như việc bạn lên lịch để thực hiện công việc trong ngày được gói gọn trong một cuốn sổ tay và khi bạn thực hiện có phải bạn sẽ làm theo thứ tự từng việc được sắp xếp sẵn trong ngày cho đến hết đúng không nào.
  • Vì thế hãy suy nghĩ thật kĩ khi viết để tránh các trường hợp viết quá nhiều hàm nhưng chức năng không rõ ràng sẽ gây bất lợi cho bạn trong việc sử dụng lại chính thư viện của mình sau này.

Trong bài học sau, chúng ta sẽ cùng tìm hiểu về Anonymous Function và Closure. Đây là 2 khái niệm rất phổ biến trong thời buổi công nghệ hiện nay, giúp cho việc lập trình của chúng ta nhanh chóng, hiệu quả và dễ hiểu hơn rất là nhiều.

Bài 4: Biểu thức trong Javascript

Biểu thức trong Javascript

Ở bài trước chúng ta đã học qua Toán tử trong Javascript, chắc hẳn các bạn cũng đang rất hứng thú khi tìm hiểu về cách sử dụng toán tử so sánh và logic rồi ? Trong bài này, chúng ta sẽ cùng nhau tìm hiểu về các biểu thức trong Javascript được sử dụng như thế nào nhé.

Biểu thức “If…Else”

Được dùng để so sánh các điều kiện, nếu thoả sẽ thực hiện công việc nào đó. Nếu sai và được lập trình viên định nghĩa thì nó cũng sẽ thực thi công việc nào đó mà lập trình viên mong muốn.

Cú pháp

<script type="text/javascript">
	if (Điều kiện 1) {
		//Nếu điều kiện 1 thoả thì thực hiện
	} else if (Điều kiện n) {
		//Nếu điều kiện n thoả thì thực hiện
	} else {
		//Nếu tất cả điều kiều trên đều sai thì thực hiện
	}
</script>

Với điều kiện “Else if” không cần phải có trong biểu thức “If…Else” nếu như các bạn không có nhu cầu kiểm tra thêm các điều kiện khác trước khi “Else” được gọi vì các điều kiện sai hoàn toàn. Và “Else” cũng không cần thiết nếu như các bạn chỉ cần điều kiện “If” hoạt động.

Ví dụ

(Vui lòng bật F12 trên Chrome/Firefox và chuyển sang Tab Console để thấy kết quả)

<script type="text/javascript">
	var a = 5;
	var b = 10;
	//Trường hợp 1
	if (a < b) {
		console.log('Thoả điều kiện a < b');
	}

	//Trường hợp 2
	if (a > b) {
		console.log('Thoả điều kiện a > b');
	}

	//Trường hợp 3
	if (a > b) {
		console.log('Thoả điều kiện a > b');
	} else {
		console.log('Không thoả điều kiện a > b');
	}

	//Trường hợp 4
	if (a > b) {
		console.log('Thoả điều kiện a > b');
	} else if (a < b) {
		console.log('Không thoả điều kiện a > b nhưng thoả a < b');
	} else {
		console.log('Các điều kiện trên không thoả');
	}
</script>

Kết quả:

Thoả điều kiện a < b
Không thoả điều kiện a > b
Không thoả điều kiện a > b nhưng thoả a < b
  • Sau khi thực nghiệm ví dụ trên, ta thấy cách sử dụng trường hợp 1 và 2 chỉ chạy khi nào thoả điều kiện và trong đó trường hợp 2 đã không được chạy vì đã không thoả điều kiện. Trường hợp 3, do điều kiện đầu không thoả lập tức nó sẽ chạy “Else”. Còn với trường hợp 4, chúng ta xét thêm 1 điều kiện nữa bổ sung cho điều kiện đầu nếu điều kiện đó sai và nó đã thoả điều kiện thứ 2 và chạy. Và trường hợp cuối là nếu như các điều kiện đầu và bổ sung đều sai thì sẽ chạy ngày “Else” như trường hợp 3.

Lưu ý: “Else if” được phép định nghĩa nhiều lần trong “if…else”. Cú pháp như sau:

<script type="text/javascript">
	if (Điều kiện 1) {
		//Thoả điều kiện 1
	} else if (Điều kiện 2) {
		//Thoả điều kiện 2
	} else if (Điều kiện n) {
		//Thoả điều kiện n
	} ...else {
		//Không hoả điều kiện
	}
</script>

Biểu thức “switch…case”

Được dùng trong trường hợp các điều kiện đều so sánh “=” và nếu thoả sẽ thực hiện các công việc trong đó.

Cú pháp

<script type="text/javascript">
	switch (Giá trị cần so sánh) {
		case 'Điều kiện 1':
			break;
		case 'Điều kiện 2':
			break;
		...
		case 'Điều kiện n':
			break;
		default:
			break;
	}	
</script>
  • Cú pháp trên sẽ rất lạ nếu như người học chưa từng lập trình qua ngôn ngữ lập trình nào. Khi sử dụng “switch…case” thì khi thoả điều kiện, chúng ta cần đến từ khoá “break” để ngừng công việc so sánh lại khi đã thực hiện xong công việc trên, nếu không vô tình nó sẽ chạy luôn công việc của điều kiện bên dưới nếu còn và nó sẽ bỏ qua kiểm tra là có thoả điều kiện hay không. Và từ khoá “default” được dùng trong trường hợp các điều kiện bên trên không thoả điều kiện nào.

Ví dụ

Trường hợp 1:

<script type="text/javascript">
	var a = 2;
	switch (a) {
		case 1:
			console.log('Thoả điều kiện a == 1');
			break;
		case 2:
			console.log('Thoả điều kiện a == 2');
			break;
		case "Hello":
			console.log('Thoả điều kiện a == "Hello"');
			break;
		default:
			console.log('Không thoả điều kiện nào');
			break;
	}	
</script>

Kết quả:

Thoả điều kiện a == 2
  • Trong trường hợp đầu tiên, chúng ta thấy rằng “switch…case” cũng giống như việc chúng ta sử dụng “if (a == 2)” nhưng trong “switch…case” thì là “case 2”. Rất đơn giản đúng không nào?

Trường hợp 2:

<script type="text/javascript">
	var a = "Hello";
	switch (a) {
		case 1:
			console.log('Thoả điều kiện a == 1');
			break;
		case 2:
			console.log('Thoả điều kiện a == 2');
			break;
		case "Hello":
			console.log('Thoả điều kiện a == "Hello"');			
		case "World":
			console.log('Thoả điều kiện a == "World"');
		default:
			console.log('Không thoả điều kiện nào');
			break;
	}	
</script>

Kết quả:

Thoả điều kiện a == "Hello"
Thoả điều kiện a == "World"
Không thoả điều kiện nào
  • Như vậy, khi thử nghiệm trường hợp 2. Các bạn đã thấy được sự nguy hiểm khi không dùng đến từ khoá “break” trong “switch…case” chưa nào. Nó sẽ bỏ qua tất cả các điều kiện sau khi thoả điều kiện đầu và sẽ không dừng lại cho đến khi nó gặp từ khoá “break” hoặc “switch…case” đó không còn điều kiện nào nữa cả.

Trường hợp 3:

<script type="text/javascript">
	var a = "999";
	switch (a) {
		case 1:
			console.log('Thoả điều kiện a == 1');
			break;
		case 2:
			console.log('Thoả điều kiện a == 2');
			break;
		case "Hello":
			console.log('Thoả điều kiện a == "Hello"');			
		case "World":
			console.log('Thoả điều kiện a == "World"');
		default:
			console.log('Không thoả điều kiện nào');
			break;
	}	
</script>

Kết quả:

Không thoả điều kiện nào
  • Trong trường hợp cuối cùng và cũng là trường hợp dễ dàng nhất khi các bạn đã hiểu qua “if…else” rồi thì trong “switch…case” nó cũng tương tự như vậy mà thôi.

Kết thúc bài học này, các bạn đã hiểu rõ được cách sử dụng biểu thức trong javascript rồi, có đúng không nào? Thật dễ dàng như việc chúng ta đang hỏi một đứa bé là “Một có lớn hơn hai không?(If 1 > 2) Nếu không thì làm sao cho nó lớn hơn? (Else)”. Ở bài học sau, chúng ta sẽ được tìm hiểu đến với “Hàm trong Javascript” hay “Chương trình con trong Javascript“.

Bài 3: Toán tử trong Javascript

Ở các bài học trước, chúng ta đã tìm hiểu về Kiểu dữ liệuPhạm vi hoạt động của biến trong Javascript. Tiếp nối bài học này, các bạn sẽ được biết qua về Toán tử trong Javascript được quy ước như thế nào?

Toán tử trong Javascript

 

Toán tử trong Javascript

 

Toán tử số học

(Vui lòng bật F12 trên Chrome/Firefox và chuyển sang Tab Console để thấy kết quả)

<script type="text/javascript">
	var a = 10;
	var b = 15;
	var c = 20;
	var d = c - b * a / 2;
	console.log(d);
</script>

Kết quả:

-55
  • Toán tử trong Javascript đều có sự tương đồng với các ngôn ngữ lập trình khác và vẫn tuân theo quy tắc toán học “Nhân chia trước, cộng trừ sau”.

Các bạn có thể xem chi tiết các toán tử của Javascript như sau:

+ Phép cộng
Phép trừ
* Phép nhân
/ Phép chia
% Phép chia lấy dư

Toán tử kết hợp

Toán tử kết hợp Ví dụ viết tắt Ví dụ đầy đủ
++ a++ a = a + 1
a– a = a – 1
+= a += 2 a = a + 2
-= a -= 2 a = a – 2
*= a *= 2 a = a * 2
/= a /= 2 a = a / 2
%= a %= 2 a = a % 2

Toán tử nối chuỗi (String)

<script type="text/javascript">
	var a = "Hello";
	var b = "World!";
	var c = a + " " + b;
	console.log();
</script>

Kết quả:

Hello World!
  • Sau khi thực hiện dòng lệnh như trên, bạn sẽ thấy cách nối chuỗi trong Javascript được thực hiện như thế nào. Thông qua việc sử dụng toán tử “+” để nối 2 chuỗi lại với nhau. Ở ví dụ bên trên còn cho chúng ta thấy được việc chúng ta không nhất thiết phải lưu trữ trong biến mới có thể nối chuỗi được mà chúng đã có thể viết chuỗi trực tiếp trong Javascript.

Trường hợp ngoại lệ

<script type="text/javascript">
	var a = "Hello" + 5;
	var b = "100" + 5;
	var c = 5 + 10 + "Hello";
	var d = 5 + "Hello" + 10;
	var e = "Hello" + 5 + 10;
	console.log(a);
	console.log(b);
	console.log(c);
	console.log(d);
	console.log(e);
</script>

Kết quả:

Hello5
1005
15Hello
5Hello10
Hello510
  • Qua 5 ví dụ đơn giản như trên, nếu như chúng ta sử dụng toán tử “+” theo thứ tự “Chuỗi + Số” thì số cũng sẽ được xem là chuỗi và nó sẽ thực hiện thao tác nối chuỗi như bình thường. Tuy nhiên ở ví dụ biến “c” chúng ta sẽ thấy được độ ưu tiên khi sử dụng toán tử là từ trái sang phải, nếu bên trái toán tử “+” và phải của toán tử “+” đều là số thì nó sẽ thực hiện phép tính trước và sau đó dùng toán tử “+” để nối chuỗi với chuỗi phía sau nó. Tương tự các ví dụ còn lại, các bạn hãy tự viết lại để nhìn nhận ra vấn đề rõ ràng hơn.

Toán tử so sánh

> Lớn hơn
< Nhỏ hơn
>= Lớn hơn hoặc bằng
<= Nhỏ hơn hoặc bằng
== Bằng
!= Không bằng
=== Bằng và giống kiểu dữ liệu
!=== Không bằng và không giống kiểu dữ liệu

Toán tử Logic

Toán tử Logic True (Đúng) False (Sai)
&& Cả 2 vế trái và phải đúng 1 trong 2 vế trai hoặc phải sai
|| 1 trong 2 vế trái hoặc phải đúng Cả 2 vế trái và phải sai
! Phủ định của False Phủ định của True

Trong bài này, “Toán tử so sánh” và “Toán tử Logic” các bạn nên tham khảo qua. Trong bài Biểu thức trong Javascript, tôi sẽ nói tiếp về các biểu thức “If…Else”, “Switch…case”. Lúc đó các bạn sẽ dần hiểu rõ nó hơn.

Bài 2: Phạm vi hoạt động của biến trong Javascript

Phạm vi hoạt động của biến trong Javascript

Phạm vi hoạt động của biến trong Javascript

Ở bài Tìm hiểu kiểu dữ liệu trong Javascript chúng ta đã được biết qua cách để khai báo và sử dụng Javascript rồi. Trong đó, chúng ta cũng tìm hiểu sơ lược về các kiểu dữ liệu phổ biến bên trong Javascript cũng như đại đa số các ngôn ngữ lập trình khác đều có. Thì trong bài học này, chúng ta sẽ tìm hiểu về phạm vi hoạt động của biến.

Continue reading Bài 2: Phạm vi hoạt động của biến trong Javascript

Bài 1: Tìm hiểu kiểu dữ liệu trong Javascript

Giới thiệu và tìm hiểu kiểu dữ liệu trong Javascript

Giới thiệu và tìm hiểu kiểu dữ liệu trong Javascript

  • JavaScript, theo phiên bản hiện hành, là một ngôn ngữ lập trình kịch bản dựa trên đối tượng được phát triển từ các ý niệm nguyên mẫu. Ngôn ngữ này được dùng rộng rãi cho các trang web, nhưng cũng được dùng để tạo khả năng viết script sử dụng các đối tượng nằm sẵn trong các ứng dụng. Nó vốn được phát triển bởi Brendan Eich tại Hãng truyền thông Netscape với cái tên đầu tiên Mocha, rồi sau đó đổi tên thành LiveScript, và cuối cùng thành JavaScript. Giống Java, JavaScript có cú pháp tương tự C, nhưng nó gần với Self hơn Java. .js là phần mở rộng thường được dùng cho tập tin mã nguồn JavaScript.
  • Phiên bản mới nhất của JavaScript là phiên bản 1.5, tương ứng với ECMA-262 bản 3. ECMAScript là phiên bản chuẩn hóa của JavaScript. Trình duyệt Mozilla phiên bản 1.8 beta 1 có hỗ trợ không đầy đủ cho E4X – phần mở rộng cho JavaScript hỗ trợ làm việc với XML, được chuẩn hóa trong ECMA-357.

(Theo Wikipedia)

Cách khai báo Javascript

Javascript có thể thực thi thông qua cách viết sau trong HTML:

<script type=”text/javascript”>
	//Đoạn code cần thực thi
	alert(“Hello World!”);
</script>

Đoạn code trên sẽ hiển thị thông báo với dòng chữ “Hello World!” đã được định nghĩa.

Ngoài ra, Javascript còn được thực thi những dòng lệnh thông qua cách triệu gọi file Javascript được viết trước đó và lưu vào một file riêng với định dạng “.js”. Và cách gọi file Javascript sẽ được viết như sau:

<script type="text/javascript" src="http://www.TenWebsite.com/ThuMucChuaFile/TenFile.js"></script>

Câu hỏi: Vậy khi nào thì ta sử dụng cách viết trực tiếp trong HTML, khi nào thì ta nên viết trong file?

Trả lời: Khi cần thực hiện những công việc có quy mô và thời gian thực hiện ngắn thì chúng ta có thể viết trực tiếp trong HTML, nhưng ngược lại thì ta nên viết trong file và lưu lại như vậy sẽ tối ưu hơn.

Biến

Biến được dùng để lưu lại dữ liệu vào bộ nhớ nhằm xử lý một tác vụ nào đó. Và trong Javascript, biến có thể chứa nhiều kiểu dữ liệu khác nhau.

Cú pháp:

(Vui lòng bật F12 trên Chrome/Firefox và chuyển sang Tab Console để thấy kết quả)

<script type="text/javascript">
	var a = 'Hello World!';
	console.log(a);
</script>

Kết quả:

Hello World!

Định nghĩa một biến bằng từ khoá “var” và “tênBiến” và sau đó chúng ta có phép gán là “=” để gán giá trị cho biến vừa đặt.

  • Lưu ý thứ 1: javascript cho phép đặt tên biến không cần từ khoá “var”. Tuy nhiên, phạm vi hoạt động của tên biến sẽ không giống nhau.
  • Lưu ý thứ 2: “console.log()” được sử dụng trong các trình duyệt hiện đại sau này (Chrome, Firefox, Opera). Và được xuất ra trong Console chứ không phải trên màn hình trình duyệt.

Kiểu dữ liệu

Kiểu dữ liệu trong Javascript rất đa dạng, vì thế nó cũng ít nhiều gây khó khăn với những người mới khi bước chân sâu vào Javascript.

Kiểu Số:

<script type="text/javascript">
	var a = 5 + 10;
	console.log(a);
</script>

Kết quả:

15

Kiểu chuỗi:

<script type="text/javascript">
	var a = "Hello World!";
	console.log(a);
</script>

Kết quả:

Hello World!

Kiểu Mảng:

<script type="text/javascript">
	var a = [5, "Hello World!", 10];
	console.log('a[0]: ' + a[0]);
	console.log('a[1]: ' + a[1]);
	console.log('a[2]: ' + a[2]);
</script>

Kết quả:

a[0]: 5
a[1]: Hello World!
a[2]: 10

Kiểu đối tượng:

<script type="text/javascript">
	var giay = {
		color: 'red',
		size: 38,
		quantity: 2
	};
	console.log('Color: ' + giay.color);
	console.log('Size: ' + giay.size);
	console.log('Quantity: ' + giay.quantity);
</script>

Kết quả:

Color: red
Size: 38
Quantity: 2

Sau khi xem qua các kiểu dữ liệu cơ bản, chắc hẳn cũng khiến các bạn đôi phần thích thú về cách sử dụng giá trị bên trong Javascript rồi đúng không nào? Khá giống với cách sử dụng của PHP khi không cần phải định nghĩa chính xác kiểu biến được sử dụng (Integer, Float, Double…) như thế nào. Thay vào đó, chúng ta hoàn toàn có thể gán cho nó bất kể giá trị nào, kể cả một array, object hay thậm chí là function (Vấn đề này sẽ nói ở các bài học sau).

Trong bài sau, chúng ta sẽ đọc tiếp tới bài Phạm vi hoạt động của biến để có thể hiểu rõ hơn về cách sử dụng biến trong Javascript.