You need to enable JavaScript to run this app. 如何将拖拽的HTML元素放置在鼠标释放的对应坐标位置
优惠活动
大模型
产品
解决方案
定价
更多

如何将拖拽的HTML元素放置在鼠标释放的对应坐标位置

解决方案

要实现拖拽元素精准定位到鼠标松开位置,需要调整样式定位规则与拖拽事件的坐标计算逻辑,具体修改如下:

关键调整点

  1. 定位规则修改
  • 放置目标容器.form添加position: relative,作为内部拖拽元素绝对定位的参考基准
  • 可拖拽元素.control添加position: absolute,支持自定义坐标放置
  • 补充缺失的.hide类样式,实现拖拽过程中源元素隐藏的效果
  • 修正原代码中文本输入框重复定义class属性的问题,保证.control类生效
  1. 拖拽逻辑修改
  • 遍历所有可拖拽元素绑定拖拽事件,修复原代码仅对第一个控件生效的问题
  • dragstart阶段记录鼠标点击在拖拽元素内部的偏移量,避免放置时元素左上角与鼠标位置对齐
  • drop阶段计算元素在放置容器内的相对坐标,赋值给元素的left、top样式属性完成定位

完整可运行代码

<style>
.toolbox {
    height: 250px;
    width: 150px;
    border: solid 3px #ccc;
    margin: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
}
.edit {
    width: 140px;
}
.form {
    height: 250px;
    width: 150px;
    border: solid 3px red;
    position: relative;
}
.drop-targets {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    margin: 20px 0;
}
.drag-over {
    border: dashed 3px red;
}
.control {
    position: absolute;
    cursor: move;
}
.hide {
    display: none;
}
</style>
<div class="drop-targets">
    <div id="controls" class="toolbox">
        <input type="button" value="Button 1" id="button1" draggable="true" class="control"> <br>
        <input type="text" value="Edit 1" class="edit control" draggable="true">
    </div>
    <div id="panel" class="form"></div>
</div>
<script>
// 给所有可拖拽元素绑定事件
const items = document.querySelectorAll('.control');
items.forEach(item => {
    item.addEventListener('dragstart', dragStart);
});
function dragStart(e) {
    e.dataTransfer.setData('text/plain', e.target.id);
    // 存储鼠标在元素内部的偏移量
    e.dataTransfer.setData('offsetX', e.offsetX);
    e.dataTransfer.setData('offsetY', e.offsetY);
    setTimeout(() => {
        e.target.classList.add('hide');
    }, 0);
}
const box = document.querySelector('#panel');
box.addEventListener('dragenter', dragEnter);
box.addEventListener('dragover', dragOver);
box.addEventListener('dragleave', dragLeave);
box.addEventListener('drop', drop);
function dragEnter(e) {
    e.preventDefault();
    box.classList.add('drag-over');
}
function dragOver(e) {
    e.preventDefault();
    box.classList.add('drag-over');
}
function dragLeave(e) {
    box.classList.remove('drag-over');
}
function drop(e) {
    e.preventDefault();
    box.classList.remove('drag-over');
    const id = e.dataTransfer.getData('text/plain');
    const draggable = document.getElementById(id);
    // 获取偏移量
    const offsetX = parseInt(e.dataTransfer.getData('offsetX'));
    const offsetY = parseInt(e.dataTransfer.getData('offsetY'));
    // 计算放置容器的坐标
    const panelRect = box.getBoundingClientRect();
    // 计算元素在容器内的相对位置
    const left = e.clientX - panelRect.left - offsetX;
    const top = e.clientY - panelRect.top - offsetY;
    // 设置元素位置
    draggable.style.left = `${left}px`;
    draggable.style.top = `${top}px`;
    box.appendChild(draggable);
    draggable.classList.remove('hide');
}
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 20:06:08