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

创建第二个可拖拽元素后功能失效问题求助

问题解决思路与修正代码

你猜的完全没错,重复使用id="mydiv"是导致问题的核心原因之一,另外还有两个关键问题让拖拽功能失效:

  • 你只在页面初始化时调用了一次dragElement(document.getElementById("mydiv")),只有第一个元素会绑定拖拽事件,后续创建的元素完全没被处理。
  • 使用document.body.innerHTML += ...更新DOM时,浏览器会重新渲染整个body的内容,之前已经绑定的拖拽事件会全部丢失。

下面是修正后的完整代码:

HTML与脚本完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <title>create dragable DOMS</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
  <div>
    <button onClick="createDiv()"> create </button>
  </div>
  <script>
    // 计数器,确保每个元素ID唯一
    let divCounter = 1;

    function createDiv() {
      // 生成唯一ID,用计数器区分每个元素
      const divId = `mydiv-${divCounter}`;
      const headerId = `${divId}-header`;
      let dom = `<div id="${divId}" style="position:absolute; top:${20 + (divCounter-1)*80}px; left:20px; border:1px solid #ccc; padding:8px;">
                  <div id="${headerId}" class="Filter" style="cursor:move; padding:4px; background:#f0f0f0;">
                    <button>test ${divCounter}</button>
                  </div>
                </div>`;
      let template = document.createElement("template");
      template.innerHTML = dom.trim();
      // 用appendChild添加,保留原有DOM和事件
      document.body.appendChild(template.content.firstChild);
      // 给新创建的元素绑定拖拽事件
      dragElement(document.getElementById(divId));
      divCounter++;
    }

    function dragElement(elmnt) {
      let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
      const header = document.getElementById(elmnt.id + "-header");
      if (header) {
        header.onmousedown = dragMouseDown;
      } else {
        elmnt.onmousedown = dragMouseDown;
      }

      function dragMouseDown(e) {
        e = e || window.event;
        e.preventDefault();
        pos3 = e.clientX;
        pos4 = e.clientY;
        document.onmouseup = closeDragElement;
        document.onmousemove = elementDrag;
      }

      function elementDrag(e) {
        e = e || window.event;
        e.preventDefault();
        pos1 = pos3 - e.clientX;
        pos2 = pos4 - e.clientY;
        pos3 = e.clientX;
        pos4 = e.clientY;
        elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
        elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
      }

      function closeDragElement() {
        document.onmouseup = null;
        document.onmousemove = null;
      }
    }
  </script>
</body>
</html>

关键修改点说明

  • 唯一ID生成:用divCounter计数器给每个新元素生成唯一ID(如mydiv-1、mydiv-2),彻底避免ID重复问题。
  • DOM更新方式:改用appendChild添加新元素,不会破坏原有DOM结构和已绑定的事件,解决了事件丢失的问题。
  • 实时绑定拖拽:创建完新元素后立即调用dragElement,给当前元素绑定拖拽事件,确保每个新元素都能拖拽。
  • 添加基础定位样式:给拖拽元素加了position:absolute和初始位置偏移,避免新元素重叠,同时保证拖拽位置计算正常。

另外注意:你引入了多个jQuery版本和jQuery UI,但当前代码没用到这些库,完全可以移除,减少不必要的资源加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:35:21