Sự kiện input kích hoạt **mỗi khi giá trị của <input>, <textarea>, <select> thay đổi** (khác với change chỉ kích hoạt khi blur/enter).
Cách gán sự kiện (Best Practice):
// 1. addEventListener (Khuyên dùng - multiple listeners, removable)
element.addEventListener('input', handler);
// 2. Property (Chỉ 1 listener, ghi đè nhau)
element.oninput = handler;
// 3. HTML attribute (Không khuyên dùng - mixing HTML/JS)
<input oninput="handler(this)" />
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>oninput Event JS</title>
<style>
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 20px; }
label { display: block; margin-bottom: 10px; font-weight: 500; }
input { padding: 8px; font-size: 16px; width: 300px; }
#output { margin-top: 10px; padding: 10px; background: #f5f5f5; font-family: monospace; min-height: 100px; }
</style>
</head>
<body>
<h1>Sự kiện oninput trong JavaScript</h1>
<label> Nhập giá trị: <input type="text" id="enterValue" placeholder="Gõ tại đây..." /> </label>
<div id="output"></div>
<script>
const input = document.getElementById('enterValue');
const output = document.getElementById('output');
// Cách 1: addEventListener (Khuyên dùng)
input.addEventListener('input', (event) => {
const value = event.target.value;
output.innerHTML = `
Giá trị: "${value}"
Độ dài: ${value.length}
Event type: ${event.type}
Target: ${event.target.tagName}#${event.target.id}
`;
console.log('Bạn đã nhập:', value);
});
// Demo: Xóa listener sau 10s
setTimeout(() => {
// input.removeEventListener('input', handler); // Cần tham chiếu function
}, 10000);
</script>
</body>
</html>
Kết quả
Mỗi ký tự gõ/xóa → Cập nhật real-time giá trị, độ dài, event info. Console log: "Bạn đã nhập: [giá trị hiện tại]".
input vs change vs keydown/keyup:
| Event | Kích hoạt khi | Thường dùng cho |
|---|---|---|
input | Giá trị thay đổi (gõ, paste, xóa, autocomplete, voice...) | Real-time validation, preview, search, auto-save |
change | Mất focus (blur) VÀ giá trị thay đổi (hoặc Enter cho select) | Form submit, xác nhận cuối cùng |
keydown | Phím được nhấn xuống | Shortcut, game, prevent default |
keyup | Phím được thả ra | Lấy giá trị sau khi phím up (đã cập nhật) |
beforeinput | Trước khi giá trị thay đổi (có thể cancel) | Input mask, filter ký tự |
Ứng dụng thực tế:
// 1. Real-time search/filter
searchInput.addEventListener('input', debounce((e) => {
filterList(e.target.value);
}, 300));
// 2. Character counter
textarea.addEventListener('input', () => {
counter.textContent = `${textarea.value.length}/200`;
counter.style.color = textarea.value.length > 200 ? 'red' : 'inherit';
});
// 3. Auto-format (input mask)
phoneInput.addEventListener('input', (e) => {
let v = e.target.value.replace(/\D/g, '');
if (v.length > 3) v = v.slice(0,3) + '-' + v.slice(3);
if (v.length > 7) v = v.slice(0,7) + '-' + v.slice(7);
e.target.value = v.slice(0, 12);
});
// 4. Password strength meter
passwordInput.addEventListener('input', (e) => {
const strength = calculateStrength(e.target.value);
updateMeter(strength);
});
Lưu ý:
inputkhông bubble trong một số trường hợp cũ (IE) - hiện đại OK- Không kích hoạt khi set value bằng JS:
input.value = "x"→ cầninput.dispatchEvent(new Event('input')) event.target.valueluôn là string