each jQuery là một phương thức được sử dụng phổ biến trong việc lặp qua mảng, đối tượng hoặc tập hợp các phần tử DOM. Với cú pháp đơn giản nhưng cực kỳ mạnh mẽ, each() giúp lập trình viên xử lý khối lượng dữ liệu lớn một cách hiệu quả, đồng thời vẫn giữ được sự ngắn gọn và dễ đọc trong đoạn mã.
Đọc bài viết sau để được giải đáp chi tiết hơn về:
- Cú pháp, công dụng và cách hoạt động của phương thức
each()
trong jQuery. - So sánh
$(‘selector ).each
và$.each()
trong jQuery. - Một số ví dụ cơ bản về
each()
trong jQuery. - So sánh JavaScript
.forEach()
và jQuery.each()
– khi nào nên dùng phương thức nào?
Tổng quan về phương thức each() trong jQuery
jQuery.each()
là một phương thức quan trọng của jQuery, được thiết kế để lặp qua một tập hợp các phần tử hoặc cấu trúc dữ liệu. jQuery cung cấp hai dạng each()
khác nhau:
$.each()
để lặp qua mảng và object$().each()
để lặp qua jQuery objects chứa các phần tử DOM
Dù bạn đang thao tác với phần tử DOM hay xử lý mảng và đối tượng, jQuery.each()
mang lại một cách tiếp cận đơn giản và hiệu quả để thực hiện các tác vụ này.
each() trong jQuery hoạt động như thế nào?
Hàm này nhận hai tham số: chỉ số (index) và giá trị (value) của phần tử hiện tại. Nhờ đó, bạn có thể thao tác với từng phần tử trong tập hợp, từ việc xử lý DOM cho đến xử lý dữ liệu.
Khi bạn gọi jQuery.each()
, nó sẽ xử lý từng phần tử trong tập hợp một cách tuần tự. Hàm callback bạn cung cấp sẽ được gọi một lần cho mỗi phần tử, với chỉ số và giá trị hiện tại được truyền vào dưới dạng tham số.
Trong callback function, từ khóa this
sẽ refer đến value của phần tử hiện tại. Cơ chế này cho phép bạn áp dụng thay đổi, tính toán kết quả, hoặc thực hiện hành động dựa trên nội dung của từng phần tử. Bạn có thể dừng vòng lặp sớm bằng cách return false
trong callback function.
Xem chi tiết: Những điều cần biết về jQuery – Thư viện Javascript hàng đầu
Tại sao each() trong jQuery được sử dụng nhiều?
Khi nói đến việc lặp qua các phần tử hoặc tập dữ liệu, jQuery.each()
nổi bật nhờ cú pháp trực quan và chức năng mạnh mẽ. Không giống như các vòng lặp truyền thống, each() tích hợp liền mạch với các phương thức chọn lọc của jQuery, mang lại cách viết ngắn gọn và sạch sẽ hơn để duyệt qua dữ liệu, giúp cải thiện khả năng đọc mã và giảm thiểu lỗi, trở thành lựa chọn phổ biến cho các lập trình viên hướng đến hiệu quả và rõ ràng.
Điểm nổi bật của phương thức này còn nằm ở sự linh hoạt, tương thích tốt với các trình duyệt cũ, đặc biệt trong thời kỳ jQuery phổ biến (2010-2015), each()
giải quyết vấn đề tương thích trình duyệt chéo (cross-browser compatibility) mà các phương thức native JavaScript như forEach()
chưa được hỗ trợ rộng rãi.
Tuy nhiên, với các dự án hiện đại, các phương thức native JavaScript (ES6+) như forEach()
, map() for...of
thường được ưu tiên hơn để tối ưu performance.
Các tham số (Parameters) trong each() jQuery
jQuery cung cấp hai dạng each()
với cú pháp khác nhau:
$.each() – Dành cho arrays và objects
$.each(collection, function(index, value) {
// Code của bạn ở đây
});
$().each() – Dành cho jQuery objects
$('selector').each(function(index, element) {
// Code của bạn ở đây
// this === element (DOM element)
});
Trong đó:
collection
có thể là một mảng hoặc một đối tượng.index
đại diện cho vị trí hiện tại (nếu là mảng) hoặc tên thuộc tính (nếu là đối tượng).value
là giá trị tương ứng.
Việc nắm vững cú pháp này là điều cần thiết để sử dụng hàm một cách hiệu quả.
Một trong những cách sử dụng phổ biến nhất của jQuery.each()
là duyệt qua các phần tử trong danh sách. Giả sử bạn có một danh sách không thứ tự (<ul>
) chứa nhiều mục (<li>
), và bạn muốn áp dụng một class cho từng mục. Với jQuery.each()
, bạn có thể lặp qua từng phần tử trong danh sách một cách hiệu quả và thao tác với từng phần tử đó.
Ví dụ thực tế
Ví dụ 1
Hãy tưởng tượng một tình huống bạn cần định dạng danh sách giá để hiển thị trên trang web. Bằng cách lặp qua một mảng chứa các mức giá, bạn có thể định dạng từng giá trị rồi chèn vào DOM:
var prices = [19.99, 29.99, 49.99];
$.each(prices, function(index, price) {
$('#price-list').append('<li>$' + price.toFixed(2) + '</li>');
});
Ví dụ này định dạng mỗi mức giá thành 2 chữ số thập phân và thêm chúng vào một danh sách không thứ tự (<ul>
).
Ví dụ 2
Bạn muốn xây dựng một thư viện ảnh hiển thị tốt trên mọi thiết bị, trong đó mỗi ảnh đi kèm với một chú thích. Bằng cách kết hợp jQuery.each()
với append()
, bạn có thể tạo các mục trong thư viện ảnh một cách linh hoạt:
var images = [
{src: 'img1.jpg', caption: 'Ảnh 1'},
{src: 'img2.jpg', caption: 'Ảnh 2'},
{src: 'img3.jpg', caption: 'Ảnh 3'}
];
$.each(images, function(index, image) {
$('#gallery').append(
'<div class="gallery-item">' +
'<img src="' + image.src + '" alt="' + image.caption + '">' +
'<p>' + image.caption + '</p>' +
'</div>'
);
});
Ví dụ trên giúp tạo ra các phần tử thư viện ảnh một cách động, kết hợp jQuery.each()
với thao tác thêm HTML vào DOM.
Sự khác nhau giữa $(‘selector ).each và $.each() trong jQuery
Trong jQuery, chúng ta thường bắt gặp hai cách sử dụng hàm each()
là $(‘selector’).each()
và $.each()
. Tuy cú pháp tương tự nhau, nhưng mục đích sử dụng và phạm vi áp dụng của chúng lại hoàn toàn khác nhau.
Hàm $(selector).each()
chỉ được dùng để lặp qua một đối tượng jQuery. Còn hàm $.each()
là một utility function (hay còn gọi là static method) của jQuery, có thể được sử dụng để lặp qua bất kỳ tập hợp nào, dù đó là một đối tượng hay một mảng.
Trong trường hợp là mảng, hàm callback
sẽ nhận vào chỉ số của mảng và giá trị tương ứng tại mỗi vòng lặp. Giá trị cũng có thể được truy cập thông qua từ khóa this
, nhưng JavaScript sẽ luôn đóng gói giá trị này thành một đối tượng, ngay cả khi đó chỉ là một chuỗi hoặc số đơn giản. Phương thức này sẽ trả về đối số đầu tiên, tức là đối tượng đã được lặp qua.
Để hiểu rõ hơn, bạn có thể xem qua ví dụ sau. Ở ví dụ dưới đây, sẽ có một mảng và có thể truy cập tất cả các phần tử của nó bằng hàm $.each() này.
<!DOCTYPE html>
<html>
<head>
<title>jQuery Each Function</title>
</head>
<body>
<h3>jQuery Each Function</h3>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
let arr = ["HTML","CSS","JavaScript","jQuery","React"];
$.each(arr, function(index, item){
console.log(`Index no ${index} : Item = ${item}`)
});
});
</script>
</body>
</html>
Khi chạy đoạn mã trên rồi mở công cụ dành cho developer của trình duyệt bằng cách nhấn phím F12 và xem bảng điều khiển, bạn sẽ thấy các bản ghi sau trong bảng điều khiển.
Hoặc một ví dụ khác, một object và có thể truy cập tất cả các cặp khóa và giá trị của object đó bằng cách sử dụng hàm $.each()
.
<!DOCTYPE html>
<html>
<head>
<title>jQuery Each Function</title>
</head>
<body>
<h3>jQuery Each Function</h3>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
let obj ={
name : 'John',
age : 22,
job : 'Web Developer',
hobby : 'cricket',
}
$.each( obj, function(key, val){
console.log( `Key = ${key} : Value = ${val}` )
});
});
</script>
</body>
</html>
Tương tự, khi chạy đoạn mã sẽ xuất hiện kết quả như sau
Một số ví dụ về each() trong jQuery
Ví dụ cơ bản về each() jQuery
Ví dụ 1: Chọn tất cả các thẻ <a>
trên trang và in ra thuộc tính href
của chúng:
$('a').each(function(index, value){
console.log(this.href);
// Hoặc: console.log($(this).attr('href'));
});
Ví dụ 2: In ra tất cả các đường dẫn href bên ngoài (external link) trên trang web (giả sử chỉ xét các đường dẫn có giao thức HTTP hoặc HTTPS):
$('a').each(function(index, value){
const link = this.href;
if (link.match(/https?:\/\//)) {
console.log(link);
}
});
Giả sử trên trang có các liên kết sau:
<a href="https://www.sitepoint.com/">SitePoint</a>
<a href="https://developer.mozilla.org">MDN web docs</a>
<a href="http://example.com/">Example Domain</a>
Thì ví dụ thứ hai sẽ in ra:
https://www.sitepoint.com/
https://developer.mozilla.org/
http://example.com/
Cần lưu ý rằng các phần tử DOM từ một đối tượng jQuery sẽ ở dạng “nguyên bản” (native DOM element) trong hàm callback được truyền vào jQuery.each()
. Lý do là vì jQuery thực chất chỉ là một lớp bao bọc (wrapper) quanh một mảng các phần tử DOM. Khi sử dụng jQuery.each()
, mảng này được lặp qua tương tự như một mảng thông thường, do đó sẽ không nhận được các phần tử đã được “gói” sẵn bằng jQuery trong callback.
Liên hệ với ví dụ thứ hai ở trên, điều này có nghĩa là bạn có thể truy cập thuộc tính href bằng cách viết this.href. Nếu muốn sử dụng phương thức attr() của jQuery, ta cần bao lại phần tử bằng jQuery như sau:
$(this).attr('href')
Ví dụ về mảng (array) khi dùng each() jQuery
Dưới đây là ví dụ về cách một mảng thông thường có thể được xử lý:
const numbers = [1, 2, 3, 4, 5];
$.each(numbers, function(index, value){
console.log(`${index}: ${value}`);
});
Đoạn mã này sẽ in ra:
0:1
1:2
2:3
3:4
4:5
So sánh với native JavaScript:
// Modern JavaScript alternative
numbers.forEach((value, index) => {
console.log(`${index}: ${value}`);
});
// Hoặc với for...of
for (const [index, value] of numbers.entries()) {
console.log(`${index}: ${value}`);
}
Nhìn chung, đoạn mã trên không có gì đặc biệt. Một mảng thông thường sử dụng chỉ số dạng số (numeric indices). Vì vậy, khi hiển thị, bạn sẽ nhận được các chỉ số bắt đầu từ 0 và tăng dần đến N-1, trong đó N là số phần tử trong mảng.
Ví dụ về jQuery each() JSON
Bạn có thể gặp phải các cấu trúc dữ liệu phức tạp hơn, chẳng hạn như mảng lồng trong mảng, đối tượng lồng trong đối tượng, mảng trong đối tượng hoặc đối tượng trong mảng. Dưới đây là ví dụ về cách jQuery.each()
có thể giúp xử lý các trường hợp này.
const colors = [
{ 'red': '#f00' },
{ 'green': '#0f0' },
{ 'blue': '#00f' }
];
$.each(colors, function() {
$.each(this, function(name, value) {
console.log(`${name} = ${value}`);
});
});
Kết quả in ra sẽ là:
red = #f00
green = #0f0
blue = #00f
So sánh với cách tiếp cận hiện đại:
// ES6+ approach
colors.forEach((colorObj, index) => {
Object.entries(colorObj).forEach(([name, value]) => {
console.log(`${name} = ${value}`);
});
});
Bạn xử lý cấu trúc lồng nhau bằng cách gọi lồng nhau jQuery.each()
. Lần gọi bên ngoài xử lý mảng chứa trong biến colors; lần gọi bên trong xử lý từng đối tượng trong mảng. Trong ví dụ này, mỗi đối tượng chỉ chứa một cặp key-value, nhưng trong thực tế, đoạn mã này có thể xử lý bất kỳ số lượng thuộc tính nào trong từng đối tượng.
Ví dụ về jQuery each() class
Dưới đây là ví dụ minh họa cách lặp qua từng phần tử có class productDescription
trong đoạn HTML bên dưới:
<div class="productDescription">Red</div>
<div>Pink</div>
<div class="productDescription">Orange</div>
<div class="generalDescription">Teal</div>
<div class="productDescription">Green</div>
Bạn sử dụng hàm hỗ trợ $.each()
thay vì phương thức .each()
trực tiếp trên selector:
$.each($('.productDescription'), function(index, value) {
console.log(index + ':' + $(value).text());
});
Trong trường hợp này, kết quả in ra là:
0:Red
1:Orange
2:Green
Không bắt buộc phải truyền index và value, đó chỉ là các tham số giúp xác định phần tử DOM hiện tại đang được lặp. Ngoài ra, trong tình huống này, bạn cũng có thể sử dụng cú pháp tiện lợi hơn với phương thức .each()
như sau:
$('.productDescription').each(function() {
console.log($(this).text());
});
Và kết quả trên console sẽ là:
mathematica
Copy
Edit
Red
Orange
Green
Lưu ý rằng bạn đang bao phần tử DOM trong một đối tượng jQuery mới ($(this)
) để có thể sử dụng phương thức .text() và lấy ra nội dung văn bản của phần tử.
So sánh: JavaScript .forEach() và jQuery .each()
Cả .forEach()
trong JavaScript và .each()
trong jQuery đều là những phương thức phổ biến dùng để lặp qua các phần tử trong mảng hoặc danh sách. Tuy nhiên, chúng được thiết kế để phục vụ các mục đích hơi khác nhau và hoạt động trong các ngữ cảnh khác nhau. Để lựa chọn được công cụ phù hợp, bạn cần hiểu rõ điểm giống và khác nhau giữa hai phương thức này.
Xem chi tiết: forEach JavaScript: Một số thao tác cơ bản và ví dụ chi tiết
Dưới đây là một số điểm khác biệt giữa 2 phương thức này
Tính năng | $.each() (jQuery) | forEach() (JavaScript) |
Phù hợp | Mảng & đối tượng | Chỉ áp dụng cho mảng và các đối tượng dạng mảng |
Giá trị trả về | Có thể return false để dừng vòng lặp | Không thể dừng vòng lặp |
Cú pháp | $.each(arrayOrObject, function(index, value) { ... }) | array.forEach(function(value, index) { ... }) |
Giá trị trả về | Không có giá trị trả về (chỉ lặp qua phần tử) | Trả về undefined, không có giá trị trả về |
Dừng vòng lặp | Không thể thoát khỏi vòng lặp bằng break hoặc return | Không thể dừng (phải dùng for loop hoặc some/every ) |
Phạm vi (scope) | Hàm callback nhận phần tử hiện tại dưới dạng this | Hàm callback nhận phần tử hiện tại là giá trị value |
Hiệu suất | Chậm hơn một chút so với forEach() do có lớp jQuery bao bọc | Nhanh hơn (native JavaScript) |
Định nghĩa về 2 phương thức
.forEach()
là phương thức gốc (native method) của JavaScript, thuộc về đối tượng Array.
Phương thức này thực thi một hàm callback
với từng phần tử trong mảng .forEach()
không làm thay đổi (mutate) mảng gốc và luôn trả về undefined. Ví dụ trong đoạn mã JavaScript dưới đây, sẽ in ra: ‘a’, ‘b’ và ‘c’ trong cửa sổ console.
var arr = ['a', 'b', 'c'];
arr.forEach(function(element) {
console.log(element);
});
// Output: 0: a, 1: b, 2: c
Modern ES6+ syntax:
const arr = ['a', 'b', 'c'];
arr.forEach((element, index) => {
console.log(`${index}: ${element}`);
});
jQuery có hai phương thức each()
khác nhau: $.each()
(utility function) và $().each()
(method), dùng để lặp qua mảng, objects hoặc tập hợp các phần tử DOM đã chọn. Ví dụ:
// $.each() - Utility function
var arr = ['a', 'b', 'c'];
$.each(arr , function (index, value){
console.log(value);
});
// $().each() - jQuery object method
$('div').each(function(index, element) {
console.log(`${index}: ${$(this).text()}`);
});
Lặp qua các phần tử DOM
Đối với .forEach()
trong JavaScript, giả sử bạn muốn lấy tất cả các thẻ <a>
(anchor) trên trang web và lặp qua từng thẻ.
Trong trường hợp này, trước tiên bạn cần sử dụng document.getElementsByTagName("a")
để lấy tất cả các thẻ <a>
, sau đó phải chuyển đổi kết quả thành một mảng, vì phương thức .forEach()
của JavaScript chỉ hoạt động với mảng.
Xem đoạn mã dưới đây được sử dụng phương thức Array.from()
để chuyển đổi sang mảng:
var links = document.getElementsByTagName("a");
var Arr = Array.from(links);
Arr.forEach(someFunction);
function someFunction(currentValue) {
console.log(currentValue);
}
Còn đối với phương thức .each()
trong jQuery, bạn có thể lặp trực tiếp qua tất cả các thẻ <a>
như ví dụ bên dưới. Phương thức này có thể lặp qua mảng, mảng đối tượng, hoặc tập hợp các phần tử DOM đã được chọn. Vì vậy, bạn không cần chuyển đổi sang mảng như khi dùng .forEach()
của JavaScript.
$("a").each(function (index, value) {
console.log($(this).attr("href"));
});
Ở ví dụ trên, bạn có thể thấy rằng trong trường hợp này, số dòng mã ít hơn đáng kể so với khi sử dụng .forEach()
trong JavaScript.
Nên chọn phương thức nào?
Bạn nên chọn phương thức each()
của jQuery trong hai trường hợp sau:
- Khi làm việc với các phần tử DOM, khi đó phương thức
each()
của jQuery có lợi thế lớn vì giúp giảm đáng kể số dòng mã. - Nếu website đã sử dụng jQuery từ trước, việc sử dụng
each()
của jQuery sẽ đảm bảo tính nhất quán trong mã nguồn của dự án.
Trong tất cả các trường hợp còn lại, bạn nên sử dụng phương thức .forEach()
của JavaScript.
Các câu hỏi thường gặp về each() trong jQuery
Các tham số của hàm callback sử dụng với .each() là gì?
Hàm callback
trong .each()
nhận hai tham số chính:
index
: Vị trí của phần tử trong vòng lặp (bắt đầu từ 0).element
: Phần tử hiện tại trong vòng lặp (phần tử DOM, không phải jQuery object).
Ví dụ:
$('li').each(function(index, element) {
console.log('Phần tử thứ ' + index + ': ' + $(element).text());
});
Sử dụng hàm .each() trong jQuery như thế nào?
Bạn có thể sử dụng hàm .each()
bằng cách chọn một tập hợp các phần tử với jQuery selector, sau đó gọi .each()
trên lựa chọn đó. Bạn cung cấp một hàm gọi lại xác định hành động sẽ được thực hiện trên mỗi phần tử. Ví dụ:
$('p').each(function() {
$(this).css('color', 'blue');
});
Sử dụng tham số index trong hàm callback của .each() như thế nào?
Tham số index đại diện cho vị trí của phần tử trong tập hợp được lặp. Bạn có thể sử dụng index để đánh số thứ tự, áp dụng kiểu dáng khác nhau cho các phần tử chẵn/lẻ, hoặc tạo ID động.
Một số trường hợp sử dụng phổ biến của hàm .each() là gì?
Các trường hợp sử dụng phổ biến bao gồm
- Lặp qua danh sách các phần tử để thao tác với thuộc tính, giá trị hoặc kiểu dáng.
- Thực hiện các hành động tùy chỉnh trên từng phần tử trong một tập hợp.
- Duyệt qua danh sách thẻ HTML để cập nhật nội dung.
- Gán sự kiện cho nhiều phần tử cùng lúc.
- Thay đổi style hàng loạt.
- Kiểm tra dữ liệu đầu vào từ các trường form.
- Tạo hiệu ứng đồng loạt.
Tổng kết về each() jQuery
each
jQuery là một công cụ bất kỳ lập trình viên nào cũng nên nắm vững khi làm việc với jQuery. Không chỉ giúp đơn giản hóa quá trình duyệt dữ liệu, each()
còn tăng khả năng tương tác với DOM một cách linh hoạt và hiệu quả. Hy vọng qua bài viết, bạn đã hiểu rõ về cách sử dụng each()
, tránh được các lỗi thường gặp và tận dụng tối đa tiềm năng của phương thức này nhé.