smooth-scroll.ts 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. const WIKI_HEADER_LINK = 120;
  2. export const smoothScrollIntoView = (
  3. element: HTMLElement = window.document.body, offsetTop = 0, scrollElement: HTMLElement | Window = window,
  4. ): void => {
  5. // get the distance to the target element top
  6. const rectTop = element.getBoundingClientRect().top;
  7. const top = window.pageYOffset + rectTop - offsetTop;
  8. scrollElement.scrollTo({
  9. top,
  10. behavior: 'smooth',
  11. });
  12. };
  13. export type SmoothScrollEventCallback = (elem: HTMLElement) => void;
  14. export const addSmoothScrollEvent = (elements: HTMLAnchorElement[], callback?: SmoothScrollEventCallback): void => {
  15. elements.forEach((link) => {
  16. const href = link.getAttribute('href');
  17. if (href == null) {
  18. return;
  19. }
  20. link.addEventListener('click', (e) => {
  21. e.preventDefault();
  22. // modify location.hash without scroll
  23. window.history.pushState({}, '', link.href);
  24. // smooth scroll
  25. const elemId = href.replace('#', '');
  26. const targetDom = document.getElementById(elemId);
  27. if (targetDom != null) {
  28. smoothScrollIntoView(targetDom, WIKI_HEADER_LINK);
  29. if (callback != null) {
  30. callback(targetDom);
  31. }
  32. }
  33. });
  34. });
  35. };