用SyntheticEvent和React Hover创建悬停事件(hover events)

2,548 阅读8分钟

简介

你可以通过使用原生的CSS:hover 选择器在React中实现一个基本的悬停事件,但你会遇到两个限制。

  1. 你不能通过JavaScript进行修改或改变实际的:hover 选择器
  2. 你不能用它来在悬停时显示其他组件

这篇文章解释了你可以在React中克服这些限制的两种替代方法。第一种将利用ReactSyntheticEvent 支持的两个事件处理程序,第二种则采用了一个名为React Hover的npm库。后者允许你在悬停时显示其他组件。

React中事件的快速概述

React处理的事件通常是你在vanilla JavaScript中写的,但有一些关键的区别。

  • 事件处理程序使用骆驼字母大小写惯例来命名。例如,onclick 成为onClick
  • 你不能像在JavaScript中那样返回false 来阻止默认行为;相反,你必须明确地调用preventDefault
  • 你的事件处理程序接收到的实例是SyntheticEvent

什么是SyntheticEvent

SyntheticEvent 是React的跨浏览器包装器,它包裹着浏览器的本地事件,这使得你的事件在所有的浏览器上都能相同地工作。

支持的事件

React支持一系列的SyntheticEvent 类型,但在本文中,我们主要关注的是鼠标事件

可用的鼠标事件在下一个代码块中列出。当你阅读它们时,你会注意到没有onHover ,这将允许你创建一个悬停事件。

onClick onContextMenu
onDoubleClick onDrag
onDragEnd onDragEnter
onDragExit onDragLeave
onDragOver onDragStart
onDrop onMouseDown
onMouseEnter onMouseLeave
onMouseMove onMouseOut
onMouseOver onMouseUp

这就是我们在这里要讨论的--幸运的是,有一个解决方法。

让我们在下一节看看这个。

如何用鼠标创建悬停事件SyntheticEvent

在本节中,我将演示如何使用React的SyntheticEvent 支持的两个事件处理程序来创建一个悬停事件。它们是onMouseEnteronMouseLeave

在这个演示中,你将创建一个tooltip,这是一个UI元素,当用户悬停在一个网页元素上时,其内容就会显示出来。

创建一个React工具提示

首先,如果你还没有React项目,你需要建立一个React项目。你可以在CodeSandbox上创建一个React项目,或者使用Create React App建立一个本地项目。

在本文中,我将选择后一种方法。

npm install create-react-app

一旦安装完成,做以下工作。

  1. 删除App.js 的内容和index.css
  2. src 文件夹中创建两个文件夹,并将其命名为csscomponent
  3. css 文件夹中,创建一个新文件,名为Tooltip.css
  4. 找到先前创建的component 文件夹,创建一个新的文件,名为Tooltip.js

现在,在Tooltip.js ,让我们写一些代码。我们将在文章的后面为Tooltip.css 写代码。

因为React允许你写基于组件的代码,所以主要的工具提示功能的代码将确实是一个组件。

下一个代码块导入ReactuseState fromReact 、以及我们之前创建的css 文件。当用户选择查看工具提示时,你将需要useState 来管理应用程序的状态。

// src/components/Tooltip.jsimport React, { useState } from 'react'
import '../css/Tooltip.css'

有了这些导入语句,你可以开始编写实现工具提示的核心功能的代码。这个核心功能将驻留在一个叫做Tooltip 的组件中,它是一个返回数据的函数。

在这个例子中,它是一个箭头函数。

// src/components/Tooltip.js
import React, { useState } from 'react'
import '../css/Tooltip.css'const Tooltip = (props) => {
   // All the code that will make the
   // tooltip work resides here
}

Tooltip 组件内,你将做以下工作。

  1. 设置一个定时器,以确定工具提示显示和隐藏的时间间隔。
  2. 设置状态,使用useState
  3. 写一个函数来显示工具提示
  4. 写一个函数来隐藏工具提示
  5. 返回JSX,其中包含一个单亲的HTML元素和它的孩子。这个父HTML元素将有onMouseEnteronMouseLeave 事件处理程序附加到它身上
  6. 写下onMouseEnter 的参数,这将是显示工具提示的函数。
  7. 写下onMouseLeave 的参数,它将是隐藏工具提示的函数。
  8. 定义子元素;也就是说,工具提示的内容将有一个类名和属性,将通过CSS进行风格化。

