前言
本文是 ahooks 源码(v3.7.4)系列的第四篇,也是 DOM 篇的完结篇,往期文章:
- 【解读 ahooks 源码系列】DOM 篇(一):useEventListener、useClickAway、useDocumentVisibility、useDrop、useDrag
- 【解读 ahooks 源码系列】DOM 篇(二):useEventTarget、useExternal、useTitle、useFavicon、useFullscreen、useHover
- 【解读 ahooks 源码系列】DOM 篇(三):useMutationObserver、useInViewport、useKeyPress、useLongPress
本文主要解读 useMouse
、useResponsive
、useScroll
、useSize
、useFocusWithin
的源码实现
useMouse
监听鼠标位置。
基本用法
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);
复制代码
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>
</>
);
};
复制代码
核心实现
实现原理:通过监听 mousemove 方法,获取鼠标的位置。通过 getBoundingClientRect(提供了元素的大小及其相对于视口的位置) 获取到 target 元素的位置大小,计算出鼠标相对于元素的位置。
export default (target?: BasicTarget) => {
const [state, setState] = useRafState(initState);
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 (targetElem