当前位置:首页 > JavaScript

js事件实现拖动

2026-02-02 14:12:10JavaScript

使用原生JavaScript实现元素拖动

在JavaScript中实现元素拖动功能需要监听鼠标事件并更新元素位置。以下是实现的基本步骤:

HTML结构

<div id="draggable" style="width: 100px; height: 100px; background: red; position: absolute;"></div>

JavaScript实现

const draggable = document.getElementById('draggable');
let isDragging = false;
let offsetX, offsetY;

draggable.addEventListener('mousedown', (e) => {
    isDragging = true;
    offsetX = e.clientX - draggable.offsetLeft;
    offsetY = e.clientY - draggable.offsetTop;
});

document.addEventListener('mousemove', (e) => {
    if (!isDragging) return;
    draggable.style.left = `${e.clientX - offsetX}px`;
    draggable.style.top = `${e.clientY - offsetY}px`;
});

document.addEventListener('mouseup', () => {
    isDragging = false;
});

使用事件委托优化多元素拖动

当页面中有多个可拖动元素时,可以使用事件委托来优化性能:

document.addEventListener('mousedown', (e) => {
    if (!e.target.classList.contains('draggable')) return;

    const draggable = e.target;
    let isDragging = true;
    const offsetX = e.clientX - draggable.offsetLeft;
    const offsetY = e.clientY - draggable.offsetTop;

    const moveHandler = (e) => {
        if (!isDragging) return;
        draggable.style.left = `${e.clientX - offsetX}px`;
        draggable.style.top = `${e.clientY - offsetY}px`;
    };

    const upHandler = () => {
        isDragging = false;
        document.removeEventListener('mousemove', moveHandler);
        document.removeEventListener('mouseup', upHandler);
    };

    document.addEventListener('mousemove', moveHandler);
    document.addEventListener('mouseup', upHandler);
});

添加边界限制

防止元素被拖出可视区域:

document.addEventListener('mousemove', (e) => {
    if (!isDragging) return;

    let newX = e.clientX - offsetX;
    let newY = e.clientY - offsetY;

    // 限制在视口内
    newX = Math.max(0, Math.min(newX, window.innerWidth - draggable.offsetWidth));
    newY = Math.max(0, Math.min(newY, window.innerHeight - draggable.offsetHeight));

    draggable.style.left = `${newX}px`;
    draggable.style.top = `${newY}px`;
});

使用CSS transform优化性能

使用transform代替top/left可以获得更好的性能:

draggable.addEventListener('mousedown', (e) => {
    isDragging = true;
    const rect = draggable.getBoundingClientRect();
    offsetX = e.clientX - rect.left;
    offsetY = e.clientY - rect.top;
    draggable.style.transform = `translate(${rect.left}px, ${rect.top}px)`;
});

document.addEventListener('mousemove', (e) => {
    if (!isDragging) return;
    draggable.style.transform = `translate(${e.clientX - offsetX}px, ${e.clientY - offsetY}px)`;
});

触摸设备支持

添加触摸事件支持使拖动在移动设备上也能工作:

draggable.addEventListener('touchstart', (e) => {
    isDragging = true;
    const touch = e.touches[0];
    offsetX = touch.clientX - draggable.offsetLeft;
    offsetY = touch.clientY - draggable.offsetTop;
    e.preventDefault();
});

document.addEventListener('touchmove', (e) => {
    if (!isDragging) return;
    const touch = e.touches[0];
    draggable.style.left = `${touch.clientX - offsetX}px`;
    draggable.style.top = `${touch.clientY - offsetY}px`;
    e.preventDefault();
});

document.addEventListener('touchend', () => {
    isDragging = false;
});

使用拖放API实现

HTML5提供了原生的拖放API,但需要更多设置:

js事件实现拖动

draggable.setAttribute('draggable', 'true');

draggable.addEventListener('dragstart', (e) => {
    e.dataTransfer.setData('text/plain', draggable.id);
    e.dataTransfer.effectAllowed = 'move';
});

document.addEventListener('dragover', (e) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
});

document.addEventListener('drop', (e) => {
    e.preventDefault();
    const id = e.dataTransfer.getData('text/plain');
    const element = document.getElementById(id);
    element.style.left = `${e.clientX - element.offsetWidth/2}px`;
    element.style.top = `${e.clientY - element.offsetHeight/2}px`;
});

这些方法提供了从基础到高级的拖动实现方案,可以根据具体需求选择适合的方式。

标签: 拖动事件
分享给朋友:

相关文章

vue实现内容拖动

vue实现内容拖动

Vue 实现内容拖动的方法 使用原生 HTML5 拖放 API 在 Vue 中可以利用 HTML5 的拖放 API 实现基本的拖动功能。通过 draggable 属性、dragstart、dragen…

vue实现全选事件

vue实现全选事件

Vue 实现全选事件 在 Vue 中实现全选功能通常涉及以下关键步骤: 数据绑定与状态管理 使用 v-model 绑定复选框的状态,确保数据与视图同步。通常需要一个数组存储选中项和一个布尔值控制全选…

vue实现页面单击事件

vue实现页面单击事件

Vue 实现页面单击事件的方法 在 Vue 中实现单击事件可以通过 v-on 指令或 @ 简写来完成。以下是几种常见的实现方式: 使用 v-on 指令绑定单击事件 通过 v-on:click 可以直…

vue 实现表格列拖动

vue 实现表格列拖动

实现表格列拖动的核心方法 使用 Vue 实现表格列拖动功能主要依赖 HTML5 的拖放 API 和 Vue 的数据绑定特性。以下是具体实现步骤: 基础拖放 API 设置 为表格列头添加 dragga…

vue点击事件实现跳转

vue点击事件实现跳转

vue点击事件实现跳转 在Vue中实现点击事件跳转可以通过多种方式完成,具体取决于跳转的目标和需求。以下是几种常见的方法: 使用router-link组件 router-link是Vue Rout…

Vue事件传递实现原理

Vue事件传递实现原理

Vue 事件传递的实现原理 Vue 的事件传递主要通过 $emit 和 $on 方法实现,基于发布-订阅模式。子组件通过 $emit 触发事件,父组件通过 v-on 或 @ 监听事件,从而实现父子组件…