useHover 监听鼠标悬停

1. 需求描述--有啥用?

使用场景 当用户将鼠标放置在产品预览图上时,我们在预览图中以鼠标为中心,以 50 像素为半径划出部分区域并将该区域进行放大,将放大的图片展示在预览图旁边。当用户将鼠标在预览图上移动鼠标时,他可以改到对应区块的细节部分。

2. 需求分析--分析问题!

我们需要一个工具函数(或者hooks),这个工具函数(或者hooks)需要有以下几个功能:

【入参】

参数 含义
target DOM 节点或者 Ref 对象
options 额外的配置项

options额外参数

参数 含义 类型
onEnter hover 时触发 ( )=>{ }
onLeave 取消 hover 时触发 ( )=>{ }
onChange onChange ( )=>{ }

【返回值】

参数 含义 类型
isHovering 鼠标元素是否处于 hover boolean

综上所述,梳理思路如下:

首先我们要理解 hover 事件的本质其实就是鼠标进入事件和鼠标离开事件的语法糖

其次我们可以通过为传入的 dom 元素添加对应的事件处理函数达到我们的目的。

最后 当事件回调函数被触发时,执行对应的用户传入的函数后,还要更新鼠标元素是否处于 hover 的状态。

3. 手动实现--独立自主!

jsx 复制代码
import React, { useEffect, useRef, useState } from 'react'

function useHover(...props) {
  let [dom, options] = props
  // 是否处于悬停状态
  let [isHovering, setIsHovering] = useState(false)
  // 悬停状态发生改变时,执行用户传入的函数
  useEffect(() => {
    options?.onChange()
  }, [isHovering])

  useEffect(() => {
    if (!dom.current) return
    //  dom 节点存在时,为 dom 节点注册鼠标移入事件
    dom.current.onmouseenter = () => {
      setIsHovering(true)
      options?.onEnter()
    }
    //  dom 节点存在时,为 dom 节点注册鼠标移出事件
    dom.current.onmouseleave = () => {
      setIsHovering(false)
      options?.onLeave()
    }
  }, [dom])
  // 悬停状态作为 hooks 的返回值!
  return isHovering
}


// 测试案例
export default () => {
  let dom = useRef(null)
  let isHovering = useHover(dom, {
    onEnter: () => console.log('onEnter'),
    onLeave: () => console.log('onLeave'),
    onChange: () => console.log('onChange'),
  })
  return <>
    <div ref={dom} style={{ width: '550px', height: '550px', backgroundColor: 'pink' }}>标题</div>
    <span>{isHovering ? 'yse' : 'no'}</span>
  </>
}
相关推荐
一孤程11 分钟前
Airtest自动化测试第五篇:小程序与Web测试——跨平台自动化全覆盖
前端·自动化测试·小程序·自动化·测试·airtest
IT_陈寒13 分钟前
SpringBoot自动配置不是你以为的那样的智能
前端·人工智能·后端
yume_sibai1 小时前
大屏数据可视化 - 边框红绿呼吸灯实现详解
前端·信息可视化·typescript
竹林8181 小时前
从 ethers.js 迁移到 Viem:一个签名验证 Bug 让我彻底放弃旧爱
javascript
Hyyy2 小时前
很多Desktop都在上的Computer Use是什么
前端·llm
慢功夫2 小时前
开篇:VS Code 为什么不是一个普通 React App
前端·visual studio code
你挚爱的强哥2 小时前
Vue2 实现 1.5s 十连击监听(连续点击若干次),封装通用可复用点击检测工具,不用 data!Vue 封装通用连击监听方法,支持自定义时长与点击次数
前端·javascript·vue.js
半个落月2 小时前
用 LangChain.js 手写一个能读写文件和执行命令的 Mini Cursor
javascript·人工智能·后端
天外天-亮2 小时前
HBuilder X 使用 uview-plus 方式
开发语言·javascript·hbuilder x·uview-plus
huashengzsj2 小时前
Shopify个人建站如何搭建独立站:从零开始的完整指南
前端·网络·人工智能