So sánh 3 thuộc tính
| Thuộc tính | Trả về | Xử lý HTML | CSS aware | Performance |
|---|---|---|---|---|
| innerHTML | HTML string (giữ thẻ) | Parse & render | Không | Chậm nhất |
| innerText | Text hiển thị (như user thấy) | Loại bỏ thẻ, xử lý CSS | ✅ Có (hidden = bỏ qua) | Chậm (layout) |
| textContent | Tất cả text node | Loại bỏ thẻ, giữ whitespace | ❌ Không | Nhanh nhất |
Ví dụ minh họa
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>innerHTML vs innerText vs textContent</title>
<style>
body { font-family: 'Segoe UI', sans-serif; padding: 20px; }
.sample { font-size: 18px; font-weight: 500; color: #d32f2f; padding: 15px; background: #ffebee; border-radius: 4px; }
.result { font-size: 14px; font-family: monospace; margin: 10px 0; padding: 15px; background: #f5f5f5; border-radius: 4px; white-space: pre-wrap; }
button { padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<h1>innerHTML vs innerText vs textContent</h1>
<div class="sample" id="sample">Hello <b>World</b> <i>Some Text</i> <span style="display:none">Hidden</span></div>
<div class="result">innerHTML: <span id="r1"></span></div>
<div class="result">innerText: <span id="r2"></span></div>
<div class="result">textContent: <span id="r3"></span></div>
<button id="btn">SO SÁNH</button>
<script>
const sampleEle = document.getElementById('sample');
const btn = document.getElementById('btn');
btn.addEventListener('click', () => {
document.getElementById('r1').textContent = sampleEle.innerHTML;
document.getElementById('r2').textContent = sampleEle.innerText;
document.getElementById('r3').textContent = sampleEle.textContent;
});
</script>
</body>
</html>
Kết quả
innerHTML: Hello World Some Text
innerText: Hello World Some Text (bỏ "Hidden" do display:none)
textContent: Hello World Some Text Hidden (giữ "Hidden", giữ whitespace)
Khi nào dùng cái nào?
✅ innerHTML - Khi cần HTML
// Render template
container.innerHTML = '...';
// Lấy HTML để lưu/edit
const html = editor.innerHTML;
✅ textContent - Khi chỉ cần text (KHUYẾN NGHỊ)
// An toàn XSS
element.textContent = userInput;
// Lấy text để search, count words
const wordCount = element.textContent.split(/\s+/).length;
// Performance tốt nhất
⚠️ innerText - Hiếm khi cần
// Chỉ khi cần text "như user thấy" (respect CSS hidden)
// Ví dụ: Copy visible text to clipboard
Bảo mật (XSS Prevention)
// ❌ NGUY HIỂM - XSS
div.innerHTML = userInput; // Nếu userInput = '
'
// ✅ AN TOÀN
div.textContent = userInput; // Hiển thị nguyên chuỗi ""
// ✅ AN TOÀN (nếu cần HTML) - DOMPurify
import DOMPurify from 'dompurify';
div.innerHTML = DOMPurify.sanitize(userInput);
Performance
// Benchmark: 10000 lần
// textContent: ~5ms
// innerText: ~150ms (trigger layout)
// innerHTML: ~50ms (parse HTML)
Kết luận: Mặc định dùng textContent. Chỉ dùng innerHTML khi cần render HTML. Tránh innerText trừ khi bắt buộc.