原生js实现React拖拽效果(resize)附带完整的demo

本文介绍了在找不到合适React组件的情况下,如何利用原生JavaScript实现拖拽resize功能。作者详细描述了遇到的问题,如react-rnd的布局问题,以及如何将基于HTML的拖拽resize代码转化为React组件。文章提供了核心代码片段,并分享了一个完整的demo链接。
摘要由CSDN通过智能技术生成

想找一个可以resize块的组件,找了好几天都没找到合适的。

尝试过的开源组件:
“react-rnd”:被拖拽的块采用的布局方式是“position:absolute”,更改布局的话拖拽的事件会失效,没有仔细去研究原理。但是我是在不知道这个布局怎么去比较好的兼容页面的flex布局,所以放弃了这个组件

网上查到的大多数拖拽组件是Draggable拖拽,多用于块的拖拽排序等,而我需要的是resize块的大小,两者截然不同。

看了有人用原生js写的html文件,上面的效果还是不错的,所以读懂了代码,在此代码的结构上进行了改动,运用到了react中。

核心代码:

var theobject = null;
var dir;
    //拖拽的时候初始化了一个object
  resizeObject = () => {
    this.el = null; //pointer to the object
    this.dir = "";      //type of current resize (n, s, e, w, ne, nw, se, sw)
    this.grabx = null;     //Some useful values
    this.graby = null;
    this.width = null;
    this.height = null;
    this.left = null
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
下面是一个使用原生JS实现框选功能的例子,你可以在React中将其包装成组件: ```javascript import React, { useEffect, useRef, useState } from 'react'; import './SelectBox.css'; const SelectBox = ({ children, onSelect }) => { const [selection, setSelection] = useState({ top: 0, left: 0, width: 0, height: 0 }); const [startPos, setStartPos] = useState({ x: 0, y: 0 }); const [dragging, setDragging] = useState(false); const containerRef = useRef(null); useEffect(() => { const handleMouseMove = (e) => { if (dragging) { const currentPos = { x: e.clientX, y: e.clientY }; const width = Math.abs(currentPos.x - startPos.x); const height = Math.abs(currentPos.y - startPos.y); const left = Math.min(currentPos.x, startPos.x); const top = Math.min(currentPos.y, startPos.y); setSelection({ top, left, width, height }); } }; const handleMouseUp = (e) => { setDragging(false); onSelect({ ...selection }); setSelection({ top: 0, left: 0, width: 0, height: 0 }); }; document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); return () => { document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); }; }, [dragging, onSelect, selection, startPos]); const handleMouseDown = (e) => { e.preventDefault(); setDragging(true); setStartPos({ x: e.clientX, y: e.clientY }); }; const containerStyle = { position: 'relative', }; const selectionStyle = { position: 'absolute', backgroundColor: 'rgba(0, 0, 255, 0.2)', border: '1px dashed blue', ...selection, }; return ( <div className="container" ref={containerRef} onMouseDown={handleMouseDown} style={containerStyle}> {children} {dragging && <div className="selection" style={selectionStyle} />} </div> ); }; export default SelectBox; ``` 这个组件将子组件包裹在一个容器中,并在容器中实现了框选功能。当用户按下鼠标左键并拖动时,组件会计算出框选区域的位置和大小,并用一个半透明的矩形覆盖在子组件上。当用户松开鼠标左键时,组件会调用`onSelect`回调函数,并将框选区域的位置和大小作为参数传递给它。 你可以像使用普通的`div`组件一样使用`SelectBox`组件。例如,你可以这样写: ```javascript import React from 'react'; import SelectBox from './SelectBox'; const App = () => { const items = [ { id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }, { id: 3, name: 'Item 3' }, { id: 4, name: 'Item 4' }, { id: 5, name: 'Item 5' }, ]; const handleSelect = (selection) => { console.log(selection); }; return ( <SelectBox onSelect={handleSelect}> {items.map((item) => ( <div key={item.id} style={{ marginBottom: 10 }}> <input type="checkbox" onChange={() => {}} /> <span style={{ marginLeft: 10 }}>{item.name}</span> </div> ))} </SelectBox> ); }; export default App; ``` 在这个例子中,我们将一个复选框列表作为子组件传递给`SelectBox`组件,并在`handleSelect`回调函数中打印出框选区域的位置和大小。当用户用鼠标左键框选一个或多个复选框时,组件会调用`handleSelect`回调函数,并将框选区域的位置和大小作为参数传递给它。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值