本文接着解读每一个关于DOM的Hook包。useFullscreen管理DOM全屏的Hook。hook主要是依赖npm包screenfull[1]实现的。选择它的原因大概有两个:兼容性好,兼容各种浏览器的全屏API。简单、小的封装尺寸。压缩后只有1.1k。关于它的几个API。.request(元素,选项?)。使元素全屏。默认元素是.exit()。退出全屏。.toggle(元素,选项?)。如果当前是全屏,则退出,否则进入全屏。.on(事件,函数)。为浏览器切换到全屏或从全屏切换或发生错误时添加一个侦听器。事件支持“更改”或“错误”。另外两种写法:.onchange(function)和.onerror(function)。.isFullscreen.判断是否全屏。.isEnabled。判断当前环境是否支持全屏。查看这个钩子的封装:首先在onChange事件中判断是否全屏,从而触发进入全屏或者退出全屏的功能。退出全屏时卸载更改事件。const{onExit,onEnter}=选项||{};//退出全屏触发constonExitRef=useLatest(onExit);//全屏触发constonEnterRef=useLatest(onEnter);const[state,setState]=useState(false);constonChange=()=>{if(screenfull.isEnabled){const{isFullscreen}=screenfull;如果(isFullscreen){onEnterRef.current?.();}else{screenfull.off('change',onChange);onExitRef.current?.();}setState(isFullscreen);}};手动进入全屏功能,支持传入ref设置需要全屏的元素。并通过screenfull.request进行设置,监听change事件。//进入全屏constenterFullscreen=()=>{constel=getTargetElement(target);如果(!el){返回;}if(screenfull.isEnabled){try{screenfull.request(el);screenfull.on('改变',onChange);}catch(错误){console.error(错误);}}};退出全屏方法调用screenfull.exit()。//退出全屏constexitFullscreen=()=>{if(!state){return;}if(screenfull.isEnabled){screenfull.exit();}};最后根据当前状态通过toggleFullscreen调用以上两个方法,达到切换全屏状态的效果。//切换模式consttoggleFullscreen=()=>{if(state){exitFullscreen();}else{enterFullscreen();}};useHover监听DOM元素是否被鼠标悬停。主要实现原理是监听mouseenter触发onEnter事件,切换状态为true,监听mouseleave触发onLeave事件,切换状态为false。代码很简单,如下:{};const[state,{setTrue,setFalse}]=useBoolean(false);//通过监听mouseenter,判断有mouseoveruseEventListener('mouseenter',()=>{onEnter?.();setTrue();},{target,},);//mouseleave没有鼠标悬停useEventListener('mouseleave',()=>{onLeave?.();setFalse();},{target,},);返回状态;};useDocumentVisibility监视页面是否可见。这个钩子主要使用Document.visibilityStateAPI。先简单看一下这个API:Document.visibilityState(只读属性),返回文档的可见性,即当前可见元素的上下文。从这里你可以知道当前文档(即页面)是否在后台,或者是一个不可见的隐藏选项卡,或者(正在)预渲染。可用值如下:'visible':此时页面内容至少部分可见。也就是说,页面位于前台选项卡中,并且窗口未最小化。'hidden':该页面此时对用户不可见。也就是说,文档位于背景选项卡中或窗口已最小化,或者操作系统已“锁定”。'prerender':页面当前正在呈现,因此不可见。文档只能从这个状态开始,永远不能从其他值改变到这个状态。典型用法是在页面呈现时阻止资源加载,或者在页面处于后台或窗口最小化时抑制某些活动。最后,这个钩子的实现很简单:通过document.visibilityState判断是否可见。通过visibilitychange事件,更新结果。constgetVisibility=()=>{if(!isBrowser){return'visible';}//Document.visibilityState(只读属性),返回文档的可见性,即当前可见元素的上下文。返回document.visibilityState;};functionuseDocumentVisibility():VisibilityState{const[documentVisibility,setDocumentVisibility]=useState(()=>getVisibility());useEventListener(//监听该事件'visibilitychange',()=>{setDocumentVisibility(getVisibility());},{target:()=>document,},);returndocumentVisibility;}参考资料[1]screenfull:https://www.npmjs.com/package/screenfull
