smooth-scroll.ts 1.2 KB

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