You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拖拽功能在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:50:22