react实现拖拽容器边框改变容器宽度

大概是想要这么个效果(只能拖拽中间的线条 拖动其他无效):


QQ20210606-205549-HD.gif

怎么实现这个效果呢?原生js中已经提供了相应的api:onmousedown(鼠标按下事件)、onmousemove(鼠标按下后元素移动事件)、onmouseup(松开鼠标事件),快忘记的同学正好可以熟悉巩固一波。

这无非就是一个计算, 通过ref拿到父容器宽度和左侧右侧的子容器宽度,移动事件中计算左侧容器宽度和右侧容器宽度。右侧width = 父容器width - 左侧容器width;

以下是组件核心代码:

import React, { useRef, useEffect, useCallback } from 'react'

import './draggleLayout.less';


const drag = ({ leftDom: ref1, rightDom: ref2, contentDom }, draggleLineDom) => {
    const _ref1 = ref1;
    const _ref2 = ref2;
    draggleLineDom.onmousedown = (e) => {
      let _e = e;
      const dir = 'horizontal'; // 设置好方向 可通过变量控制默认水平方向 horizontal | vertical
      const firstX = _e.clientX; // 获取第一次点击的横坐标
      const width = ref2.offsetWidth; // 获取到元素的宽度
      // 移动过程中对左右元素宽度计算赋值
      document.onmousemove = (_event) => {
        _e = _event;
        // 可扩展上下拖动等
        switch (dir) {
          case 'horizontal':
              _ref1.style.width = `${contentDom.offsetWidth - width + (_e.clientX - firstX)}px`;
              _ref2.style.width = `${width - (_e.clientX - firstX)}px`;
            break;
          default:
            break;
        }
      };
      // 在左侧和右侧元素父容器上绑定松开鼠标解绑拖拽事件
      contentDom.onmouseup = () => {
        document.onmousemove = null;
      };
      return false;
    };
};
export default function DraggleLayout({contentDom, leftDom, rightDom}) {
    const draggleLineRef = useRef();
    const init = useCallback(drag.bind(null, { leftDom, rightDom, contentDom }),
     [leftDom, rightDom, contentDom, draggleLineRef.current]);

    useEffect(() => {
        // 初始化绑定拖拽事件
        init(draggleLineRef.current);
    }, []);

    return (
) }

使用示例:

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

import DraggleLayout from './DraggleLayout';
import './demo.less';

export default function Demo() {
    const contentRef = useRef();
    const leftDomRef = useRef();
    const rightDomRef = useRef();
    const [init, setInit] = useState(false);

    useEffect(() => {
        setInit(true);
    }, [])

    const draggleLayoutProps = {
        contentDom: contentRef.current,
        leftDom: leftDomRef.current,
        rightDom: rightDomRef.current,
    };
    return (
        
左侧
{/* 父组件加载完再加载子组件 从而通过ref拿到父组件的dom节点 */} {init && }
右侧
) }

你可能感兴趣的:(react实现拖拽容器边框改变容器宽度)