Skip to content

Instantly share code, notes, and snippets.

@NikaBuligini
Last active February 14, 2023 12:30
Show Gist options
  • Save NikaBuligini/58bbadfb41dbb9dd62dfeb5dd3f7b208 to your computer and use it in GitHub Desktop.
Save NikaBuligini/58bbadfb41dbb9dd62dfeb5dd3f7b208 to your computer and use it in GitHub Desktop.
useDocumentVisibility (react hook)
import React from 'react';
import useEventListener from './useEventListener';
function getVisibilityPropertyNames() {
// Opera 12.10 and Firefox 18 and later support
if (typeof document.hidden !== 'undefined') {
return ['hidden', 'visibilitychange'];
}
if (typeof document.msHidden !== 'undefined') {
return ['msHidden', 'msvisibilitychange'];
}
if (typeof document.webkitHidden !== 'undefined') {
return ['webkitHidden', 'webkitvisibilitychange'];
}
return ['hidden', 'visibilitychange'];
}
const [hidden, visibilityChange] = getVisibilityPropertyNames();
function isDocumentHidden() {
return document[hidden];
}
if (typeof document.addEventListener === 'undefined' || hidden === undefined) {
console.log(
'This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.',
);
}
export function useDocumentVisibilityChange(callback) {
const onChange = React.useCallback(() => {
callback(isDocumentHidden());
}, [callback]);
useEventListener(visibilityChange, onChange, document);
}
export function useDocumentVisibility() {
const [isHidden, setHidden] = React.useState(isDocumentHidden());
const onChange = React.useCallback(state => setHidden(state), [setHidden]);
useDocumentVisibilityChange(onChange);
return isHidden;
}
import React from 'react';
function useEventListener(eventName, handler, element = global) {
const savedCallback = React.useRef();
React.useEffect(() => {
savedCallback.current = handler;
}, [handler]);
React.useEffect(() => {
// Make sure element supports addEventListener
const isSupported = element && element.addEventListener;
if (!isSupported) {
return;
}
const eventListener = event => savedCallback.current(event);
element.addEventListener(eventName, eventListener);
// eslint-disable-next-line consistent-return
return () => {
element.removeEventListener(eventName, eventListener);
};
}, [eventName, element]);
}
export default useEventListener;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment