中间添加一条可以拖拽的分界线,来动态调整两个模块的宽度

在 React 中操作 DOM 元素时,使用 document.querySelector 以及全局事件监听(如 addEventListener)并不推荐,因为这些方法无法与 React 的生命周期很好地协调,可能会导致内存泄漏或影响性能。

可以改为使用 useRefuseEffect 来处理 DOM 元素以及事件监听。

React 代码:

javascript 复制代码
import React, { useRef, useEffect, useState } from 'react';
import styles from './index.module.less';

const ComponentName = () => {
  const containerRef = useRef(null);
  const leftPanelRef = useRef(null);
  const rightPanelRef = useRef(null);
  const dividerRef = useRef(null);

  const [isDragging, setIsDragging] = useState(false);

  useEffect(() => {
    const handleMouseDown = () => {
      setIsDragging(true);
    };

    const handleMouseMove = (e) => {
      if (!isDragging) return;

      const containerRect = containerRef.current.getBoundingClientRect();
      const offsetX = e.clientX - containerRect.left;

      const leftWidth = (offsetX / containerRect.width) * 100;
      const rightWidth = 100 - leftWidth;

      leftPanelRef.current.style.width = `${leftWidth}%`;
      rightPanelRef.current.style.width = `${rightWidth}%`;
    };

    const handleMouseUp = () => {
      setIsDragging(false);
    };

    const divider = dividerRef.current;

    divider.addEventListener('mousedown', handleMouseDown);
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);

    // 清理事件监听器
    return () => {
      divider.removeEventListener('mousedown', handleMouseDown);
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isDragging]);

  return (
    <div className={styles.container} ref={containerRef}>
      <div className={styles.leftPanel} ref={leftPanelRef}></div>
      <div className={styles.divider} ref={dividerRef}></div>
      <div className={styles.rightPanel} ref={rightPanelRef}></div>
    </div>
  );
};

export default ComponentName;

样式css:

javascript 复制代码
.container {
  display: flex;
  width: 100%;
  height: 100vh; 
  position: relative;
}


.leftPanel {
  width: 50%;
  background-color: lightblue;
}

.rightPanel {
  width: 50%;
  background-color: lightgreen;
}

.divider {
  width: 5px;
  background-color: gray;
  cursor: ew-resize; 
  position: relative;
}

注释:

  1. useRef :用来获取 DOM 元素引用,如 containerRefleftPanelRefrightPanelRefdividerRef
  2. useState :用来存储拖动的状态 isDragging
  3. useEffect:用于在组件挂载时添加事件监听器,并在组件卸载时清理这些监听器。这样可以避免内存泄漏或重复监听。
  4. 清理事件 :确保在组件卸载时移除 mousemovemouseup 的事件监听,避免意外行为。
  5. getBoundingClientRect() 是 JavaScript 中用于获取元素的边界信息的方法。它返回一个 DOMRect 对象,包含该元素相对于视口的位置和大小信息,包括 top, right, bottom, left, width, 和 height 等属性。
相关推荐
lolo大魔王33 分钟前
Gin 框架响应格式与 HTML 模板渲染完整实战教程
前端·html·gin
llz_1123 小时前
web-第二次课后作业
前端·后端·web
vipbic8 小时前
别再把“做个H5”挂嘴边了:这个词,官方压根就没有定义过
前端
ZC跨境爬虫9 小时前
跟着 MDN 学CSS day_39:(Flexbox 弹性盒子核心机制)
前端·css·ui·html·tensorflow
小陈同学呦9 小时前
前端如何处理订单状态导航的数据竞态问题
前端·javascript
开发者每周简报10 小时前
网海三部曲·无名宗师传
javascript·人工智能
喵个咪10 小时前
GoWind Toolkit 前端代码生成|Vue3(ElementPlus/Vben)、React(AntDesign)全自动一键生成教程
前端·vue.js·react.js
摆烂大大王11 小时前
玩转 OpenClaw:用 TaskFlow + Heartbeat 打造自动化工作流
前端·人工智能·自动化
zhangxingchao11 小时前
AI 大模型核心六:量化、Workflow 与 Agent、多轮 RAG
前端·人工智能·后端
梦想的颜色12 小时前
TypeScript 完全指南(上):从零开始掌握类型系统
前端·typescript