Skip to content

Instantly share code, notes, and snippets.

@ellemedit
Created April 23, 2020 08:10
Show Gist options
  • Save ellemedit/68cc51dd63d4781b3260c92d3dcd1987 to your computer and use it in GitHub Desktop.
Save ellemedit/68cc51dd63d4781b3260c92d3dcd1987 to your computer and use it in GitHub Desktop.
sometimes we need to care screen itself rather than intersectionObserver.
import * as React from 'react';
export function useScreenEffect(handler: () => void, deps: ReadonlyArray<any>) {
React.useLayoutEffect(() => {
const enhancedHandler = debounceToNextAnimationFrame(handler);
window.addEventListener("scroll", enhancedHandler, canUsePassive && { passive: true });
window.addEventListener("resize", enhancedHandler, canUsePassive && { passive: true });
enhancedHandler();
return () => {
window.removeEventListener("scroll", enhancedHandler);
window.removeEventListener("resize", enhancedHandler);
};
// eslint-disable-next-line
}, deps);
}
let canUsePassive = false;
try {
(window as any).addEventListener(
"test",
null,
Object.defineProperty({}, "passive", {
get() {
canUsePassive = true;
return true;
},
})
);
} catch {}
function debounceToNextAnimationFrame<T extends Function>(handler: T): T {
let handling = false;
return ((...args: any[]) => {
if (handling) {
return;
}
handling = true;
requestAnimationFrame(() => {
try {
handler(...args);
} finally {
handling = false;
}
});
}) as any;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment