持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
今天开始一起学习分享 ahooks 的源码
ahooks是阿里巴巴出品的一套高质量可靠的 React Hooks 库
今天分享 第11个 hooks-useMouse
useBoolean
首先看下 useMouse 的作用是什么
useMouse 的作用是监听鼠标位置
接下来 看下 API
API
const state: {
screenX: number,
screenY: number,
clientX: number,
clientY: number,
pageX: number,
pageY: number,
elementX: number,
elementY: number,
elementH: number,
elementW: number,
elementPosX: number,
elementPosY: number,
} = useMouse(target?: Target);
Params
参数只有1个,target表示 目标元素dom节点 或者 也可以传入 ref来表示目标元素
| 参数 | 说明 | 类型 |
|---|---|---|
| target | DOM 节点或者 Ref | Element | () => Element | MutableRefObject<Element> |
Result
返回的结果 是 各种 距离
| 参数 | 说明 | 类型 |
|---|---|---|
| screenX | 距离显示器左侧的距离 | number |
| screenY | 距离显示器顶部的距离 | number |
| clientX | 距离当前视窗左侧的距离 | number |
| clientY | 距离当前视窗顶部的距离 | number |
| pageX | 距离完整页面左侧的距离 | number |
| pageY | 距离完整页面顶部的距离 | number |
| elementX | 距离指定元素左侧的距离 | number |
| elementY | 距离指定元素顶部的距离 | number |
| elementH | 指定元素的高 | number |
| elementW | 指定元素的宽 | number |
| elementPosX | 指定元素距离完整页面左侧的距离 | number |
| elementPosY | 指定元素距离完整页面顶部的距离 | number |
接下来 看下 用法
基本用法
获取鼠标位置。
只有使用useMouse,返回mouse,mouse就能返回鼠标的当前位置
import { useMouse } from 'ahooks';
import React from 'react';
export default () => {
const mouse = useMouse();
return (
<div>
<p>
Client - x: {mouse.clientX}, y: {mouse.clientY}
</p>
<p>
Page - x: {mouse.pageX}, y: {mouse.pageY}
</p>
<p>
Screen - x: {mouse.screenX}, y: {mouse.screenY}
</p>
</div>
);
};
获取鼠标相对于元素的位置
通过传入目标元素,可以获取鼠标相对于元素的位置。
import React, { useRef } from 'react';
import { useMouse } from 'ahooks';
export default () => {
const ref = useRef(null);
const mouse = useMouse(ref.current);
return (
<>
<div
ref={ref}
style={{
width: '200px',
height: '200px',
backgroundColor: 'gray',
color: 'white',
lineHeight: '200px',
textAlign: 'center',
}}
>
element
</div>
<div>
<p>
Mouse In Element - x: {mouse.elementX}, y: {mouse.elementY}
</p>
<p>
Element Position - x: {mouse.elementPosX}, y: {mouse.elementPosY}
</p>
<p>
Element Dimensions - width: {mouse.elementW}, height: {mouse.elementH}
</p>
</div>
</>
);
};
接下来一起看下 源码
源码
1.首先 定义 目标元素的类型
import type { BasicTarget } from '../utils/domTarget';
export type BasicTarget<T extends TargetType = Element> =
| (() => TargetValue<T>)
| TargetValue<T>
| MutableRefObject<TargetValue<T>>;
target?: BasicTarget
2.通过state初始化元素位置信息
const [state, setState] = useRafState(initState);
const initState: CursorState = {
screenX: NaN,
screenY: NaN,
clientX: NaN,
clientY: NaN,
pageX: NaN,
pageY: NaN,
elementX: NaN,
elementY: NaN,
elementH: NaN,
elementW: NaN,
elementPosX: NaN,
elementPosY: NaN,
};
3.使用useEventListener hooks来监听鼠标移动事件mousemove。通过event来获取元素的各位置信息,然后获取目标元素,判断如果当目标元素存在的时候,则将这些位置信息通过setState更新,最后返回state
useEventListener(
'mousemove',
(event: MouseEvent) => {
const { screenX, screenY, clientX, clientY, pageX, pageY } = event;
const newState = {
screenX,
screenY,
clientX,
clientY,
pageX,
pageY,
elementX: NaN,
elementY: NaN,
elementH: NaN,
elementW: NaN,
elementPosX: NaN,
elementPosY: NaN,
};
const targetElement = getTargetElement(target);
if (targetElement) {
const { left, top, width, height } = targetElement.getBoundingClientRect();
newState.elementPosX = left + window.pageXOffset;
newState.elementPosY = top + window.pageYOffset;
newState.elementX = pageX - newState.elementPosX;
newState.elementY = pageY - newState.elementPosY;
newState.elementW = width;
newState.elementH = height;
}
setState(newState);
},
{
target: () => document,
},
);