当前位置:首页 > React

react实现拖拽按钮

2026-01-27 00:00:40React

React 实现拖拽按钮的方法

使用 HTML5 拖放 API

HTML5 提供了原生的拖放 API,可以直接在 React 中使用。通过 draggable 属性、onDragStartonDragOveronDrop 等事件实现拖拽功能。

import React, { useState } from 'react';

const DraggableButton = () => {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const handleDragStart = (e) => {
    e.dataTransfer.setData('text/plain', 'draggable-button');
  };

  const handleDragOver = (e) => {
    e.preventDefault();
  };

  const handleDrop = (e) => {
    e.preventDefault();
    setPosition({
      x: e.clientX,
      y: e.clientY,
    });
  };

  return (
    <div
      onDragOver={handleDragOver}
      onDrop={handleDrop}
      style={{ width: '100%', height: '500px', border: '1px solid #ccc' }}
    >
      <button
        draggable
        onDragStart={handleDragStart}
        style={{
          position: 'absolute',
          left: `${position.x}px`,
          top: `${position.y}px`,
          cursor: 'move',
        }}
      >
        Drag Me
      </button>
    </div>
  );
};

export default DraggableButton;

使用第三方库 react-dnd

react-dnd 是一个流行的拖拽库,提供了更灵活的拖拽功能,适合复杂场景。

安装依赖:

react实现拖拽按钮

npm install react-dnd react-dnd-html5-backend

实现代码:

import React from 'react';
import { useDrag, useDrop, DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

const ItemTypes = {
  BUTTON: 'button',
};

const DraggableButton = () => {
  const [{ isDragging }, drag] = useDrag(() => ({
    type: ItemTypes.BUTTON,
    collect: (monitor) => ({
      isDragging: !!monitor.isDragging(),
    }),
  }));

  return (
    <button
      ref={drag}
      style={{
        opacity: isDragging ? 0.5 : 1,
        cursor: 'move',
      }}
    >
      Drag Me
    </button>
  );
};

const DropArea = () => {
  const [{ canDrop, isOver }, drop] = useDrop(() => ({
    accept: ItemTypes.BUTTON,
    drop: () => ({ name: 'DropArea' }),
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  }));

  const isActive = canDrop && isOver;
  let backgroundColor = '#fff';
  if (isActive) backgroundColor = '#ddd';
  else if (canDrop) backgroundColor = '#eee';

  return (
    <div
      ref={drop}
      style={{
        width: '100%',
        height: '500px',
        border: '1px solid #ccc',
        backgroundColor,
      }}
    >
      {isActive ? 'Release to drop' : 'Drag button here'}
    </div>
  );
};

const App = () => {
  return (
    <DndProvider backend={HTML5Backend}>
      <div>
        <DraggableButton />
        <DropArea />
      </div>
    </DndProvider>
  );
};

export default App;

使用 react-beautiful-dnd

react-beautiful-dnd 是另一个强大的拖拽库,适合列表和网格中的拖拽排序。

react实现拖拽按钮

安装依赖:

npm install react-beautiful-dnd

实现代码:

import React from 'react';
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';

const items = [
  { id: '1', content: 'Button 1' },
  { id: '2', content: 'Button 2' },
  { id: '3', content: 'Button 3' },
];

const DraggableButtons = () => {
  const [buttons, setButtons] = React.useState(items);

  const handleDragEnd = (result) => {
    if (!result.destination) return;

    const newButtons = Array.from(buttons);
    const [reorderedItem] = newButtons.splice(result.source.index, 1);
    newButtons.splice(result.destination.index, 0, reorderedItem);

    setButtons(newButtons);
  };

  return (
    <DragDropContext onDragEnd={handleDragEnd}>
      <Droppable droppableId="buttons">
        {(provided) => (
          <div {...provided.droppableProps} ref={provided.innerRef}>
            {buttons.map(({ id, content }, index) => (
              <Draggable key={id} draggableId={id} index={index}>
                {(provided) => (
                  <button
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                    style={{
                      ...provided.draggableProps.style,
                      margin: '8px',
                      padding: '8px',
                      cursor: 'move',
                    }}
                  >
                    {content}
                  </button>
                )}
              </Draggable>
            ))}
            {provided.placeholder}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
};

export default DraggableButtons;

自定义拖拽实现

如果需要更简单的自定义拖拽,可以通过鼠标事件实现。

import React, { useState, useRef } from 'react';

const CustomDraggableButton = () => {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [isDragging, setIsDragging] = useState(false);
  const buttonRef = useRef(null);

  const handleMouseDown = (e) => {
    setIsDragging(true);
    const rect = buttonRef.current.getBoundingClientRect();
    const offsetX = e.clientX - rect.left;
    const offsetY = e.clientY - rect.top;

    const handleMouseMove = (e) => {
      if (!isDragging) return;
      setPosition({
        x: e.clientX - offsetX,
        y: e.clientY - offsetY,
      });
    };

    const handleMouseUp = () => {
      setIsDragging(false);
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
  };

  return (
    <div style={{ width: '100%', height: '500px', border: '1px solid #ccc' }}>
      <button
        ref={buttonRef}
        onMouseDown={handleMouseDown}
        style={{
          position: 'absolute',
          left: `${position.x}px`,
          top: `${position.y}px`,
          cursor: isDragging ? 'grabbing' : 'grab',
        }}
      >
        Drag Me
      </button>
    </div>
  );
};

export default CustomDraggableButton;

以上方法可以根据需求选择,HTML5 拖放 API 适合简单场景,第三方库适合复杂交互,自定义实现则提供了最大的灵活性。

标签: 拖拽按钮
分享给朋友:

相关文章

vue实现按钮实现点击功能

vue实现按钮实现点击功能

Vue 按钮点击功能实现 在 Vue 中实现按钮点击功能可以通过多种方式完成,以下是常见的实现方法: 方法一:使用 v-on 指令 通过 v-on:click 或简写 @click 绑定事件:…

css 制作按钮

css 制作按钮

基础按钮样式 使用CSS创建一个基础按钮需要定义padding、background-color、border和border-radius等属性。以下是一个简单示例: .button { pad…

css按钮制作

css按钮制作

基础按钮样式 使用CSS创建基础按钮需要定义padding、background-color、border和border-radius等属性。以下是一个简单的按钮样式示例: .button {…

css图片按钮制作

css图片按钮制作

使用纯CSS创建图片按钮 通过CSS的background-image属性可以轻松将图片设置为按钮背景。关键点在于设置合适的尺寸、去除默认边框并添加交互状态: .image-btn { wid…

vue实现模块拖拽

vue实现模块拖拽

Vue 实现模块拖拽的方法 使用 HTML5 原生拖拽 API HTML5 提供了原生拖拽 API,可以通过 draggable 属性、dragstart、dragend、dragover 和 dro…

vue单选按钮实现

vue单选按钮实现

Vue 单选按钮实现方法 在 Vue 中实现单选按钮可以通过 v-model 指令绑定数据,结合 <input type="radio"> 或第三方组件库完成。以下是几种常见实现方式:…