成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

再續那些關于DOM的常見Hook封裝

開發 前端
Document.visibilityState (只讀屬性), 返回document的可見性, 即當前可見元素的上下文環境。由此可以知道當前文檔 (即為頁面) 是在背后, 或是不可見的隱藏的標簽頁,或者 (正在) 預渲染。

本篇接著針對關于 DOM 的各個 Hook 封裝進行解讀。

useFullscreen

管理 DOM 全屏的 Hook。

該 hook 主要是依賴 screenfull[1] 這個 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]screenfull: https://www.npmjs.com/package/screenfull


責任編輯:武曉燕 來源: 前端雜貨鋪
相關推薦

2022-07-03 23:26:38

DOMHook封裝

2022-07-20 09:06:27

Hook封裝工具庫

2022-04-14 11:50:39

函數組件hook

2017-07-19 14:26:01

前端JavaScriptDOM

2021-01-25 10:05:27

ReactDOM前端

2015-09-14 09:28:47

2009-02-19 10:21:00

路由多WAN口

2021-03-18 16:05:20

SSD存儲故障

2015-08-13 10:54:46

2022-08-04 10:18:32

棧遷移?寄存器內存

2012-07-13 00:03:08

WEB前端開發WEB開發

2019-12-10 08:00:46

Kata容器Linux

2022-06-10 08:01:01

ahookshook代碼

2012-05-01 08:06:49

手機

2023-07-06 08:10:57

Vue3參數請求

2023-12-25 08:25:42

AndroidHook應用程序

2015-06-16 09:53:48

swift蘋果開源

2017-01-03 19:12:56

數據中心冷卻機架

2023-08-02 10:11:00

DOM曝光封裝

2017-04-12 12:31:14

緩存Web瀏覽器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲91精品 | 91人人在线 | 黄色精品| 男人天堂久久久 | 欧美三区在线观看 | 国产成人精品免费 | 欧产日产国产精品视频 | 久久久精品一区二区三区 | 国产精品久久亚洲 | 日产精品久久久一区二区福利 | 91精品国产91综合久久蜜臀 | 国产一区二区在线播放 | 国精品一区 | 亚洲网站在线 | 黄色香蕉视频在线观看 | 成人免费网站视频 | 久久精品69 | 久久另类视频 | 日韩精品一区二区三区视频播放 | 99中文字幕 | 久久777| 中文字幕精品一区久久久久 | 天堂三级 | 91原创视频 | 亚洲欧美日韩成人在线 | 国产伦一区二区三区四区 | 国产精品国产 | jlzzjlzz欧美大全 | 日本精品视频一区二区 | 四虎成人在线播放 | 亚洲欧美日韩在线 | 精品一二区 | 免费午夜视频 | 中文字幕在线观看第一页 | 殴美黄色录像 | 97免费在线观看视频 | 成人av片在线观看 | 久久久网| 在线国产中文字幕 | aaaaaaa片毛片免费观看 | 中文一区 |