Nguyên nhân chính: Thiếu xử lý sự kiện dragover. Mặc định trình duyệt chặn drop trừ khi dragover gọi preventDefault().
Code sai (không drop được)
<div id="dropzone">Kéo thả vào đây</div>
<script>
document.getElementById('dropzone').addEventListener('drop', function(e) {
e.preventDefault();
console.log('Dropped:', e.dataTransfer.files);
});
// THIẾU dragover handler!
</script>
Code đúng
<div id="dropzone">Kéo thả vào đây</div>
<script>
var dropzone = document.getElementById('dropzone');
// BẮT BUỘC: preventDefault trên dragover
dropzone.addEventListener('dragover', function(e) {
e.preventDefault(); // Cho phép drop
e.dataTransfer.dropEffect = 'copy'; // Hiển thị con trỏ copy
});
dropzone.addEventListener('drop', function(e) {
e.preventDefault();
var files = e.dataTransfer.files;
console.log('Dropped files:', files);
// Xử lý files...
});
</script>
Các cách preventDefault()
<div ondragover="return false">(inline handler, trả về false = preventDefault).<div ondragover="event.preventDefault()">(inline gọi method).addEventListener('dragover', e => e.preventDefault())(khuyên dùng, tách biệt).
Quy trình Drag & Drop chuẩn
- Kéo:
dragstarttrên element nguồn → setdataTransfer.setData(). - Vượt qua target:
dragenter,dragover(phảipreventDefault()). - Thả:
droptrên target →preventDefault(), đọcdataTransfer.getData(). - Kết thúc:
dragendtrên nguồn.