零经验学 react 的第14天 - 获取 DOM 元素

5 阅读2分钟

一、核心总结

  • Class 组件通过 this.div1 = React.createRef(); <div ref={this.div1}>...</div> 获取DOM 元素,this.div1.current 就是 DOM 元素
  • Function 组件通过 const div1 = useRef(null); <div ref={div1}>...</div> 获取 DOM 元素,div1.current 就是 DOM 元素

二、示例

2.1、函数组件获取 DOM 元素: useRef() 获取 DOM 元素 的方式在函数组件中使用 useRef() 来创建一个 ref 对象,并直接在 JSX 中将其作为 ref 属性传递给需要获取 DOM 元素的标签,然后通过 ref1.current 来访问 DOM 元素。

import {useState, useRef } from 'react';

function Ref1 () {
    const ref1 = useRef(null);
    const [canMove, setCanMove] = useState(false); // 是否可移动
    const [position, setPosition] = useState({x: 0, y: 0}); // 记录鼠标 左右移动和 上下移动距离(x,y)
    const [style, setStyle] = useState({
        top: 0,
        left: 0,
    }); // 记录div的定位样式


    const nomalStyle = {
        width: '100px',
        height: '100px',
        border: '1px solid #000',
        position: 'absolute',
        left: 0,
        top: 0,
        cursor: 'move',
    }

    // 鼠标按下,开始拖拽
    const handleMouseDown = (e) => {
        e.preventDefault();
        const clientX = e.clientX; // 鼠标按下时的X坐标(鼠标距离 左边 的距离)
        const clientY = e.clientY; // 鼠标按下时的Y坐标(鼠标距离 上边 的距离)
        const offsetLeft = ref1.current.offsetLeft; // div元素的左偏移(div左上角 距离 左边 的距离)
        const offsetTop = ref1.current.offsetTop; // div元素的上偏移(div左上角 距离 上边 的距离)
        setCanMove(true);

        // 记录鼠标移动的位置(向左移动、向右移动的距离)
        setPosition({
            x: clientX - offsetLeft,
            y: clientY - offsetTop,
        })
    }

    // 鼠标抬起,停止拖拽
    const handleMouseUp = (e) => {
        setCanMove(false);
        // 重置位置
        setPosition({
            x: 0,
            y: 0
        });
    }

    // 鼠标移动,拖拽中
    const handleMouseMove = (e) => {
        if (canMove) {
            const clientX = e.clientX; // 鼠标按下时的X坐标
            const clientY = e.clientY; // 鼠标按下时的Y坐标
            setStyle({
                top: clientY - position.y + 'px',
                left: clientX - position.x + 'px',
            })
        }
    }

    return (
        <div
            ref={ref1}
            style={{...nomalStyle, ...style}}
            onMouseDown={handleMouseDown}
            onMouseUp={handleMouseUp}
            onMouseMove={handleMouseMove}
        >
            div元素
        </div>
    )
}

export default Ref1;

2.2、类组件获取 DOM 元素:使用 React.createRef() 来创建一个 ref 对象,并将其赋值给组件实例的属性,然后通过 this.ref1.current 来访问 DOM 元素

import React from 'react';

class Ref2 extends React.Component {
    constructor(props) {
    super(props);
        this.ref1 = React.createRef();

        this.state = {
            canMove: false, // 是否可移动
            position: {x: 0, y: 0}, // 记录鼠标 左右移动和 上下移动距离(x,y)
            style: {
                top: 0,
                left: 0,
            } // 记录div的定位样式
        };
    }


    nomalStyle = {
        width: '100px',
        height: '100px',
        border: '1px solid #000',
        position: 'absolute',
        left: 0,
        top: 0,
        cursor: 'move',
    }


    // 鼠标按下,开始拖拽
    handleMouseDown = (e) => {
        e.preventDefault();
        const clientX = e.clientX; // 鼠标按下时的X坐标(鼠标距离 左边 的距离)
        const clientY = e.clientY; // 鼠标按下时的Y坐标(鼠标距离 上边 的距离)
        const offsetLeft = this.ref1.current.offsetLeft; // div元素的左偏移(div左上角 距离 左边 的距离)
        const offsetTop = this.ref1.current.offsetTop; // div元素的上偏移(div左上角 距离 上边 的距离)
        this.setState({
            canMove: true,
            position: {
                x: clientX - offsetLeft,
                y: clientY - offsetTop,
            }
        });
    }


    // 鼠标抬起,停止拖拽
    handleMouseUp = (e) => {
        this.setState({
            canMove: false,
            position: {x: 0, y: 0}
        });
    }


    // 鼠标移动,拖拽中
    handleMouseMove = (e) => {
        const { canMove, position } = this.state;
        if (canMove) {
            const clientX = e.clientX; // 鼠标按下时的X坐标
            const clientY = e.clientY; // 鼠标按下时的Y坐标
            this.setState({
                style: {
                    top: clientY - position.y + 'px',
                    left: clientX - position.x + 'px',
                }
            });
        }
    }

    render() {
        return (
            <div
                ref={this.ref1}
                style={{...this.nomalStyle, ...this.state.style}}
                onMouseDown={this.handleMouseDown}
                onMouseUp={this.handleMouseUp}
                onMouseMove={this.handleMouseMove}
            >
                div元素
            </div>
        );
    }
}

export default Ref2;