当前位置: 首页 > news >正文

React强大且灵活hooks库——ahooks入门实践之DOM类hook(dom)详解

什么是 ahooks?

ahooks 是一个 React Hooks 库,提供了大量实用的自定义 hooks,帮助开发者更高效地构建 React 应用。其中 DOM 类 hooks 是 ahooks 的一个重要分类,专门用于处理 DOM 相关操作,如事件监听、元素状态、拖拽等。

安装 ahooks

npm install ahooks

DOM 类 hooks 详解

useEventListener – 事件监听器

useEventListener 用于添加事件监听器。

import React, { useState, useRef } from "react";
import { useEventListener } from "ahooks";
import { Card, Button } from "antd";const UseEventListenerExample = () => {const [count, setCount] = useState(0);const buttonRef = useRef(null);useEventListener("click",() => {setCount((prev) => prev + 1);},{ target: buttonRef });return (<Card title="useEventListener 事件监听器"><div style={{ marginBottom: 16 }}><p><strong>点击次数:</strong> {count}</p></div><Button ref={buttonRef}>点击我增加计数</Button></Card>);
};

useClickAway – 点击外部

useClickAway 用于检测点击元素外部的事件。

import { useClickAway } from "ahooks";
import { useRef, useState } from "react";function Dropdown() {const [visible, setVisible] = useState(false);const ref = useRef();useClickAway(() => {setVisible(false);}, ref);return (<div ref={ref} style={{ position: "relative" }}><button onClick={() => setVisible(!visible)}>下拉菜单</button>{visible && (<divstyle={{position: "absolute",top: "100%",border: "1px solid #ccc",}}><div>菜单项 1</div><div>菜单项 2</div><div>菜单项 3</div></div>)}</div>);
}

useDocumentVisibility – 文档可见性

useDocumentVisibility 用于监听文档可见性状态。

import React from "react";
import { useDocumentVisibility } from "ahooks";
import { Card } from "antd";const UseDocumentVisibilityExample = () => {const documentVisibility = useDocumentVisibility();return (<Card title="useDocumentVisibility 文档可见性"><div style={{ marginBottom: 16 }}><p><strong>当前状态:</strong> {documentVisibility}</p><p style={{ fontSize: "12px", color: "#666" }}>切换标签页或最小化窗口查看状态变化</p></div></Card>);
};

useDrop & useDrag – 拖拽

useDrop 和 useDrag 用于处理拖拽操作。

import React, { useState } from "react";
import { useDrop, useDrag } from "ahooks";
import { Card } from "antd";const UseDropDragExample = () => {const [isOver, setIsOver] = useState(false);const [isDragging, setIsDragging] = useState(false);const dropRef = useDrop({onDom: (content) => {console.log("拖拽内容:", content);setIsOver(false);},onDragEnter: () => setIsOver(true),onDragLeave: () => setIsOver(false),});const dragRef = useDrag({onDragStart: () => setIsDragging(true),onDragEnd: () => setIsDragging(false),});return (<Card title="useDrop & useDrag 拖拽"><div style={{ display: "flex", gap: 16 }}><divref={dragRef}draggableonDragStart={(e) => {e.dataTransfer.setData("text/plain", "拖拽的内容");setIsDragging(true);}}onDragEnd={() => setIsDragging(false)}style={{padding: 16,backgroundColor: isDragging ? "#e6f7ff" : "#f0f0f0",border: "2px dashed #d9d9d9",borderRadius: 4,cursor: "move",userSelect: "none",}}>拖拽我</div><divref={dropRef}onDragOver={(e) => e.preventDefault()}onDrop={(e) => {e.preventDefault();const data = e.dataTransfer.getData("text/plain");console.log("放置的内容:", data);setIsOver(false);}}onDragEnter={(e) => {e.preventDefault();setIsOver(true);}}onDragLeave={(e) => {e.preventDefault();setIsOver(false);}}style={{padding: 16,backgroundColor: isOver ? "#f6ffed" : "#f0f0f0",border: "2px dashed #d9d9d9",borderRadius: 4,minHeight: 60,}}>放置区域</div></div></Card>);
};

useEventTarget – 事件目标

useEventTarget 用于处理表单输入事件。

import React from "react";
import { useEventTarget } from "ahooks";
import { Card, Input, Button } from "antd";const UseEventTargetExample = () => {const [value, { onChange, reset }] = useEventTarget({initialValue: "",});return (<Card title="useEventTarget 事件目标"><div style={{ marginBottom: 16 }}><Inputvalue={value}onChange={onChange}placeholder="输入内容"style={{ marginBottom: 8 }}/><p><strong>当前值:</strong> {value}</p></div><Button onClick={reset}>重置</Button></Card>);
};

useExternal – 外部资源

useExternal 用于动态加载外部资源。

import React, { useState } from "react";
import { useExternal } from "ahooks";
import { Card, Button } from "antd";const UseExternalExample = () => {const [path, setPath] = useState("");const status = useExternal(path);return (<Card title="useExternal 外部资源"><div style={{ marginBottom: 16 }}><p><strong>状态:</strong> <b>{status}</b></p><p style={{ fontSize: "12px", color: "#666" }}>加载 Bootstrap CSS 查看徽章样式效果</p></div><div style={{ marginBottom: 16 }}><divclassName="bd-example flex gap-2"style={{ wordBreak: "break-word" }}><span className="badge bg-primary">Primary</span><span className="badge bg-secondary">Secondary</span><span className="badge bg-success">Success</span><span className="badge bg-danger">Danger</span><span className="badge bg-warning text-dark">Warning</span><span className="badge bg-info text-dark">Info</span><span className="badge bg-light text-dark">Light</span><span className="badge bg-dark">Dark</span></div></div><div><ButtononClick={() =>setPath("https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css")}style={{ marginRight: 8 }}>加载 Bootstrap CSS</Button><Button onClick={() => setPath("")}>卸载</Button></div></Card>);
};

useTitle – 页面标题

useTitle 用于动态设置页面标题。

import React, { useState } from "react";
import { useTitle } from "ahooks";
import { Card, Input, Button } from "antd";const UseTitleExample = () => {const [title, setTitle] = useState("ahooks 示例");useTitle(title);return (<Card title="useTitle 页面标题"><div style={{ marginBottom: 16 }}><Inputvalue={title}onChange={(e) => setTitle(e.target.value)}placeholder="输入页面标题"style={{ marginBottom: 8 }}/><p><strong>当前标题:</strong> {title}</p></div><Button onClick={() => setTitle("ahooks 示例")}>重置标题</Button></Card>);
};

useFavicon – 网站图标

useFavicon 用于动态设置网站图标。

import React, { useState } from "react";
import { useFavicon } from "ahooks";
import { Card, Button } from "antd";const UseFaviconExample = () => {const [favicon, setFavicon] = useState("https://ahooks.js.org/favicon.ico");useFavicon(favicon);return (<Card title="useFavicon 网站图标"><div style={{ marginBottom: 16 }}><p><strong>当前图标:</strong> {favicon}</p><p style={{ fontSize: "12px", color: "#666" }}>查看浏览器标签页图标变化</p></div><div><ButtononClick={() => setFavicon("https://www.google.com/favicon.ico")}style={{ marginRight: 8 }}>设置为 Google 图标</Button><Button onClick={() => setFavicon("https://ahooks.js.org/favicon.ico")}>恢复默认</Button></div></Card>);
};

useFullscreen – 全屏

useFullscreen 用于控制全屏状态。

import React, { useRef } from "react";
import { useFullscreen } from "ahooks";
import { Card, Button } from "antd";const UseFullscreenExample = () => {const ref = useRef(null);const [isFullscreen, { enterFullscreen, exitFullscreen, toggleFullscreen }] =useFullscreen(ref);return (<Card title="useFullscreen 全屏"><div style={{ marginBottom: 16 }}><p><strong>全屏状态:</strong> {isFullscreen ? "是" : "否"}</p></div><divref={ref}style={{padding: 16,backgroundColor: "#f0f0f0",border: "1px solid #d9d9d9",borderRadius: 4,marginBottom: 16,}}>这个区域可以全屏显示</div><div><Button onClick={enterFullscreen} style={{ marginRight: 8 }}>进入全屏</Button><Button onClick={exitFullscreen} style={{ marginRight: 8 }}>退出全屏</Button><Button onClick={toggleFullscreen}>切换全屏</Button></div></Card>);
};

useHover – 悬停状态

useHover 用于检测元素悬停状态。

import React, { useRef } from "react";
import { useHover } from "ahooks";
import { Card } from "antd";const UseHoverExample = () => {const ref = useRef(null);const isHovering = useHover(ref);return (<Card title="useHover 悬停状态"><div style={{ marginBottom: 16 }}><p><strong>悬停状态:</strong> {isHovering ? "悬停中" : "未悬停"}</p></div><divref={ref}style={{padding: 16,backgroundColor: isHovering ? "#e6f7ff" : "#f0f0f0",border: "1px solid #d9d9d9",borderRadius: 4,transition: "background-color 0.3s",}}>鼠标悬停我</div></Card>);
};

useMutationObserver – 元素变化监听

useMutationObserver 用于监听 DOM 元素变化。

import React, { useState, useRef, useCallback } from "react";
import { useMutationObserver } from "ahooks";
import { Card, Button } from "antd";const UseMutationObserverExample = () => {const [changeCount, setChangeCount] = useState(0);const ref = useRef(null);const handleMutation = useCallback((mutationsList) => {mutationsList.forEach(() => setChangeCount((c) => c + 1));}, []);useMutationObserver(handleMutation, ref, {attributes: true,childList: true,subtree: true,});const addElement = () => {const div = document.createElement("div");div.textContent = "新元素";ref.current?.appendChild(div);};const changeAttribute = () => {if (ref.current) {ref.current.style.backgroundColor = "#e6f7ff";}};return (<Card title="useMutationObserver 元素变化监听"><div style={{ marginBottom: 16 }}><p><strong>变化次数:</strong> {changeCount}</p></div><divref={ref}style={{padding: 16,backgroundColor: "#f0f0f0",border: "1px solid #d9d9d9",borderRadius: 4,marginBottom: 16,minHeight: 60,}}>监听区域</div><div><Button onClick={addElement} style={{ marginRight: 8 }}>添加元素</Button><Button onClick={changeAttribute}>改变属性</Button></div></Card>);
};

useInViewport – 视口可见性

useInViewport 用于检测元素是否在视口中可见。

import React, { useRef } from "react";
import { useInViewport } from "ahooks";
import { Card } from "antd";const UseInViewportExample = () => {const ref = useRef(null);const [inViewport] = useInViewport(ref);return (<Card title="useInViewport 视口可见性"><div style={{ marginBottom: 16 }}><p><strong>可见状态:</strong> {inViewport ? "可见" : "不可见"}</p></div><divstyle={{ height: 200, overflow: "auto", border: "1px solid #d9d9d9" }}><div style={{ height: 100, backgroundColor: "#f0f0f0" }}>滚动区域顶部</div><divref={ref}style={{padding: 16,backgroundColor: inViewport ? "#f6ffed" : "#fff2e8",border: "1px solid #d9d9d9",borderRadius: 4,margin: 16,}}>监听可见性的元素</div><div style={{ height: 300, backgroundColor: "#f0f0f0" }}>滚动区域底部</div></div></Card>);
};

useKeyPress – 键盘按键

useKeyPress 用于监听键盘按键事件。

import React, { useState } from "react";
import { useKeyPress } from "ahooks";
import { Card } from "antd";const UseKeyPressExample = () => {const [pressedKey, setPressedKey] = useState("");useKeyPress(["a", "b", "c"], (event) => {setPressedKey(event.key);});return (<Card title="useKeyPress 键盘按键"><div style={{ marginBottom: 16 }}><p><strong>按下的键:</strong> {pressedKey || "无"}</p><p style={{ fontSize: "12px", color: "#666" }}>按下 A、B、C 键查看效果</p></div></Card>);
};