所有这些步骤都在下一个代码块中涉及。

// src/components/Tooltip.js
// Code truncated, check the previous
// code block.
const Tooltip = (props) => {
   // All the code that will make the
   // tooltip work resides here
   
   // Set up timer and state
   let TooltipTimeout;
   const [activeToolTip, setActiveToolTip] = useState(false);
   
   // Write a function to show the tooltip
   const showToolTip = () => {
       TooltipTimeout = setTimeout(() => {
           setActiveToolTip(true);
      }, props.delay || 300);
  };
   
   // Write a function to hide the tooltip
   const hideToolTip = () => {
       setActiveToolTip(false);
       clearInterval(TooltipTimeout);
  };
   
   // Return JSX which contains the HTML
   // data for the tooltip
   
   // Note the usage of the 2 supported event handlers
   // mentioned earlier in this article. They make
   // it is possible to create the hover event in React.
   return (
       <div
           className="Tooltip-Container"
           onMouseEnter={showToolTip}
           onMouseLeave={hideToolTip}
       >
           
          {props.children}
​
          {activeToolTip && (
               <div className={`Tooltip-Content ${props.direction} || "top"}`}>
                   {props.content}
               </div>
           )}
           
       </div>
   );
};
​
// Export the tooltip
export default Tooltip

工具提示现在可以使用了,但在我们部署它之前,我们需要把它导入到App.js (或任何其他你认为有用的组件)。

下一个代码块就可以做到这一点。

// App.jsimport React from "react"
import Tooltip from './components/Tooltip';
import './index.css';
​
const App = () => {
return (
  <div className="App">
    <div className="tooltip-wrapper">
      <Tooltip content="I am a tooltip" direction="top">
        Hover your mouse here
      </Tooltip>
    </div>
  </div>
)
}
​
export default App

现在我们可以开始做样式设计了。

为我们的React工具提示设置样式

切换到Tooltip.css 文件,并写下以下内容。

/* css/Tooltip.css *//**
* The CSS class name starts with a
* capital letter to indicate it's a
* component.
*/
.Tooltip-Container {
   position: relative;
   display: inline-block;
}
​
.Tooltip-Content {
   position: absolute;
   left: 50%;
   padding: 8px;
   color: #ffffff;
   background: #1a1a1a;
   font-size: 0.85em;
   border-radius: 6px;
   transform: translateX(-50%);
   z-index: 1;
   white-space: nowrap;
}
​
.Tooltip-Content::before {
   left: 50%;
   position: absolute;
   content: " ";
   border: 6px solid transparent;
   margin-left: -6px;
}
​
.Tooltip-Content.top {
   top: -30px;
}
​
.Tooltip-Content.top::before {
   top: 100%;
   border-top-color: #1a1a1a;
}
​
/**
* The following styles are
* variations of the tooltip when you
* change the value if the "direction" attribute
* in the App component.
*/
.Tooltip-Content.right {
   top: 50%;
   left: calc(100% + 20px);
   transform: translateY(-50%);
}
​
.Tooltip-Content.right::before {
   top: 50%;
   left: -6px;
   transform: translateY(-50%);
   border-right-color: #1a1a1a;
}
​
.Tooltip-Content.bottom::before {
   bottom: 100%;
   border-bottom-color: #1a1a1a;
}
​
.Tooltip-Content.left {
   top: 50%;
   right: calc(100% + 30px);
   left: auto;
   transform: translateY(-50%);
}
​
.Tooltip-Content.left::before {
   top: 50%;
   right: -12px;
   left: auto;
   transform: translateY(-50%);
   border-left-color: #1a1a1a;
}

之后,切换到index.css ,它应该仍然是空的,并写下以下内容。

/* index.css */
.App {
    font-family: "Trebuchet MS", Verdana, Geneva, Tahoma, sans-serif;
    padding-top: 16px;
    padding-right: 16px;
    padding-bottom: 120px;
    padding-left: 16px;
}
​
.tooltip-wrapper {
    padding: 16px 120px;
}

现在,当你把鼠标悬停在 "把鼠标悬停在这里 "的文字上时,就会出现工具提示。当你把鼠标从文本上移开时,工具提示就消失了。

很好!你不仅实现了这一目标,而且还使我们的生活变得更加美好。尽管React缺乏一个默认的onHover 方法,但你不仅实现了这一点,而且还利用了React的SyntheticEventonMouseEnteronMouseLeave )支持的两个事件处理程序来创建它。

在下一节,我将解释如何使用一个名为React Hover的npm库做类似的事情。

使用React Hover创建悬停事件

正如其官方npm页面上所说的,"React Hover允许你把任何东西变成'可悬停'的对象。" 这个 "任何东西 "可以是普通的HTML或你的应用程序中的其他组件。

在我们深入了解React Hover的语法和它的工作原理之前,让我们先安装它。

npm install --save react-hover

上述命令将React Hover安装在你当前的项目目录中。你可以通过检查你的package.json 文件来验证它的成功安装。

现在,来看看语法。

React Hover的语法

React Hover为创建 "hoverable "对象提供了以下选项。

  • <ReactHover>: 你将把它包裹在两个东西周围,这就是<Trigger><Hover> 组件
  • <Trigger>: 这是对<Trigger> 组件的包装器。
  • <Hover>: 这是对<Hover> 组件的包装器。
  • options :这是<ReactHover> 的一个属性,其值是一个对象,当你把光标移到<Trigger> 组件上时,它决定了<Hover> 组件的行为和位置。该对象接受以下三个属性。
    • followCursor: 接受一个布尔值,决定当你把光标移到<Trigger> 组件上时,<Hover> 组件是否会跟随光标。
    • shiftX: 决定<Hover> 组件在X轴上的位置,即左边或右边。
    • shiftY: 这决定了<Hover> 组件沿Y轴的位置,即顶部或底部
  • type :这个属性确定该组件是一个触发器还是一个悬停器;因此,它的值对于触发器组件来说是<Trigger> ,对于悬停器组件来说是<Hover>

题外话:如果你喜欢使用纯HTML的React Hover而不是一个组件,可以直接将HTML代码分别写在<Trigger><Hover>

实现React Hover

好了,理论够了--是时候写点代码了!

在你的组件文件夹中创建两个文件,即TriggerComponent.jsHoverComponent.js 。切换到你的编辑器,在TriggerComponent.js 中输入下一个代码块。

// components/TriggerComponent.jsimport React from 'react'const TriggerComponent = () => {
   return (
       <p>Hover on me</p>
  )
}
​
export default TriggerComponent

接下来,切换到HoverComponent.js ,并输入以下内容。

// components/HoverComponent.jsimport React from 'react'const HoverComponent = () => {
   return (
       <p>I am a hover component.</p>
  )
}

export default HoverComponent

这些文件都设置好后,你可以在App.js 或你的应用程序中的任何其他位置使用它们。请注意,在App.js ,你将写下你要传递给options 属性的对象。如前所述,当光标移动到<Trigger> ,这个对象将决定被悬停的组件的行为。

既然如此,在下一个代码块中,我们将继续使用App.js

// App.jsimport React from 'react'
import ReactHover, { Trigger, Hover } from 'react-hover'
import TriggerComponent from './components/TriggerComponent'
import HoverComponent from './components/HoverComponent'// Set the option that determines the position
// and behavior of the hover component
const OptionsCursorTrueWithMargins = {
   followCursor: true,
   shiftX: 20,
   shiftY: 0
}
​
// The App function
const App = () => {
   return (
       <ReactHover options={OptionsCursorTrueWithMargins}>
           <Trigger type="trigger">
               <TriggerComponent />
           </Trigger>
           
           <Hover type="hover">
               <HoverComponent />
           </Hover>
       </ReactHover>
  )
};
​
export default App

保存你的文件,根据你的需要添加一些样式,然后在你的网络浏览器中进行测试。你应该有类似于下面的GIF的东西。

React Hover result demo

总结

这篇文章涵盖了两个很好的选择,当你打算在React中创建悬停事件时,可以在你的武器库中找到。第一个选项是利用React的SyntheticEvent 支持的两个事件处理程序,第二个选项是使用React Hover,一个在npm注册表上的JavaScript库。

The postCreating hover events with SyntheticEvent and React Hoverappeared first onLogRocket Blog.