拖拽功能在jQuery .on()中正常,原生JS实现遇问题求解决
原生JS拖拽上传转换问题修复
我正在把一套可用的jQuery拖拽上传代码改成原生JS实现,但转换后功能失效了,需要排查问题。
可用的jQuery实现代码
function readURL(input) { if (input.files && input.files[0]) { let reader = new FileReader(); reader.onload = function(e) { let listIcon = e.target.result; document.getElementById("list-image").src = listIcon; document.querySelector(".image-upload-wrap").classList.remove("image-dropping"); }; reader.readAsDataURL(input.files[0]); } } let dragTimer; $(document).on("dragover", function(e) { let dt = e.originalEvent.dataTransfer; if (dt.types && (dt.types.indexOf ? dt.types.indexOf("Files") != -1 : dt.types.contains("Files"))) { document.querySelector(".image-upload-wrap").classList.add("image-dropping"); window.clearTimeout(dragTimer); } }); $(document).on("dragleave", function(e) { dragTimer = window.setTimeout(function() { document.querySelector(".image-upload-wrap").classList.remove("image-dropping"); }, 25); });
失效的原生JS代码(问题出在此处)
let dragTimer; document.addEventListener("dragstart", function(e) { ev.dataTransfer.setData("image", e.target.id); }); document.addEventListener("dragover", function(e) { e.preventDefault(); let dt = e.originalEvent.dataTransfer; if (dt.types && (dt.types.indexOf ? dt.types.indexOf("Files") != -1 : dt.types.contains("Files"))) { document.querySelector(".image-upload-wrap").classList.add("image-dropping"); window.clearTimeout(dragTimer); } }); document.addEventListener("dragleave", function(e) { e.preventDefault(); dragTimer = window.setTimeout(function() { document.querySelector(".image-upload-wrap").classList.remove("image-dropping"); }, 25); });
问题排查与修复方案
原生代码里有几个关键错误:
- 多余且错误的
dragstart事件监听:原jQuery代码没有这个逻辑,而且代码里的ev是未定义变量,直接删掉即可。 - 错误获取
dataTransfer:jQuery的事件对象是封装过的,需要用e.originalEvent拿到原生事件,但原生JS里直接用e.dataTransfer就行,不需要额外取originalEvent。 dragleave里无需preventDefault:这个操作会干扰默认拖拽行为,原jQuery代码也没有做这个处理。
修复后的原生JS代码
function readURL(input) { if (input.files && input.files[0]) { let reader = new FileReader(); reader.onload = function(e) { let listIcon = e.target.result; document.getElementById("list-image").src = listIcon; document.querySelector(".image-upload-wrap").classList.remove("image-dropping"); }; reader.readAsDataURL(input.files[0]); } } let dragTimer; document.addEventListener("dragover", function(e) { e.preventDefault(); // 必须阻止默认行为,否则无法触发后续drop事件 const dt = e.dataTransfer; // 用更现代的includes方法兼容主流浏览器 if (dt.types && (dt.types.includes ? dt.types.includes("Files") : dt.types.contains("Files"))) { document.querySelector(".image-upload-wrap").classList.add("image-dropping"); window.clearTimeout(dragTimer); } }); document.addEventListener("dragleave", function(e) { dragTimer = window.setTimeout(function() { document.querySelector(".image-upload-wrap").classList.remove("image-dropping"); }, 25); }); // 补充文件掉落的处理逻辑(原功能完整需要) document.addEventListener("drop", function(e) { e.preventDefault(); document.querySelector(".image-upload-wrap").classList.remove("image-dropping"); if (e.dataTransfer.files.length > 0) { readURL({ files: e.dataTransfer.files }); // 复用已有的readURL函数 } });
内容的提问来源于stack exchange,提问作者Yash Raj Bharti
相关产品推荐
相关产品推荐

