在 React 应用程序中单击除特定 DOM 节点之外的任何内容上的事件

Click event on anything except specific DOM-node in a React app

本文关键字:任何内 事件 节点 DOM 应用程序 React 单击      更新时间:2023-09-26

在 React 应用程序中捕获和处理"除特定 DOM 节点之外的任何内容"的点击事件的最佳方法是什么?

click事件的处理程序是简单的部分:这可以是任何方法。事件的注册和调用处理程序的触发器是困难的部分。

没有干净的方法来捕获"外面的点击......"事件。但是,您可以应用各种(HTML/CSS/Javascript)技巧:

  • 如果是模态页面/弹出窗口,您还可以渲染一个整页背景矩形(例如略微透明的灰色),它位于整个页面的前面,但在弹出窗口的后面。向此背景添加点击事件侦听器以删除模态 + 灰色背景。
  • 另一种方法是在top-act组件上使用focusout javascript事件:
    • 由 react 渲染的顶级 HTML 组件应该能够获得焦点(需要是一个<a>或类似的 HTML,或者 - 稍微不那么干净 - 需要一个tabindex=...才能工作)
    • 在元素
    • 渲染后立即给予元素焦点(在组件DidMount()'内部)
    • 添加一个 FocusOut 事件侦听器,该侦听器会触发处理程序对外部单击执行某些操作。

一旦组件不再具有焦点,就会触发 focusout 事件: - 如果组件的子组件获得焦点(例如,您单击组件内的某些内容),则也会触发 FocusOut:通常菜单没有问题,但对于带有表单的弹出窗口则不需要 - 如果用户按 TAB,也会触发焦点输出。

没有特定于

React 的方法可以做到这一点;所有 React 事件处理程序都绑定到它们设置的组件。实现此目的的最佳方法取决于您需要完成的工作的详细信息,但解决此问题的一种相当简单的方法是将委派的单击处理程序添加到 body 元素,或包含要从中捕获点击的区域的最接近的祖先元素。您可以将此事件处理程序附加到组件的 componentDidMount() 上,或者在它变得相关时附加,例如,在切换组件的状态以显示下拉菜单之后。

按照您通常的方式附加事件处理程序 - element.addEventListener 或 jQuery 的 $().on 或 what-have-you,并在事件目标触发时对其进行评估,以确定是否需要执行自定义逻辑。

简单的例子,没有jQuery:

componentDidMount() {
   document.body.addEventListener('click', (e) => {
    if (e.target !== [your dom node]) {
     // do something
    }
   }
 }

在 body 元素上附加单个事件处理程序应该不会造成任何性能问题,但对于大多数使用此类内容的情况,最佳做法是在不再需要事件处理程序时将其删除。

相关文章: