本文是深入浅出 ahooks 源码系列文章的第十五篇,该系列已整理成文档-地址。觉得还不错,给个 star 支持一下哈,Thanks。

本篇接着针对关于 DOM 的各个 Hook 封装进行解读。

useFullscreen

管理 DOM 全屏的 Hook。

该 hook 主要是依赖 screenfull 这个 npm 包进行实现的。

选择它的原因,估计有两个:

  • 它的兼容性好,兼容各个浏览器的全屏 API。
  • 简单,包体积小。压缩后只要 1.1 k。

大概介绍几个它的 API。

  • .request(element, options?)。使一个元素全屏显示。默认元素是 <html>
  • .exit()。退出全屏。
  • .toggle(element, options?)。假如目前是全屏,则退出,否则进入全屏。
  • .on(event, function)。添加一个监听器,用于当浏览器切换到全屏或切换出全屏或出现错误时。event 支持 'change' 或者 'error'。另外两种写法:.onchange(function).onerror(function)
  • .isFullscreen。判断是否是全屏。
  • .isEnabled。判断当前环境是否支持全屏。

来看该 hook 的封装:

首先是 onChange 事件中,判断是否是全屏,从而触发进入全屏的函数或者退出全屏的函数。

当退出全屏的时候,卸载 change 事件。

const { onExit, onEnter } = options || {};
// 退出全屏触发
const onExitRef = useLatest(onExit);
// 全屏触发
const onEnterRef = useLatest(onEnter);
const [state, setState] = useState(false); const onChange = () => {
if (screenfull.isEnabled) {
const { isFullscreen } = screenfull;
if (isFullscreen) {
onEnterRef.current?.();
} else {
screenfull.off('change', onChange);
onExitRef.current?.();
}
setState(isFullscreen);
}
};

手动进入全屏函数,支持传入 ref 设置需要全屏的元素。并通过 screenfull.request 进行设置,并监听 change 事件。

// 进入全屏
const enterFullscreen = () => {
const el = getTargetElement(target);
if (!el) {
return;
} if (screenfull.isEnabled) {
try {
screenfull.request(el);
screenfull.on('change', onChange);
} catch (error) {
console.error(error);
}
}
};

退出全屏方法,调用 screenfull.exit()

// 退出全屏
const exitFullscreen = () => {
if (!state) {
return;
}
if (screenfull.isEnabled) {
screenfull.exit();
}
};

最后通过 toggleFullscreen,根据当前状态,调用上面两个方法,达到切换全屏状态的效果。

// 切换模式
const toggleFullscreen = () => {
if (state) {
exitFullscreen();
} else {
enterFullscreen();
}
};

useHover

监听 DOM 元素是否有鼠标悬停。

主要实现原理是监听 mouseenter 触发 onEnter 事件,切换状态为 true,监听 mouseleave 触发 onLeave 事件,切换状态为 false。代码简单,如下:

export default (target: BasicTarget, options?: Options): boolean => {
const { onEnter, onLeave } = options || {};
const [state, { setTrue, setFalse }] = useBoolean(false);
// 通过监听 mouseenter 判断有鼠标悬停
useEventListener(
'mouseenter',
() => {
onEnter?.();
setTrue();
},
{
target,
},
); // mouseleave 没有鼠标悬停
useEventListener(
'mouseleave',
() => {
onLeave?.();
setFalse();
},
{
target,
},
); return state;
};

useDocumentVisibility

监听页面是否可见。

这个 hook 主要使用了 Document.visibilityState 这个 API。先简单看下这个 API:

Document.visibilityState (只读属性), 返回document的可见性, 即当前可见元素的上下文环境。由此可以知道当前文档 (即为页面) 是在背后, 或是不可见的隐藏的标签页,或者 (正在) 预渲染。可用的值如下:

  • 'visible' : 此时页面内容至少是部分可见. 即此页面在前景标签页中,并且窗口没有最小化。
  • 'hidden' : 此时页面对用户不可见。即文档处于背景标签页或者窗口处于最小化状态,或者操作系统正处于 '锁屏状态' 。
  • 'prerender' : 页面此时正在渲染中,因此是不可见的。文档只能从此状态开始,永远不能从其他值变为此状态。

典型用法是防止当页面正在渲染时加载资源,或者当页面在背景中或窗口最小化时禁止某些活动。

最后看这个 hook 的实现就很简单了:

  • 通过 document.visibilityState 判断是否可见。
  • 通过 visibilitychange 事件,更新结果。
const getVisibility = () => {
if (!isBrowser) {
return 'visible';
}
// Document.visibilityState (只读属性), 返回document的可见性, 即当前可见元素的上下文环境。
return document.visibilityState;
}; function useDocumentVisibility(): VisibilityState {
const [documentVisibility, setDocumentVisibility] = useState(() => getVisibility()); useEventListener(
// 监听该事件
'visibilitychange',
() => {
setDocumentVisibility(getVisibility());
},
{
target: () => document,
},
);
return documentVisibility;
}

本文已收录到个人博客中,欢迎关注~

最新文章

  1. Markdown精简版个人语法
  2. WPF去边框与webbrowser的冲突
  3. UIFont的常用字体
  4. 加速编码的 JavaScript 库和工具
  5. showModalDialog 的重要提示
  6. 2013级软件工程GitHub账号信息
  7. javascript基础之打印乘法表
  8. 【同步复制常见错误处理3】找不到存储的过程 sp_MSins_tablename
  9. Windows Phone 开发起步之旅之二 C#中的值类型和引用类型
  10. FreeModbus Slave For AVR源代码 精简版2 【worldsing 笔记】
  11. 初步掌握MapReduce的架构及原理
  12. Eclipse 添加快捷方式
  13. Linux笔记(二) - 权限管理
  14. php 环信 接口的例子
  15. SpringCloud Eureka 报错 无法启动问题
  16. 2018最完整ITTO分节整理指导(PMP项目管理入门必备)
  17. 基于LVM卷的MYSQL快照恢复
  18. HTTP 中 GET 与 POST 的区别
  19. 删除SQL Server大容量日志的方法(转)
  20. python特殊成员函数

热门文章

  1. .NET 6.0.6 和 .NET Core 3.1.26、Visual Studio 2022 17.2 和 17.3 Preview 2 和 .NET 7.0 Preview 5 同时发布
  2. 软件项目管理 7.5.项目进度模型(SPSP)
  3. BUUCTF-乌镇峰会种图
  4. CPI教程-异步接口创建及使用
  5. 自建批量更改标准BO数据程序
  6. Electron学习(三)之简单交互操作
  7. NC16597 [NOIP2011]聪明的质监员
  8. 『现学现忘』Git后悔药 — 29、版本回退git reset --mixed命令说明
  9. Oracle创建用户和表空间
  10. Collection集合和Collection集合常用功能