@cascadia-code/scroll-to-hash-element
Version:
Detects location.hash changes and scrolls to the element with the corresponding id. Customizable scroll behavior.
53 lines (52 loc) • 2.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
const ScrollToHashElement = ({ behavior = "auto", inline = "nearest", block = "start", }) => {
const [hash, setHash] = (0, react_1.useState)(window.location.hash);
const originalPushState = window.history.pushState;
const originalReplaceState = window.history.replaceState;
window.history.pushState = function (...args) {
const result = originalPushState.apply(this, args);
window.dispatchEvent(new Event('pushstate'));
window.dispatchEvent(new Event('locationchange'));
return result;
};
window.history.replaceState = function (...args) {
const result = originalReplaceState.apply(this, args);
window.dispatchEvent(new Event('replacestate'));
window.dispatchEvent(new Event('locationchange'));
return result;
};
window.addEventListener('popstate', () => {
window.dispatchEvent(new Event('locationchange'));
});
(0, react_1.useEffect)(() => {
const handleLocationChange = () => {
setHash(window.location.hash);
};
window.addEventListener('locationchange', handleLocationChange);
// Cleanup the event listener on component unmount
return () => {
window.removeEventListener('locationchange', handleLocationChange);
};
}, []);
(0, react_1.useLayoutEffect)(() => {
const removeHashCharacter = (str) => {
const result = str.slice(1);
return result;
};
if (hash) {
const element = document.getElementById(removeHashCharacter(hash));
if (element) {
console.log("scrollIntoView");
element.scrollIntoView({
behavior: behavior,
inline: inline,
block: block,
});
}
}
}, [hash]);
return null;
};
exports.default = ScrollToHashElement;