useLongPress – 长按

useLongPress 用于检测长按事件。

import React, { useState } from "react";
import { useLongPress } from "ahooks";
import { Card } from "antd";const UseLongPressExample = () => {const [message, setMessage] = useState("");const longPress = useLongPress(() => {setMessage("长按触发");},{onCancel: () => {setMessage("长按取消");},},{delay: 1000,});return (<Card title="useLongPress 长按"><div style={{ marginBottom: 16 }}><p><strong>状态:</strong> {message || "等待长按"}</p></div><div{...longPress}style={{padding: 16,backgroundColor: "#f0f0f0",border: "1px solid #d9d9d9",borderRadius: 4,cursor: "pointer",userSelect: "none",}}>长按我 1 秒</div></Card>);
};

useMouse – 鼠标位置

useMouse 用于获取鼠标位置。

import React from "react";
import { useMouse } from "ahooks";
import { Card } from "antd";const UseMouseExample = () => {const mouse = useMouse();return (<Card title="useMouse 鼠标位置"><div style={{ marginBottom: 16 }}><p><strong>X 坐标:</strong> {mouse.clientX}</p><p><strong>Y 坐标:</strong> {mouse.clientY}</p><p><strong>屏幕 X:</strong> {mouse.screenX}</p><p><strong>屏幕 Y:</strong> {mouse.screenY}</p></div><div style={{ fontSize: "12px", color: "#666" }}>移动鼠标查看坐标变化</div></Card>);
};

useResponsive – 响应式

useResponsive 用于检测屏幕尺寸。

import React from "react";
import { configResponsive, useResponsive } from "ahooks";
import { Card } from "antd";configResponsive({small: 0,middle: 800,large: 1200,
});const UseResponsiveExample = () => {const responsive = useResponsive();return (<Card title="useResponsive 响应式"><div style={{ marginBottom: 16 }}><p>请调整浏览器窗口宽度查看效果:</p>{Object.keys(responsive).map((key) => (<p key={key}><strong>{key}:</strong> {responsive[key] ? "✔" : "✘"}</p>))}</div><div style={{ fontSize: "12px", color: "#666" }}>断点配置: small(0px) | middle(800px) | large(1200px)</div></Card>);
};

useScroll – 滚动

useScroll 用于监听滚动事件。

import React, { useRef } from "react";
import { useScroll } from "ahooks";
import { Card } from "antd";const UseScrollExample = () => {const ref = useRef(null);const scroll = useScroll(ref);return (<Card title="useScroll 滚动"><div style={{ marginBottom: 16 }}><p><strong>滚动位置:</strong> {scroll?.top || 0}</p><p><strong>滚动方向:</strong> {scroll?.direction || "无"}</p></div><divref={ref}style={{height: 200,overflow: "auto",border: "1px solid #d9d9d9",padding: 16,}}>{Array.from({ length: 20 }, (_, i) => (<divkey={i}style={{ padding: 8, borderBottom: "1px solid #f0f0f0" }}>滚动内容 {i + 1}</div>))}</div></Card>);
};

useSize – 元素尺寸

useSize 用于监听元素尺寸变化。

import React, { useRef } from "react";
import { useSize } from "ahooks";
import { Card, Button } from "antd";const UseSizeExample = () => {const ref = useRef(null);const size = useSize(ref);const toggleSize = () => {if (ref.current) {ref.current.style.width =ref.current.style.width === "200px" ? "300px" : "200px";ref.current.style.height =ref.current.style.height === "100px" ? "150px" : "100px";}};return (<Card title="useSize 元素尺寸"><div style={{ marginBottom: 16 }}><p><strong>宽度:</strong> {size?.width}px</p><p><strong>高度:</strong> {size?.height}px</p></div><divref={ref}style={{width: 200,height: 100,backgroundColor: "#f0f0f0",border: "1px solid #d9d9d9",borderRadius: 4,marginBottom: 16,transition: "all 0.3s",}}>监听尺寸的元素</div><Button onClick={toggleSize}>切换尺寸</Button></Card>);
};

