携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
💻文档地址:ahooks.js.org/zh-CN/
👨💻github地址:github.com/alibaba/hoo…
useFullscreen
这个 hooks 中,用到了 screenfull 库。
hooks 向外暴露当前是否全屏的状态 state,以及 enterFullscreen,exitFullscreen,toggleFullscreen 三个方法。
enterFullscreen
判断当前是否存在 el。判断 screenfull.isEnabled 是否为 true(支持全屏),如果为 true,则调用 screenfull 的 request() 方法。
exitFullscreen
调用 screenfull 的 exit() 方法。
const useFullscreen = (target: BasicTarget, options?: Options) => {
const [state, setState] = useState<boolean>(false);
const enterFullscreen = () => {
const el = getTargetElement(target);
if (!el) {
return;
}
if (screenfull.isEnabled) {
try {
screenfull.request(el);
} catch (error) {
console.error(error);
}
}
};
const exitFullscreen = () => {
if (screenfull.isEnabled) {
screenfull.exit();
}
};
return [
state,
{
enterFullscreen: useMemoizedFn(enterFullscreen),
exitFullscreen: useMemoizedFn(exitFullscreen),
isEnabled: screenfull.isEnabled,
},
] as const;
};
export default useFullscreen;
触发函数之后的回调,onExitRef 和 onEnterRef。
screenfull.off('change', callback);
const onChange = () => {
if (screenfull.isEnabled) {
const { isFullscreen } = screenfull;
if (isFullscreen) {
onEnterRef.current?.();
} else {
// screenfull.off('change', onChange);
onExitRef.current?.();
}
setState(isFullscreen);
}
};
const enterFullscreen = () => {
if (screenfull.isEnabled) {
try {
screenfull.on('change', onChange);
}
}
};
useFocusWithin
监听当前焦点是否在某个区域之内,同 css 属性 :focus-within。
:focus-within 是一个CSS 伪类 ,表示一个元素获得焦点
/* 当 <div> 的某个后代获得焦点时,匹配 <div> */
h2:focus-within {
background: red;
}
<form>
<label for="given_name">Given Name:</label>
<input id="given_name" type="text">
<br>
<label for="family_name">Family Name:</label>
<input id="family_name" type="text">
</form>
form {
border: 1px solid;
color: gray;
padding: 4px;
}
form:focus-within {
background: #ff8;
color: black;
}
input {
margin: 4px;
}
传入 target,监听 focusin 和 focusout 事件。向外触发 onFocus 和 onChange 事件,并且设置当前 focus 的状态为 true or false。
export default function useFocusWithin(target: BasicTarget, options?: Options) {
const [isFocusWithin, setIsFocusWithin] = useState<boolean>(false);
const { onFocus, onBlur, onChange } = options || {};
useEventListener(
'focusin',
(e: FocusEvent) => {
if (!isFocusWithin) {
onFocus?.(e);
onChange?.(true);
setIsFocusWithin(true);
}
},
{
target,
},
);
useEventListener(
'focusout',
(e: FocusEvent) => {
if (isFocusWithin && !(e.currentTarget as Element)?.contains?.(e.relatedTarget as Element)) {
onBlur?.(e);
onChange?.(false);
setIsFocusWithin(false);
}
},
{
target,
},
);
return isFocusWithin;
}
useHover
监听 DOM 元素是否有鼠标悬停
传入 tagret,监听 mouseenter 和 mouseleave 事件。向外触发 onEnter 或者 onLeave 或者 onChange 事件。
export default (target: BasicTarget, options?: Options): boolean => {
const { onEnter, onLeave, onChange } = options || {};
const [state, { setTrue, setFalse }] = useBoolean(false);
useEventListener(
'mouseenter',
() => {
onEnter?.();
setTrue();
onChange?.(true);
},
{
target,
},
);
useEventListener(
'mouseleave',
() => {
onLeave?.();
setFalse();
onChange?.(false);
},
{
target,
},
);
return state;
};