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

解决replaceChild报错并实现无需setData/getData的图片拖拽互换功能

报错原因

你遇到的DOMException是因为drop事件触发时,e.target通常是你点中的<img>元素,而<img>是外层.listitemClass div的子元素,并不是#imageListId的直接子节点,调用replaceChild时传入<img>作为被替换节点,自然不符合API要求,因此抛出错误。

方案说明

  1. 完全可以不用setData和getData实现功能,直接通过全局变量存储当前拖拽的元素节点即可,逻辑更简洁。
  2. 推荐直接把包裹图片的.listitemClass div同时作为可拖拽对象和可放置对象,所有拖拽相关事件都绑定在div层即可,不需要在img层绑定事件,避免事件触发对象层级混乱。

修复后完整代码

HTML

<div class="height"></div><br>

<div id="imageListId">
  <div id="div1" class="listitemClass" draggable="true" ondragstart="dragStart(event)" ondragend="dragEnd()" ondrop="drop(event)" ondragover="allowDrop(event)">
    <img id="drag1" src="https://images.fastcompany.net/image/upload/w_1280,f_auto,q_auto,fl_lossy/w_596,c_limit,q_auto:best,f_auto/fc/3034007-inline-i-applelogo.jpg" alt="">
  </div>

  <div id="div2" class="listitemClass" draggable="true" ondragstart="dragStart(event)" ondragend="dragEnd()" ondrop="drop(event)" ondragover="allowDrop(event)">
    <img id="drag2" src="https://www.tailorbrands.com/wp-content/uploads/2020/07/mcdonalds-logo.jpg" alt="">
  </div>

  <div id="div3" class="listitemClass" draggable="true" ondragstart="dragStart(event)" ondragend="dragEnd()" ondrop="drop(event)" ondragover="allowDrop(event)">
    <img id="drag3" src="https://cdn.dribbble.com/users/24078/screenshots/15522433/media/e92e58ec9d338a234945ae3d3ffd5be3.jpg?compress=1&resize=400x300" alt="">
  </div>
</div>

JavaScript

// 存储当前正在拖拽的div节点
let draggingEl = null;

function dragStart(e) {
  draggingEl = e.target;
  // 拖拽时添加半透效果,提升交互体验
  draggingEl.style.opacity = '0.5';
}

function dragEnd() {
  // 拖拽结束恢复元素样式
  draggingEl.style.opacity = '1';
  draggingEl = null;
}

function allowDrop(e) {
  e.preventDefault();
}

function drop(e) {
  e.preventDefault();
  // 获取当前放置目标的div节点
  const dropTarget = e.currentTarget;
  // 拖拽到自身时不做处理
  if (draggingEl === dropTarget) return;

  const parentContainer = document.getElementById("imageListId");
  // 记录两个元素的相邻节点作为位置标记
  const dragNext = draggingEl.nextSibling;
  const dropNext = dropTarget.nextSibling;

  // 互换两个元素的位置
  parentContainer.insertBefore(draggingEl, dropNext);
  parentContainer.insertBefore(dropTarget, dragNext);
}

CSS(无修改)

body {
  text-align: center;
}

/* image dimension */
img {
  height: 200px;
  width: 350px;
}

/* imagelistId styling */
#imageListId {
  margin: 0;
  padding: 0;
  list-style-type: none;
}

#imageListId div {
  margin: 0 4px 4px 4px;
  padding: 0.4em;
  display: inline-block;
}

/* Output order styling */
.listitemClass {
  border: 1px solid #006400;
  width: 350px;
}

.height {
  height: 10px;
}

内容的提问来源于stack exchange,提问作者Sumit basera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:54:05