useFocusWithin – 焦点状态

useFocusWithin 用于检测元素或其子元素是否获得焦点。

import React, { useRef } from "react";
import { useFocusWithin } from "ahooks";
import { Card, Input, Button, message } from "antd";const UseFocusWithinExample = () => {const ref = useRef(null);const isFocusWithin = useFocusWithin(ref, {onFocus: () => {message.info("获得焦点");},onBlur: () => {message.info("失去焦点");},});return (<Card title="useFocusWithin 焦点状态"><div style={{ marginBottom: 16 }}><p><strong>焦点状态:</strong> {JSON.stringify(isFocusWithin)}</p></div><divref={ref}style={{padding: 16,backgroundColor: isFocusWithin ? "#f6ffed" : "#f0f0f0",border: "1px solid #d9d9d9",borderRadius: 4,transition: "background-color 0.3s",}}><Input placeholder="点击我" style={{ marginBottom: 8 }} /><Button>按钮</Button></div></Card>);
};

DOM 类 hooks 速查表

Hook 名称用途描述
useEventListener事件监听器添加事件监听器
useClickAway点击外部检测点击元素外部的事件
useDocumentVisibility文档可见性监听文档可见性状态
useDrop & useDrag拖拽处理拖拽操作
useEventTarget事件目标处理表单输入事件
useExternal外部资源动态加载外部资源
useTitle页面标题动态设置页面标题
useFavicon网站图标动态设置网站图标
useFullscreen全屏控制全屏状态
useHover悬停状态检测元素悬停状态
useMutationObserver元素变化监听监听 DOM 元素变化
useInViewport视口可见性检测元素是否在视口中可见
useKeyPress键盘按键监听键盘按键事件
useLongPress长按检测长按事件
useMouse鼠标位置获取鼠标位置
useResponsive响应式检测屏幕尺寸
useScroll滚动监听滚动事件
useSize元素尺寸监听元素尺寸变化
useFocusWithin焦点状态检测元素或其子元素是否获得焦点

 React强大且灵活hooks库——ahooks入门实践之DOM类hook(dom)详解 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿动态资讯

http://www.lryc.cn/news/587990.html

相关文章:

  • C++-linux 5.gdb调试工具
  • LSY_C语言编程题
  • AI数据分析仪设计原理图:RapidIO信号接入 平板AI数据分析仪
  • Markdown表格列格式(加粗 / 高亮 / 复选 / 进度条 / 数值 / 货币 /…)~优雅好用的 Typora 主题与增强插件 VLOOK™
  • MFC中BOOL类型,在某些操作系统中,-1不能被识别,一般是哪些原因?
  • NAT原理与实验指南:网络地址转换技术解析与实践
  • com2tcp工具
  • 使用axios向服务器请求信息并渲染页面
  • DVWA靶场通关笔记-存储型XSS(Stored Medium级别)
  • TCP心跳机制详解
  • 多客户端-服务器(select,poll)
  • 多客户端 - 服务器结构-实操
  • 如何在服务器上运行一个github项目
  • Rsyslog介绍及运用
  • 面试150 二叉树中的最大路径和
  • 26-计组-多处理器
  • K8S的平台核心架构思想[面向抽象编程]
  • 自动驾驶数据仓库:时间片合并算法。
  • ether.js—6—contractFactory以部署ERC20代币标准为例子
  • 0201-solidity基础-区块链-web3
  • OneCode 3.0 VFS客户端驱动(SDK)技术解析:从架构到实战
  • 虚拟货币交易:游走在合法与犯罪的生死线
  • 排序树与无序树:数据结构中的有序性探秘
  • 【【异世界历险之数据结构世界(二叉树)】】
  • 交换类排序的C语言实现
  • 删除当前项目关联的远程仓库(remote)
  • C#结构体:值类型的设计艺术与实战指南
  • 基于ASP.NET+SQL Server实现(Web)排球赛事网站
  • iOS高级开发工程师面试——RunTime
  • JAVA面试宝典 - 《MyBatis 进阶:插件开发与二级缓存》