feat(main): Add base theme: This is the falcon theme out of the box.
This commit is contained in:
75
_dev/js/theme/components/useStickyElement.js
Normal file
75
_dev/js/theme/components/useStickyElement.js
Normal file
@ -0,0 +1,75 @@
|
||||
import debounce from '@js/theme/utils/debounce';
|
||||
|
||||
/**
|
||||
* Returns sticky element data
|
||||
* @param element
|
||||
* @returns {{getTop: ((function(): number)), getTopOffset: ((function(): number)), getFullTopOffset: (function(): number)}}
|
||||
*/
|
||||
export default (element, stickyWrapper, options = {}) => {
|
||||
if (!element) {
|
||||
throw new Error('Sticky element: element not found');
|
||||
}
|
||||
|
||||
if (!stickyWrapper) {
|
||||
throw new Error('Sticky element: stickyWrapper not found');
|
||||
}
|
||||
|
||||
const {
|
||||
extraOffsetTop = 0,
|
||||
debounceTime = 5,
|
||||
zIndex = 100,
|
||||
} = options;
|
||||
let isSticky = false;
|
||||
const getWrapperRect = () => {
|
||||
const wrapperRect = stickyWrapper.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: wrapperRect.top,
|
||||
bottom: wrapperRect.bottom,
|
||||
height: wrapperRect.height,
|
||||
width: wrapperRect.width,
|
||||
};
|
||||
};
|
||||
const getExtraOffsetTop = typeof extraOffsetTop === 'function' ? extraOffsetTop : () => extraOffsetTop;
|
||||
const setElementSticky = () => {
|
||||
const { height } = getWrapperRect();
|
||||
stickyWrapper.style.height = `${height}px`;
|
||||
element.style.top = `${getExtraOffsetTop()}px`;
|
||||
element.style.left = 0;
|
||||
element.style.right = 0;
|
||||
element.style.bottom = 'auto';
|
||||
element.style.position = 'fixed';
|
||||
element.style.zIndex = zIndex;
|
||||
element.classList.add('is-sticky');
|
||||
isSticky = true;
|
||||
};
|
||||
const unsetElementSticky = () => {
|
||||
element.style.top = null;
|
||||
element.style.bottom = null;
|
||||
element.style.position = null;
|
||||
element.style.zIndex = null;
|
||||
element.classList.remove('is-sticky');
|
||||
stickyWrapper.style.height = null;
|
||||
isSticky = false;
|
||||
};
|
||||
const getIsSticky = () => isSticky;
|
||||
const handleSticky = () => {
|
||||
const { top } = getWrapperRect();
|
||||
|
||||
if (top <= getExtraOffsetTop()) {
|
||||
if (!isSticky) {
|
||||
setElementSticky();
|
||||
}
|
||||
} else if (isSticky) {
|
||||
unsetElementSticky();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', debounce(handleSticky, debounceTime));
|
||||
handleSticky();
|
||||
|
||||
return {
|
||||
getExtraOffsetTop,
|
||||
getIsSticky,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user