smooth-scroll.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. const WIKI_HEADER_LINK = 120;
  2. export const smoothScrollIntoView = (element: HTMLElement, offsetTop = 0, scrollElement: HTMLElement | Window = window): 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. scrollElement.scrollTo({
  8. top,
  9. behavior: 'smooth',
  10. });
  11. };
  12. /**
  13. * scroll to the top of the target element
  14. * by using JQuery slimScroll: http://rocha.la/jQuery-slimScroll
  15. */
  16. export const jQuerySlimScrollIntoView = (scrollableElement: HTMLElement, scrollTargetElement: HTMLElement, offsetTop = 0): void => {
  17. const targetTop = scrollTargetElement.getBoundingClientRect().top;
  18. const scrollTo = targetTop - offsetTop;
  19. (<any>$(scrollableElement)).slimScroll({ scrollTo });
  20. };
  21. export type SmoothScrollEventCallback = (elem: HTMLElement) => void;
  22. export const addSmoothScrollEvent = (elements: HTMLAnchorElement[], callback?: SmoothScrollEventCallback): void => {
  23. elements.forEach((link) => {
  24. const href = link.getAttribute('href');
  25. if (href == null) {
  26. return;
  27. }
  28. link.addEventListener('click', (e) => {
  29. e.preventDefault();
  30. // modify location.hash without scroll
  31. window.history.pushState({}, '', link.href);
  32. // smooth scroll
  33. const elemId = href.replace('#', '');
  34. const targetDom = document.getElementById(elemId);
  35. if (targetDom != null) {
  36. smoothScrollIntoView(targetDom, WIKI_HEADER_LINK);
  37. if (callback != null) {
  38. callback(targetDom);
  39. }
  40. }
  41. });
  42. });
  43. };