about.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. document.body.classList.add('about-nav-light');
  2. (function () {
  3. var siteHeader = document.getElementById('siteHeader');
  4. var siteLogoImg = document.getElementById('siteLogoImg');
  5. var links = Array.prototype.slice.call(document.querySelectorAll('.about-side-link'));
  6. var panels = Array.prototype.slice.call(document.querySelectorAll('.about-panel[data-panel]'));
  7. var accordions = Array.prototype.slice.call(document.querySelectorAll('.about-inline-accordion'));
  8. function syncAboutHeader() {
  9. if (!siteHeader) return;
  10. siteHeader.classList.remove('hero-theme-light');
  11. siteHeader.classList.add('hero-theme-dark', 'page-navbar-solid');
  12. }
  13. if (siteHeader) {
  14. syncAboutHeader();
  15. if (siteLogoImg) {
  16. var darkLogo = siteLogoImg.getAttribute('data-logo-dark');
  17. if (darkLogo) siteLogoImg.src = darkLogo;
  18. }
  19. window.addEventListener('scroll', syncAboutHeader, { passive: true });
  20. document.addEventListener('DOMContentLoaded', syncAboutHeader);
  21. }
  22. function setActiveLink(id) {
  23. links.forEach(function (link) {
  24. var active = link.getAttribute('data-target') === id;
  25. link.classList.toggle('is-active', active);
  26. if (active) link.setAttribute('aria-current', 'true');
  27. else link.removeAttribute('aria-current');
  28. });
  29. panels.forEach(function (panel) {
  30. panel.classList.toggle('is-active', panel.getAttribute('data-panel') === id);
  31. });
  32. }
  33. links.forEach(function (link) {
  34. link.addEventListener('click', function (event) {
  35. event.preventDefault();
  36. var targetId = link.getAttribute('data-target');
  37. var targetEl = targetId ? document.getElementById(targetId) : null;
  38. if (targetEl) {
  39. targetEl.scrollIntoView({ behavior: 'smooth', block: 'start' });
  40. setActiveLink(targetId);
  41. }
  42. });
  43. });
  44. if ('IntersectionObserver' in window && panels.length) {
  45. var observer = new IntersectionObserver(function (entries) {
  46. var visible = entries.filter(function (entry) { return entry.isIntersecting; }).sort(function (a, b) { return b.intersectionRatio - a.intersectionRatio; });
  47. if (visible.length) setActiveLink(visible[0].target.getAttribute('data-panel'));
  48. }, { threshold: [0.35, 0.5, 0.68, 0.85], rootMargin: '-16% 0px -22% 0px' });
  49. panels.forEach(function (panel) { observer.observe(panel); });
  50. } else if (panels.length) {
  51. var onScroll = function () {
  52. var current = panels[0];
  53. var marker = window.innerHeight * 0.42;
  54. panels.forEach(function (panel) {
  55. var rect = panel.getBoundingClientRect();
  56. if (rect.top <= marker && rect.bottom >= marker) current = panel;
  57. });
  58. if (current) setActiveLink(current.getAttribute('data-panel'));
  59. };
  60. window.addEventListener('scroll', onScroll, { passive: true });
  61. onScroll();
  62. }
  63. function initAccordion(accordion) {
  64. var stageButtons = Array.prototype.slice.call(accordion.querySelectorAll('.about-accordion-year'));
  65. var stagePanels = Array.prototype.slice.call(accordion.querySelectorAll('.about-stage-panel[data-stage-panel]'));
  66. var stageItems = Array.prototype.slice.call(accordion.querySelectorAll('.about-inline-accordion-item[data-accordion-item], .about-inline-accordion-item'));
  67. function setActiveStage(targetId) {
  68. if (!targetId) return;
  69. stageButtons.forEach(function (button) {
  70. button.classList.toggle('is-active', button.getAttribute('data-stage-target') === targetId);
  71. });
  72. stagePanels.forEach(function (panel) {
  73. panel.classList.toggle('is-active', panel.id === targetId);
  74. });
  75. stageItems.forEach(function (item) {
  76. var button = item.querySelector('.about-accordion-year');
  77. var active = button && button.getAttribute('data-stage-target') === targetId;
  78. item.classList.toggle('is-active', !!active);
  79. });
  80. }
  81. stageButtons.forEach(function (button) {
  82. button.addEventListener('click', function () {
  83. setActiveStage(button.getAttribute('data-stage-target'));
  84. });
  85. });
  86. if (stageButtons.length) {
  87. setActiveStage(stageButtons[0].getAttribute('data-stage-target'));
  88. }
  89. }
  90. accordions.forEach(initAccordion);
  91. Array.prototype.slice.call(document.querySelectorAll('[data-stage-slider]')).forEach(function (slider) {
  92. var slides = Array.prototype.slice.call(slider.querySelectorAll('[data-stage-slide]'));
  93. var prevBtn = slider.querySelector('.about-stage-arrow-prev');
  94. var nextBtn = slider.querySelector('.about-stage-arrow-next');
  95. var index = 0;
  96. slides.forEach(function (slide, i) {
  97. slide.hidden = false;
  98. slide.classList.toggle('is-active', i === 0);
  99. });
  100. function render(direction) {
  101. slides.forEach(function (slide, slideIndex) {
  102. slide.classList.remove('is-active', 'is-leaving-left', 'is-leaving-right', 'is-entering-left', 'is-entering-right');
  103. if (slideIndex === index) {
  104. if (direction === 'prev') slide.classList.add('is-entering-left');
  105. if (direction === 'next') slide.classList.add('is-entering-right');
  106. requestAnimationFrame(function () {
  107. slide.classList.add('is-active');
  108. slide.classList.remove('is-entering-left', 'is-entering-right');
  109. });
  110. }
  111. });
  112. var single = slides.length <= 1;
  113. prevBtn.disabled = single;
  114. nextBtn.disabled = single;
  115. prevBtn.style.display = single ? 'none' : 'flex';
  116. nextBtn.style.display = single ? 'none' : 'flex';
  117. }
  118. prevBtn.addEventListener('click', function () {
  119. if (slides.length <= 1) return;
  120. slides[index].classList.add('is-leaving-right');
  121. index = (index - 1 + slides.length) % slides.length;
  122. render('prev');
  123. });
  124. nextBtn.addEventListener('click', function () {
  125. if (slides.length <= 1) return;
  126. slides[index].classList.add('is-leaving-left');
  127. index = (index + 1) % slides.length;
  128. render('next');
  129. });
  130. render();
  131. });
  132. if (panels.length) {
  133. setActiveLink(panels[0].getAttribute('data-panel'));
  134. }
  135. })();