Reactjs Antd Table onRow外部点击?
Reactjs Antd Table onRow外部点击?
我正在寻找一种方法来检测是否发生了在组件之外的点击事件,就像这篇文章中所描述的那样。使用jQuery closest()可以查看点击事件的目标是否具有dom元素作为其父元素之一。如果有匹配项,则单击事件属于其中一个子项,因此不被认为是在组件之外。
因此,在我的组件中,我希望将一个点击处理程序附加到window
上。当处理程序触发时,我需要将目标与我的组件的dom子项进行比较。
点击事件包含像\"path\"这样的属性,它似乎保存事件所经过的dom路径。我不确定要比较什么或者如何最好地遍历它,并且我认为某个聪明的实用程序函数中必须已经将其放入... 不是吗?
admin 更改状态以发布 2023年5月22日
我也曾困在同一个问题上。我来晚了,但对我来说这是一个非常好的解决方案。希望它能对其他人有帮助。您需要从react-dom
导入findDOMNode
。
import ReactDOM from 'react-dom'; // ... componentDidMount() { document.addEventListener('click', this.handleClickOutside, true); } componentWillUnmount() { document.removeEventListener('click', this.handleClickOutside, true); } handleClickOutside = event => { const domNode = ReactDOM.findDOMNode(this); if (!domNode || !domNode.contains(event.target)) { this.setState({ visible: false }); } }
React Hooks 方法(16.8 +)
您可以创建一个名为useComponentVisible
的可重用钩子。
import { useState, useEffect, useRef } from 'react'; export default function useComponentVisible(initialIsVisible) { const [isComponentVisible, setIsComponentVisible] = useState(initialIsVisible); const ref = useRef(null); const handleClickOutside = (event) => { if (ref.current && !ref.current.contains(event.target)) { setIsComponentVisible(false); } }; useEffect(() => { document.addEventListener('click', handleClickOutside, true); return () => { document.removeEventListener('click', handleClickOutside, true); }; }, []); return { ref, isComponentVisible, setIsComponentVisible }; }
然后在您希望添加功能的组件中执行以下操作:
const DropDown = () => { const { ref, isComponentVisible } = useComponentVisible(true); return ( {isComponentVisible && (Dropdown Component
)} ); }
在此codesandbox中查找示例。
以下的解决方案使用ES6,并遵循绑定以及通过方法设置ref的最佳实践。
要了解它的实际使用:
Hooks实现:
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 {props.children}; }
Class实现:
16.3之后
import React, { Component } from "react"; /** * Component that alerts if you click outside of it */ export default class OutsideAlerter extends Component { constructor(props) { super(props); this.wrapperRef = React.createRef(); 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 {this.props.children}; } }
16.3之前
import React, { Component } from "react"; /** * Component that alerts if you click outside of it */ export default class OutsideAlerter extends Component { constructor(props) { super(props); this.setWrapperRef = this.setWrapperRef.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); } componentDidMount() { document.addEventListener("mousedown", this.handleClickOutside); } componentWillUnmount() { document.removeEventListener("mousedown", this.handleClickOutside); } /** * Set the wrapper ref */ setWrapperRef(node) { this.wrapperRef = node; } /** * Alert if clicked on outside of element */ handleClickOutside(event) { if (this.wrapperRef && !this.wrapperRef.contains(event.target)) { alert("You clicked outside of me!"); } } render() { return {this.props.children}; } }