检测 React 组件外的点击 [英] Detect click outside React component

查看:30
本文介绍了检测 React 组件外的点击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法来检测点击事件是否发生在组件之外,如本 文章.jQuery Nearest() 用于查看来自单击事件的目标是否将 dom 元素作为其父元素之一.如果匹配,则单击事件属于其中一个子项,因此不被视为组件之外.

I'm looking for a way to detect if a click event happened outside of a component, as described in this article. jQuery closest() is used to see if the target from a click event has the dom element as one of its parents. If there is a match the click event belongs to one of the children and is thus not considered to be outside of the component.

所以在我的组件中,我想将一个点击处理程序附加到窗口.当处理程序触发时,我需要将目标与组件的 dom 子项进行比较.

So in my component I want to attach a click handler to window. When the handler fires I need to compare the target with the dom children of my component.

点击事件包含诸如path"之类的属性.它似乎包含事件所经过的 dom 路径.我不确定要比较什么或如何最好地遍历它,我想一​​定有人已经把它放在一个聪明的效用函数中......不是吗?

The click event contains properties like "path" which seems to hold the dom path that the event has travelled. I'm not sure what to compare or how to best traverse it, and I'm thinking someone must have already put that in a clever utility function... No?

推荐答案

React 16.3+ 中的引用用法已更改.

Refs usage in React 16.3+ changed.

以下解决方案使用 ES6,并遵循绑定和通过方法设置 ref 的最佳实践.

The following solution uses ES6 and follows best practices for binding as well as setting the ref through a method.

查看实际效果:

类实现:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

/**
 * Component that alerts if you click outside of it
 */
export default class OutsideAlerter extends Component {
    constructor(props) {
        super(props);

        this.wrapperRef = React.createRef();
        this.setWrapperRef = this.setWrapperRef.bind(this);
        this.handleClickOutside = this.handleClickOutside.bind(this);
    }

    componentDidMount() {
        document.addEventListener('mousedown', this.handleClickOutside);
    }

    componentWillUnmount() {
        document.removeEventListener('mousedown', this.handleClickOutside);
    }

    /**
     * Alert if clicked on outside of element
     */
    handleClickOutside(event) {
        if (this.wrapperRef && !this.wrapperRef.current.contains(event.target)) {
            alert('You clicked outside of me!');
        }
    }

    render() {
        return <div ref={this.wrapperRef}>{this.props.children}</div>;
    }
}

OutsideAlerter.propTypes = {
    children: PropTypes.element.isRequired,
};

钩子实现:

import React, { useRef, useEffect } from "react";

/**
 * Hook that alerts clicks outside of the passed ref
 */
function useOutsideAlerter(ref) {
    useEffect(() => {
        /**
         * Alert if clicked on outside of element
         */
        function handleClickOutside(event) {
            if (ref.current && !ref.current.contains(event.target)) {
                alert("You clicked outside of me!");
            }
        }

        // Bind the event listener
        document.addEventListener("mousedown", handleClickOutside);
        return () => {
            // Unbind the event listener on clean up
            document.removeEventListener("mousedown", handleClickOutside);
        };
    }, [ref]);
}

/**
 * Component that alerts if you click outside of it
 */
export default function OutsideAlerter(props) {
    const wrapperRef = useRef(null);
    useOutsideAlerter(wrapperRef);

    return <div ref={wrapperRef}>{props.children}</div>;
}

这篇关于检测 React 组件外的点击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