Giới thiệu
Bài viết này cung cấp cái nhìn toàn diện về việc thêm JavaScript vào file HTML, chi tiết ba phương pháp cốt lõi: đặt script inline trong <head>, inline trong <body>, và link đến file .js external. Bên cạnh 'cách làm', bài viết đi sâu vào 'tại sao' quan trọng, giải thích các tác động hiệu năng đáng kể của mỗi cách, bao gồm khái niệm như render-blocking, browser caching, và dùng các attribute hiện đại như defer và async.
Để nối lý thuyết và thực hành, hướng dẫn bao gồm các ví dụ thực tế như tạo dark mode toggle và validate web form. Cuối cùng, nó trang bị cho bạn các best practices thiết yếu cho code sạch, maintainable và hướng dẫn troubleshooting giúp giải quyết common beginner errors dùng browser's developer console, đảm bảo bạn bắt đầu dự án web development với tự tin.
Cần deploy dự án JavaScript nhanh? Kiểm tra DigitalOcean App Platform và deploy JS project trực tiếp từ GitHub trong vài phút.
Các điểm chính
- Best practice để thêm JavaScript là dùng file
.jsexternal cho tổ chức, bảo trì, và tái sử dụng tốt hơn. - Đặt thẻ
<script>trong<head>tồi tệ nhất cho hiệu năng vì nó render-blocking, buộc user nhìn trang trắng. - Dùng attribute
defertrên script external là cách tiếp cận hiện đại khuyến nghị cho hiệu năng tối ưu. - File JavaScript external mang lại boost hiệu năng lớn nhờ browser caching, điều mà inline script không có.
- Một file
.jsđơn lẻ có thể link qua nhiều trang, làm cho update và maintenance hiệu quả hơn nhiều. - Developer Console (F12) là công cụ quan trọng nhất để troubleshoot common JavaScript errors.
Phương pháp 1: Cách thêm Inline Script vào <head>
Bạn có thể thêm JavaScript code trong HTML document bằng thẻ HTML chuyên dụng <script> bao quanh JavaScript code. Thẻ <script> có thể đặt trong section <head> hoặc <body> của HTML, tùy khi bạn muốn JavaScript load.
Thông thường, JavaScript code có thể đặt trong document <head> section để giữ nó contained và tách khỏi main content của HTML document.
Hãy xem xét HTML document cơ bản sau với browser title Today's Date:
index.html
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Today's Date</title> </head> <body> </body> </html>
Để thêm script tạo alert, chúng ta thêm thẻ <script> và JavaScript code dưới thẻ <title>, như sau:
index.html
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Today's Date</title> <script> let d = new Date(); alert("Today's date is " + d); </script> </head> <body> </body> </html>
Đặt script ở đây báo hiệu browser parse và execute JavaScript trước khi bắt đầu render content trong <body> của trang.
Cách này phù hợp nhất cho script không cần trực tiếp tương tác với element trên trang. Khi script trong <head> chạy, browser chưa build Document Object Model (DOM) cho <body>. Điều này nghĩa là bất kỳ HTML element như heading, paragraph, hay div nào chưa tồn tại. Kết quả, code cố gắng tìm hoặc sửa đổi element này (ví dụ dùng document.getElementById()) sẽ fail. Phương pháp này do đó lý tưởng cho việc setup functions và variables để dùng sau, hoặc include third-party analytics scripts cần load sớm nhất.
Khi load trang, bạn sẽ nhận alert như sau:

Phương pháp 2: Cách thêm Inline Script vào <body>
Thẻ <script> cũng có thể đặt trong section <body>. Khi script đặt ở đây, HTML parser sẽ tạm dừng công việc để execute script tại điểm chính xác nó xuất hiện trong document. Đây là phương pháp bắt buộc cho bất kỳ JavaScript code nào cần ngay lập tức tìm và sửa đổi HTML element.
Một common best practice là đặt script ngay trước thẻ đóng </body>. Vị trí này đảm bảo tất cả HTML element trên trang đã được parsed và available trong DOM trước khi script bắt đầu chạy. Nó cũng cải thiện perceived page performance, vì browser có thể render tất cả text và hình ảnh nhìn thấy trước, cho phép user thấy page content trước khi JavaScript tốn thời gian được execute. Điều này cho phép content hiển thị mà không bị chặn bởi JavaScript execution.
Hãy dùng phương pháp này để viết date trực tiếp vào HTML body.
index.html
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Today's Date</title> </head> <body> <script> let d = new Date(); document.body.innerHTML = "<h1>Today's date is " + d + "</h1>" </script> </body> </html>
Output cho HTML document trên load qua web browser sẽ trông như sau:

