shoelace/src/internal/scroll.ts

58 wiersze
1.9 KiB
TypeScript
Czysty Zwykły widok Historia

2020-07-15 21:30:37 +00:00
import { getOffset } from './offset';
const locks = new Set();
2020-07-15 21:30:37 +00:00
2022-12-06 16:48:57 +00:00
/**
* Prevents body scrolling. Keeps track of which elements requested a lock so multiple levels of locking are possible
* without premature unlocking.
*/
2020-07-15 21:30:37 +00:00
export function lockBodyScrolling(lockingEl: HTMLElement) {
locks.add(lockingEl);
document.body.classList.add('sl-scroll-lock');
2020-07-15 21:30:37 +00:00
}
2022-12-06 16:48:57 +00:00
/**
* Unlocks body scrolling. Scrolling will only be unlocked once all elements that requested a lock call this method.
*/
2020-07-15 21:30:37 +00:00
export function unlockBodyScrolling(lockingEl: HTMLElement) {
locks.delete(lockingEl);
2020-07-15 21:30:37 +00:00
if (locks.size === 0) {
2020-07-15 21:30:37 +00:00
document.body.classList.remove('sl-scroll-lock');
}
}
2022-12-06 16:48:57 +00:00
/**
* Scrolls an element into view of its container. If the element is already in view, nothing will happen.
*/
2020-07-15 21:30:37 +00:00
export function scrollIntoView(
element: HTMLElement,
container: HTMLElement,
2020-12-23 14:07:08 +00:00
direction: 'horizontal' | 'vertical' | 'both' = 'vertical',
behavior: 'smooth' | 'auto' = 'smooth'
2020-07-15 21:30:37 +00:00
) {
const offset = getOffset(element, container);
const offsetTop = offset.top + container.scrollTop;
const offsetLeft = offset.left + container.scrollLeft;
const minX = container.scrollLeft;
const maxX = container.scrollLeft + container.offsetWidth;
const minY = container.scrollTop;
const maxY = container.scrollTop + container.offsetHeight;
if (direction === 'horizontal' || direction === 'both') {
if (offsetLeft < minX) {
2020-12-23 14:07:08 +00:00
container.scrollTo({ left: offsetLeft, behavior });
2020-07-15 21:30:37 +00:00
} else if (offsetLeft + element.clientWidth > maxX) {
2020-12-23 14:07:08 +00:00
container.scrollTo({ left: offsetLeft - container.offsetWidth + element.clientWidth, behavior });
2020-07-15 21:30:37 +00:00
}
}
if (direction === 'vertical' || direction === 'both') {
if (offsetTop < minY) {
2020-12-23 14:07:08 +00:00
container.scrollTo({ top: offsetTop, behavior });
2020-07-15 21:30:37 +00:00
} else if (offsetTop + element.clientHeight > maxY) {
2020-12-23 14:07:08 +00:00
container.scrollTo({ top: offsetTop - container.offsetHeight + element.clientHeight, behavior });
2020-07-15 21:30:37 +00:00
}
}
}