@advdominion/scroll-to
This commit is contained in:
40
packages/scroll-to/index.js
Normal file
40
packages/scroll-to/index.js
Normal file
@@ -0,0 +1,40 @@
|
||||
export const scrollTo = ($el, offset = 0, offsetInPx = false) => {
|
||||
return new Promise((resolve) => {
|
||||
if (!$el) {
|
||||
console.warn('Элемент не найден');
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
const elementPosition = $el.getBoundingClientRect().top + window.scrollY;
|
||||
const topOffset = offsetInPx ? offset : (window.innerHeight * offset) / 100;
|
||||
const targetScrollTop = elementPosition - topOffset;
|
||||
|
||||
// Если элемент уже в нужной позиции
|
||||
if (Math.abs(window.scrollY - targetScrollTop) < 1) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
let resolved = false; // На случай, если scrollend и fallback запустятся одновременно
|
||||
let fallbackTimeout; // eslint-disable-line prefer-const
|
||||
|
||||
const done = () => {
|
||||
if (resolved) return;
|
||||
resolved = true;
|
||||
|
||||
window.removeEventListener('scrollend', done);
|
||||
clearTimeout(fallbackTimeout);
|
||||
|
||||
resolve();
|
||||
};
|
||||
|
||||
window.addEventListener('scrollend', done, { once: true });
|
||||
fallbackTimeout = setTimeout(done, 1500);
|
||||
|
||||
window.scrollTo({
|
||||
top: targetScrollTop,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user