简介
你可以通过使用原生的CSS:hover
选择器在React中实现一个基本的悬停事件,但你会遇到两个限制。
- 你不能通过JavaScript进行修改或改变实际的
:hover
选择器 - 你不能用它来在悬停时显示其他组件
这篇文章解释了你可以在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
支持的两个事件处理程序来创建一个悬停事件。它们是onMouseEnter
和onMouseLeave
。
在这个演示中,你将创建一个tooltip,这是一个UI元素,当用户悬停在一个网页元素上时,其内容就会显示出来。
创建一个React工具提示
首先,如果你还没有React项目,你需要建立一个React项目。你可以在CodeSandbox上创建一个React项目,或者使用Create React App建立一个本地项目。
在本文中,我将选择后一种方法。
npm install create-react-app
一旦安装完成,做以下工作。
- 删除
App.js
的内容和index.css
- 在
src
文件夹中创建两个文件夹,并将其命名为css
和component
- 在
css
文件夹中,创建一个新文件,名为Tooltip.css
- 找到先前创建的
component
文件夹,创建一个新的文件,名为Tooltip.js
现在,在Tooltip.js
,让我们写一些代码。我们将在文章的后面为Tooltip.css
写代码。
因为React允许你写基于组件的代码,所以主要的工具提示功能的代码将确实是一个组件。
下一个代码块导入React
、useState
fromReact
、以及我们之前创建的css
文件。当用户选择查看工具提示时,你将需要useState
来管理应用程序的状态。
// src/components/Tooltip.js
import 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
组件内,你将做以下工作。
- 设置一个定时器,以确定工具提示显示和隐藏的时间间隔。
- 设置状态,使用
useState
- 写一个函数来显示工具提示
- 写一个函数来隐藏工具提示
- 返回JSX,其中包含一个单亲的HTML元素和它的孩子。这个父HTML元素将有
onMouseEnter
和onMouseLeave
事件处理程序附加到它身上 - 写下
onMouseEnter
的参数,这将是显示工具提示的函数。 - 写下
onMouseLeave
的参数,它将是隐藏工具提示的函数。 - 定义子元素;也就是说,工具提示的内容将有一个类名和属性,将通过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.js
import 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的SyntheticEvent
(onMouseEnter
和onMouseLeave
)支持的两个事件处理程序来创建它。
在下一节,我将解释如何使用一个名为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.js
和HoverComponent.js
。切换到你的编辑器,在TriggerComponent.js
中输入下一个代码块。
// components/TriggerComponent.js
import React from 'react'
const TriggerComponent = () => {
return (
<p>Hover on me</p>
)
}
export default TriggerComponent
接下来,切换到HoverComponent.js
,并输入以下内容。
// components/HoverComponent.js
import 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.js
import 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中创建悬停事件时,可以在你的武器库中找到。第一个选项是利用React的SyntheticEvent
支持的两个事件处理程序,第二个选项是使用React Hover,一个在npm注册表上的JavaScript库。
The postCreating hover events with SyntheticEvent
and React Hoverappeared first onLogRocket Blog.