Trong xây dựng giao diện web, template HTML cho phép bạn lưu trữ các đoạn mã HTML “ẩn”, không được hiển thị ngay khi tải trang, chỉ được kích hoạt bằng JavaScript. Bài viết này sẽ giúp bạn hiểu rõ cách hoạt động, ứng dụng và những lợi ích mà thẻ <template> mang lại cho lập trình front-end.
Đọc bài viết sau để được giải đáp chi tiết hơn về:
- Tổng quan về thẻ template trong HTML: Cú pháp, tiện ích và những trình duyệt hỗ trợ
- Một số thuộc tính thường gặp khi sử dụng <template>
- Ví dụ về cách sử dụng thẻ <template> trong HTML
- Cách sử dụng thẻ <template> trong JavaScript
- Cách sử dụng thẻ <template> với framework
- Những ưu & nhược điểm của thẻ <template>
Giới thiệu về thẻ template HTML
Thẻ <template> là một phần tử HTML5 được dùng để lưu trữ các đoạn mã HTML không được hiển thị ngay khi trang được tải. Phần tử này có thể được sao chép và chèn vào file HTML.
Nội dung trong thẻ <template> sẽ được ẩn khỏi máy khách vì nó được lưu trữ ở phía máy khách. Các mẫu này sẽ không được hiển thị trong trình duyệt cho đến khi bạn kích hoạt chúng bằng JavaScript. JavaScript được sử dụng để lấy nội dung từ một mẫu và thêm vào trang web.
Việc tạo <template> cũng rất đơn giản. Bạn chỉ cần chỉ định phần tử <template> và cung cấp cho nó một ID phù hợp. Việc gán một ID cho phần tử <template> giúp bạn dễ dàng truy xuất và tái sử dụng nội dung của nó bằng JavaScript.
<template id="content-wrapper"> <div>render this content</div> </template>
Thuộc tính của thẻ template HTML
Thẻ <template> hỗ trợ các thuộc tính toàn cục (global attribute) như id, class, style,… Chúng giúp bạn dễ dàng điều chỉnh các chức năng như kiểu dáng, nhận dạng, khả năng truy cập và tương tác, giúp cải thiện giao diện và chức năng của trang web.
Bên cạnh đó, <template> cũng hỗ trợ các thuộc tính đặc biệt liên quan đến Declarative Shadow DOM, cụ thể:
Thuộc tính | Mô tả |
shadowrootmode |
Thẻ <template> có thể khai báo nội dung cho một ShadowRoot sẽ được tạo ra trên phần tử cha. Đây là cách khai báo để thay thế cho việc gọi Element.attachShadow() trong JavaScript. Nó cũng hỗ trợ các giá trị giống như khi gọi hàm đó:
|
shadowrootclonable |
Thiết lập giá trị thuộc tính clonable của ShadowRoot được tạo từ phần tử này thành true. Khi bật thuộc tính này, nếu bạn sao chép phần tử chứa shadow DOM (tức là phần tử cha của thẻ <template>) bằng Node.cloneNode() hoặc Document.importNode(), thì bản sao cũng sẽ bao gồm ShadowRoot giống bản gốc. |
shadowrootdelegatesfocus |
Thiết lập giá trị thuộc tính delegatesFocus của ShadowRoot được tạo từ phần tử này thành true. Khi được đặt, trình duyệt sẽ tự động chuyển focus đến phần tử đầu tiên có thể focus trong Shadow DOM khi phần tử chứa nó (shadow host) nhận focus. |
shadowrootserializable |
Giá trị của thuộc tính có thể tuần tự hóa của shadowroot được tạo bằng thuộc tính này thành true. Nếu được thiết lập, shadow root có thể được tuần tự hóa bằng cách gọi các phương thức Element.getHTML() hoặc ShadowRoot.getHTML() với tham số options.serializableShadowRoots được đặt thành true. |
Ví dụ về cách sử dụng thẻ template HTML
Dưới đây là một số ví dụ về cách sử dụng thẻ <template> trong HTML:
Ví dụ sử dụng thẻ template HTML 1
Sử dụng <template> để giữ một số nội dung sẽ bị ẩn khi tải trang, sau đó sử dụng JavaScript để hiển thị nội dung.
<!DOCTYPE html> <html> <body> <h1>The template Element</h1> <p>Click the button below to display the hidden content from the template element.</p> <button onclick="showContent()">Show hidden content</button> <template> <h2>Flower</h2> <img src="img_white_flower.jpg" width="214" height="204"> </template> <script> function showContent() { const temp = document.getElementsByTagName("template")[0]; const clon = temp.content.cloneNode(true); document.body.appendChild(clon); } </script> </body> </html>
Kết quả hiển thị của đoạn mã trên:
Kết quả hiển thị khi nhấn button “Show hidden content”:
Trong ví dụ trên, có thể thấy:
- <template> đã giữ nội dung bên trong không được hiển thị cho đến khi bạn gọi nó bằng JavaScript.
- Khi bạn bấm vào nút <button>, hàm showContent() được gọi.
- Trong hàm showContent() sẽ thực hiện:
- getElementsByTagName(“template”)[0] lấy ra phần tử <template> đầu tiên trên trang
- .content.cloneNode(true) sao chép toàn bộ nội dung của template
- appendChild(clon) chèn bản sao đó vào cuối thẻ <body>.
Kết quả hiển thị, khi bạn nhấn vào nút “Show hidden content”, hình ảnh bông hoa sẽ xuất hiện.
Ví dụ sử dụng thẻ template HTML 2
Sử dụng danh sách không theo thứ tự (unordered list) các bài viết đã được ẩn để hiển thị bằng cách sử dụng thẻ <template>.
<!DOCTYPE html> <html> <body> <h1>ITviec</h1> <h3>HTML template tag</h3> <p> Nội dung bên trong thẻ mẫu sẽ bị ẩn khỏi máy khách. </p> <!-- Html script tag starts here --> <template id="checkbox-template"> <h2>ITviec: Checkbox HTML: Cách chèn và tùy chỉnh checkbox trong HTML</h2> <h4>Tổng quan về checkbox HTML </h4> <ul> <li>Heading 1</li> <li>Heading 2</li> <li>Heading 3</li> <li>Heading 4</li> </ul> </template> <!-- Html template tag ends here --> <p>Kết thúc ví dụ về thẻ template</p> </body> </html>
Kết quả hiển thị của đoạn mã trên:
Ở ví dụ trên cho thấy nội dung trong <template> không hiển thị ngay mà chỉ được hiển thị khi bạn sử dụng thêm JavaScript.
- Thẻ <template> chứa một đoạn HTML với tiêu đề, phụ đề, và danh sách. Tuy nhiên, nội dung này không hiển thị ra ngoài vì chưa được gọi bằng JavaScript.
- Đây là nội dung “chờ sẵn”, chỉ được hiển thị nếu bạn dùng JavaScript để lấy nó ra.
Ví dụ sử dụng thẻ template HTML 3
Sử dụng JavaScript để hiển thị nội dung <template>:
<!DOCTYPE html> <html> <body> <h1>ITviec</h1> <h3>HTML template tag</h3> <p>Nhấn vào nút để lấy nội dung từ mẫu và hiển thị trên trang web.</p> <button onclick="myGeeks()"> Show content </button> <!-- Html template tag starts here --> <template id="template-content"> <h2>ITviec</h2> <img src= "https://itviec.com/assets/logo-itviec-4492a2f2577a15a0a1d55444c21c0fa55810822b3b189fc689b450fb62ce0b5b.png"> <br> Content Writer: <input type="text" placeholder="author name"> </template> <!-- Html template tag ends here --> <!-- Script to display the content of template tag --> <script> function myGeeks() { const t = document.getElementById("template-content"); const clone = t.content.cloneNode(true); document.body.appendChild(clone); } </script> </body> </html>
Kết quả hiển thị của đoạn mã trên:
Kết quả hiển thị khi nhấn button “Show content”:
Ở ví dụ trên, có thể thấy:
- Khi người dùng bấm nút <button>, trình duyệt sẽ gọi hàm JavaScript myGeeks().
- Hàm myGeeks() sẽ lấy phần tử <template> đầu tiên trên trang. Tạo bản sao nội dung bên trong template (cloneNode(true) là sao chép toàn bộ). Chèn bản sao đó vào cuối thẻ <body> để hiển thị ra trình duyệt.
Cách sử dụng thẻ <template> trong JavaScript như thế nào?
Để sử dụng thẻ template trong JavaScript, bạn có thể sử dụng phương thức querySelector để chọn phần tử template. Sau đó, sử dụng thuộc tính content để truy cập nội dung của <template>.
Xem thêm: JavaScript là gì? Học JavaScript cơ bản với lộ trình dễ hiểu nhất
Sau đây là ví dụ về cách bạn có thể sử dụng thẻ template trong JavaScript.
// Chọn thành phần template let template = document.querySelector('#item-template'); // Truy cập vào nội dung template let templateContent = template.content; // Tạo một thành phần DOM mới sử dụng template let newItem = document.importNode(templateContent, true); // Cập nhật text của thành phần mới newItem.querySelector('.item-name').textContent = 'Item 1'; // Thêm thành phần mới vào trang document.querySelector('#items').appendChild(newItem);
Ở ví dụ trên, có thể thấy:
- Phương thức querySelector được sử dụng để chọn phần tử template có id là item-template.
- Sử dụng thuộc tính content để truy cập nội dung của phần tử mẫu, là đối tượng DocumentFragment.
- Sử dụng phương thức importNode để tạo phần tử DOM mới dựa trên <template>.
- Cuối cùng, sử dụng phương thức querySelector để chọn <span> có class là item-name và sử dụng thuộc tính textContent để cập nhật văn bản của phần tử.
- Sử dụng thêm phương thức appendChild để thêm phần tử mới vào trang.
Cách sử dụng <template> với framework
Thẻ <template> có thể được sử dụng với framework như React. Tuy nhiên, React xử lý các phần tử này theo cách khác. Công dụng của thẻ <template> không phải là hiển thị các phần tử con, mà là xử lý như văn bản chưa phân tích cú pháp. Trình duyệt phân tích cú pháp chỉ để đảm bảo rằng đó là HTML hợp lệ.
Tuy nhiên, việc sử dụng <template> trong React không được khuyến nghị. Ngoài ra, việc sử dụng dangerouslySetInnerHTML có thể gây ra XSS nếu dữ liệu không được kiểm soát.
Xem thêm: Framework là gì? Top 15+ framework web, mobile phổ biến
Để sử dụng thẻ này trong React, bạn sẽ phải đặt nội dung của nó dưới dạng chuỗi.
function Template({ children, ...attrs }) { return ( <template {...attrs} dangerouslySetInnerHTML={{ __html: children }} /> ); }
Sau đó, React tạo tất cả các thẻ con dưới dạng các phần tử node nhưng trình duyệt sẽ quyết định phải làm gì. Bất cứ khi nào bạn cần sử dụng <template>, bạn cần lưu ý rằng nội dung bên trong phải nằm trong dấu ngoặc kép vì nó phải là một chuỗi.
render() { return ( <Template> {'<div>some content</div>'} </Template> ) }
Ưu & nhược điểm khi sử dụng thẻ template HTML
Thẻ <template> đặc biệt hữu ích khi bạn muốn tách biệt nội dung chưa được hiển thị với giao diện người dùng cho đến khi cần. Tuy nhiên, thẻ <template> có cả ưu điểm lẫn hạn chế mà bạn cần nắm rõ trước khi áp dụng vào dự án thực tế.
Ưu điểm | Nhược điểm |
|
|
Câu hỏi thường gặp về thẻ template HTML
Thẻ <template> có thể được sử dụng ngoài file HTML không?
Câu trả lời là có, nhưng sẽ đi kèm với điều kiện. Thẻ <template> thường được sử dụng trong file HTML tiêu chuẩn, tuy nhiên bạn vẫn có thể nhúng nó vào file JavaScript thông qua cách tạo chuỗi HTML trong code và chèn vào DOM.
Dù vậy, cách phổ biến và được khuyến nghị nhất vẫn là sử dụng trực tiếp trong file HTML hoặc trong các file HTML được tải động qua JavaScript (AJAX hoặc fetch).
void async function () { //get the imported document in templates: var templates = document.createElement( 'template' ) templates.innerHTML = await ( await fetch( 'templates.html' ) ).text() //fetch template2 1 and 2: var template1 = templates.content.querySelector( '#t1' ) var template2 = templates.content.querySelector( '#t2' ) console.log( template2 ) } ()
Nội dung bên trong thẻ <template> có hiển thị trong “View Source” không?
Câu trả lời là Có. Khi bạn xem “View Source” (Xem nguồn trang), nội dung trong thẻ <template> vẫn sẽ hiển thị, bởi vì đây là cách trình duyệt hiển thị nội dung gốc của file HTML. Tuy nhiên, nội dung bên trong thẻ <template> sẽ không hiển thị trên giao diện người dùng (UI) khi trang được tải, trừ khi có JavaScript can thiệp và chèn nó vào DOM.
Nên đặt thẻ <template> ở đâu trong HTML?
Bạn có thể đặt <template> trong phần đầu (head section) hoặc trong phần thân (body) của trang HTML, tùy theo cách nào thuận tiện hơn đối với bạn. Ngoài ra, <template> có thể chứa bất kỳ mã đánh dấu HTML hợp lệ nào, bao gồm các phần tử như <style> và <script> hay thậm chí cả <template>.
Tổng kết về thẻ template HTML
Thẻ template HTML là một công cụ giúp tăng tính linh hoạt trong thiết kế giao diện web hiện đại. Khi được sử dụng đúng cách, thẻ <template> không chỉ tối ưu hiệu suất mà còn giúp mã HTML trở nên gọn gàng, dễ quản lý và mở rộng trong các dự án phức tạp.
Xem thêm: Giải đáp “tất tần tật” những điều cần biết về HTML