Script nhỏ hoặc chỉ chạy trên một trang có thể ổn trong HTML file, nhưng cho script lớn hoặc script dùng trên nhiều trang, nó không phải giải pháp hiệu quả vì include nó có thể trở nên cồng kềnh hoặc khó đọc hiểu. Phần sau, chúng ta sẽ xem cách handle separate JavaScript file trong HTML document.
Phương pháp 3: Cách làm việc với Separate JavaScript File
Cho script lớn hoặc code cần dùng qua nhiều trang, giải pháp hiệu quả và chuyên nghiệp nhất là đặt JavaScript trong file riêng với extension .js. Sau đó link đến file external này từ HTML dùng thẻ <script> với attribute src (source).
Lợi ích của cách này đáng kể:
- Separation of Concerns: Giữ HTML cho structure, CSS cho styling, và JavaScript cho interactivity trong file riêng. Điều này làm project cleaner, organized hơn, và dễ debug hơn.
- Reusability và Maintenance: Một file script đơn lẻ, như
main-navigation.js, có thể link từ mọi trang của website. Nếu cần update navigation logic, bạn chỉ edit file đó. - Browser Caching: Khi user truy cập site lần đầu, browser tải file .js. Ở lần truy cập sau hoặc điều hướng đến trang khác dùng cùng file, browser dùng cached copy thay vì tải lại. Điều này cải thiện loading time đáng kể.
Để demo cách connect JavaScript document đến HTML document, hãy tạo một web project nhỏ. Nó bao gồm script.js trong thư mục js/, style.css trong css/, và index.html chính ở root project.
project/ ├── css/ | └── style.css ├── js/ | └── script.js └── index.html
Hãy chuyển JavaScript code hiển thị date như <h1> header vào file script.js:
script.js
let d = new Date(); document.body.innerHTML = "<h1>Today's date is " + d + "</h1>"
Tiếp theo, edit file style.css thêm background color và style cho header <h1>:
style.css
body { background-color: #0080ff; } h1 { color: #fff; font-family: Arial, Helvetica, sans-serif; }
Cuối cùng, reference cả script và stylesheet từ index.html. Dùng thẻ <link> trong <head> cho CSS và thẻ <script> với attribute src trong <body> cho JavaScript.
index.html
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Today's Date</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <script src="js/script.js"></script> </body> </html>
Bây giờ, với JavaScript và CSS ở chỗ, project của chúng ta organized hơn nhiều. Khi load index.html vào browser, chúng ta thấy trang styled với date hiện tại như sau:

Bây giờ chúng ta đã đặt JavaScript trong file, chúng ta có thể gọi nó theo cùng cách từ các web page khác và update tất cả ở một vị trí. Phương pháp này cung cấp cách organized và scalable nhất để quản lý JavaScript trong web project. Để có thêm control về cách external scripts load, bạn có thể xem xét dùng attribute async và defer trên thẻ <script>.
Một số ví dụ thực tế?
Hãy xem vài ví dụ thực tế dựa trên những gì đã học.
1. Simple Dark Mode Toggle
Gần như mọi website/app hiện đại cung cấp dark mode. Điều này đạt được bằng cách toggle CSS class với JavaScript.
HTML:
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Dark Mode</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <button id="theme-toggle">Toggle Dark Mode</button> <h1 id="title">DigitalOcean</h1> <p>This is some example text on the page.</p> <script src="js/script.js"></script> </body> </html>
CSS:
/* Class này sẽ được add hoặc remove bởi JavaScript */ .dark-mode { background-color: #222; color: #eee; }
JavaScript:
const toggleButton = document.getElementById('theme-toggle'); toggleButton.addEventListener('click', function() { document.body.classList.toggle('dark-mode'); });
JavaScript đầu tiên tìm button bằng ID. Sau đó attach event listener chờ click. Khi button clicked, lệnh classList.toggle('dark-mode') chạy. Nếu element <body> không có class .dark-mode, JavaScript thêm nó. Nếu đã có, JavaScript xóa nó. Browser ngay lập tức apply CSS styles liên quan đến class đó.
2. Basic Form Validation
Website cần đảm bảo user điền form đúng trước khi submit. JavaScript kiểm tra ngay lập tức mà không reload trang.
HTML:
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Form Validator</title> </head> <body> <form id="contact-form"> <label for="email">Email:</label> <input type="text" id="email" placeholder="you@example.com"> <button type="submit">Subscribe</button> <p id="error-message" style="color: red;"></p> </form> <script src="js/script.js"></script> </body> </html>
JavaScript:
const contactForm = document.getElementById('contact-form'); const emailInput = document.getElementById('email'); const errorMessage = document.getElementById('error-message'); contactForm.addEventListener('submit', function(event) { if (!emailInput.value.includes('@')) { event.preventDefault(); errorMessage.textContent = 'Please enter a valid email address.'; } else { errorMessage.textContent = ''; } });
Script lắng nghe event submit trên form. Khi click nút "Subscribe", function chạy. Nó kiểm tra text trong email input có chứa ký hiệu @ không.
- Nếu không,
event.preventDefault()dừng default submission behavior của form. Sau đó hiển thị error message hữu ích cho user. - Nếu có, script không làm gì, và form submit như bình thường.
Các performance considerations cho mỗi phương pháp?
Hãy thảo luận các performance considerations chính cho từng phương pháp load JavaScript đã thảo luận:
Inline Script trong <head>
-
Vấn đề chính: Render-Blocking
Đặt script trong
<head>có tác động tiêu cực nhất đến hiệu năng. Browser phải download, parse, và execute JavaScript trước khi có thể render bất kỳ phần nào của<body>. Nếu script lớn hoặc chạy chậm, user sẽ nhìn trang trắng cho đến khi script xong. Điều này tăng time to First Contentful Paint (FCP), một user experience metric quan trọng. -
Caching: Không có
Inline scripts là một phần của HTML document. Chúng không thể cached riêng biệt bởi browser. Mỗi lần user truy cập trang, script được re-downloaded và re-parsed cùng với phần còn lại của HTML.
Phương pháp này tổng quát tồi tệ cho hiệu năng và nên tránh trừ khi script cực nhỏ và bắt buộc phải chạy trước mọi thứ khác.
Inline Script trong <body>
-
Vấn đề chính: Partial Render-Blocking
Phương pháp này cải thiện lớn so với đặt script trong
<head>. Browser parse và render HTML cho đến khi gặp thẻ<script>. Lúc đó, nó dừng render để execute script. Bằng cách đặt script ở cuối<body>(ngay trước thẻ</body>), bạn cho phép toàn bộ visible page được render trước. -
Caching: Không có
Giống script trong
<head>, inline script trong<body>là phần của HTML và không thể cached độc lập.
Đặt script ở cuối body là strategy tốt để cải thiện perception của speed vì content visible nhanh. Tuy nhiên, nó vẫn có thể delay trang trở nên fully interactive.
External JavaScript File
Phương pháp này cung cấp flexibility nhiều nhất và hiệu năng tốt nhất, chủ yếu nhờ hai yếu tố: browser caching và special loading attributes.
-
Lợi ích chính: Caching và Asynchronous Loading
-
Caching: Đây là performance win lớn nhất. File
.jsexternal tải một lần ở lần truy cập đầu. Cho tất cả trang tiếp theo dùng script giống nhau, browser load file từ local cache, loại bỏ network delay và speed up site đáng kể. -
Attribute
defervàasync: External scripts mở khóa dùng hai attribute mạnh mẽ.<script defer src="..."></script>: báo browser download script trong background trong khi continue parsing HTML. Script chỉ execute sau khi entire document parsed. Đây là modern approach khuyến nghị vì non-blocking và đảm bảo script chạy theo thứ tự xuất hiện trong HTML.<script async src="..."></script>: cũng download background không block render. Tuy nhiên, nó execute script ngay khi download xong, có thể xảy ra bất kỳ lúc nào và có thể interrupt render. Tốt cho third-party scripts độc lập (như ads hoặc analytics) nơi execution order không quan trọng.
-
Dùng external file link với attribute defer là best practice cho optimal performance. Nó kết hợp lợi ích non-blocking loading với browser caching mạnh mẽ.
Một số best practices?
Dưới đây là một số best practices thiết yếu và troubleshooting tips cho việc làm việc với JavaScript trong HTML file.
- Giữ JavaScript trong External Files: Luôn ưu tiên link đến file
.js(<script src="..."></script>) thay vì viết JavaScript trực tiếp trong HTML. Điều này giữ code organized, dễ maintain, và cho phép browser cache file để load nhanh hơn. - Load Scripts ở cuối
<body>vớidefer: Cho trải nghiệm user tốt nhất, đặt thẻ<script>ngay trước thẻ đóng</body>và thêm attributedefer. Điều này đảm bảo page content load và hiển thị nhanh mà không bị block bởi JavaScript. - Viết Readable Code: Dùng tên rõ ràng, mô tả cho variables và functions (ví dụ
calculateTotalPricethay vìcalc). Dùng comments//để giải thích tại sao bạn viết đoạn code, không phải nó làm gì. - Don't Repeat Yourself (DRY): Nếu thấy mình viết cùng dòng code ở nhiều nơi, wrap code đó vào function. Sau đó call function khi cần, làm code ngắn hơn và dễ update hơn.
Một số common issues và cách troubleshoot?
Khi script không chạy, đừng hoang mang! Browser's Developer Tools là người bạn tốt nhất. Nhấn F12 (hoặc right-click trang chọn "Inspect") và click tab "Console". Hầu hết errors sẽ hiện ở đây màu đỏ.
-
Error: "Cannot read properties of null" hoặc "is not defined"
- Ý nghĩa: JavaScript cố truy cập HTML element chưa load.
- Giải pháp: Gần như luôn nghĩa là thẻ
<script>ở<head>hoặc quá cao trong<body>. Di chuyển script xuống cuối<body>và thêm attribute defer.
-
Error: "Uncaught SyntaxError"
- Ý nghĩa: Bạn có typo trong code.
- Giải pháp: Console thường cho line number. Xem kỹ dòng đó cho missing parentheses
(), curly braces{}, quotes"", hoặc typo khác.
-
Problem: Script không chạy, không error trong Console.
- Ý nghĩa: HTML file có thể không tìm thấy file
.js. - Giải pháp: Check tab "Network" trong Developer Tools. Nếu thấy script file liệt kê với 404 error, file path trong attribute
srcsai. Kiểm tra spelling và folder structure (ví dụ<script src="js/script.js"></script>).
- Ý nghĩa: HTML file có thể không tìm thấy file
-
Problem: Code chạy nhưng không làm gì tôi mong đợi.
-
Ý nghĩa: Đây là logic error. Syntax đúng nhưng steps sai.
-
Giải pháp: Dùng
console.log()để debug. Đặt nó trong code để in giá trị variables ở các stage khác nhau. Điều này giúp trace logic và thấy chính xác nơi sai.let userRole = 'guest'; console.log('User role before check:', userRole); // Xem giá trị là gì if (userIsAdmin) { userRole = 'admin'; }
-
Frequently Asked Questions (FAQs)
1. Cách tốt nhất thêm JavaScript vào HTML file là gì?
Cách tốt nhất là link đến file .js external với attribute defer, đặt script tag ngay trước thẻ đóng </body> (ví dụ <script src="path/to/script.js" defer></script>).
2. Nên để JavaScript ở head hay body?
Bạn gần như luôn nên đặt thẻ <script> ở cuối section <body>, ngay trước thẻ đóng </body>.
Đặt script trong <head> block page render, nghĩa là user thấy trang trắng cho đến khi script download và execute xong. Khi đặt script ở cuối <body>, browser render toàn bộ HTML và CSS trước, nên user thấy content nhanh hơn nhiều.
3. Có thể thêm multiple script tags trong một HTML file không?
Có, bạn có thể include bao nhiêu thẻ <script> cần trong một HTML file. Browser sẽ download và execute chúng theo thứ tự xuất hiện trong document.
Điều này thường dùng để load third-party libraries trước custom scripts phụ thuộc vào chúng.
<body> <script src="library.js"></script> <script src="my-app.js"></script> </body>
4. Khác biệt chính giữa async và defer là gì?
Cả hai attribute load script không block page render. Khác biệt chính là defer đảm bảo script execute theo thứ tự xuất hiện sau khi document fully parsed, trong khi async execute script ngay khi download xong, có thể theo bất kỳ thứ tự nào.
5. Làm sao debug JavaScript không chạy?
Mở Developer Tools (F12), check tab Console cho error messages, dùng tab Network verify file loading, và thêm console.log() để trace variable values.
Kết luận
Trong hướng dẫn này, bạn học ba phương pháp cốt lõi thêm JavaScript vào HTML: inline trong <head>, inline trong <body>, và link đến file .js external. Bạn cũng khám phá performance implications bao gồm render-blocking, browser caching, và attribute defer và async, cùng với ví dụ thực tế và troubleshooting guide dùng Developer Console.
Bây giờ bạn có thể chọn đúng JavaScript loading strategy cho use case, viết code sạch và maintainable dùng external file, và debug common errors dùng browser Developer Tools. Dùng file .js external với attribute defer là approach khuyến nghị cho hầu hết production web projects.
Để tiếp tục xây dựng JavaScript skills, khám phá các hướng dẫn sau:
- How To Use the JavaScript Developer Console
- How To Write Comments in JavaScript
- Understanding Syntax and Code Structure in JavaScript
- Understanding Variables, Scope, and Hoisting in JavaScript
Bản 작업 này được cấp phép theo Giấy phép Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.