创建第二个可拖拽元素后功能失效问题求助
问题解决思路与修正代码
你猜的完全没错,重复使用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
相关产品推荐
相关产品推荐

