main.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /**
  2. * Utils
  3. */
  4. // Load and run script via AJAX
  5. //
  6. const loadScript = (source, beforeEl, async = true, defer = true) => {
  7. return new Promise((resolve, reject) => {
  8. let script = document.createElement('script');
  9. const prior = beforeEl || document.getElementsByTagName('script')[0];
  10. script.async = async;
  11. script.defer = defer;
  12. function onloadHander(_, isAbort) {
  13. if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) {
  14. script.onload = null;
  15. script.onreadystatechange = null;
  16. script = undefined;
  17. if (isAbort) { reject(); } else { resolve(); }
  18. }
  19. }
  20. script.onload = onloadHander;
  21. script.onreadystatechange = onloadHander;
  22. script.src = source;
  23. prior.parentNode.insertBefore(script, prior);
  24. });
  25. }
  26. // Throttle
  27. //
  28. const throttle = (callback, limit) => {
  29. let timeoutHandler = null;
  30. return () => {
  31. if (timeoutHandler == null) {
  32. timeoutHandler = setTimeout(() => {
  33. callback();
  34. timeoutHandler = null;
  35. }, limit);
  36. }
  37. };
  38. };
  39. /**
  40. * Functions
  41. */
  42. // Auto Hide Header
  43. //
  44. let lastScrollPosition = window.pageYOffset;
  45. let header = document.getElementById('site-header');
  46. const autoHideHeader = () => {
  47. let currentScrollPosition = window.pageYOffset;
  48. if (currentScrollPosition > lastScrollPosition) {
  49. header.classList.remove('slideInUp');
  50. header.classList.add('slideOutDown');
  51. }
  52. else {
  53. header.classList.remove('slideOutDown');
  54. header.classList.add('slideInUp');
  55. }
  56. lastScrollPosition = currentScrollPosition;
  57. }
  58. // Mobile Menu Toggle
  59. //
  60. let mobileMenu = document.getElementById('mobile-menu');
  61. let mobileMenuVisible = false;
  62. const mobileMenuToggle = () => {
  63. if (mobileMenuVisible == false) {
  64. mobileMenu.style.animationName = 'bounceInRight';
  65. mobileMenu.style.webkitAnimationName = 'bounceInRight';
  66. mobileMenu.style.display = 'block';
  67. mobileMenuVisible = true;
  68. } else {
  69. mobileMenu.style.animationName = 'bounceOutRight';
  70. mobileMenu.style.webkitAnimationName = 'bounceOutRight'
  71. mobileMenuVisible = false;
  72. }
  73. }
  74. if (haveHeader == true) {
  75. document.getElementById('menu-btn').addEventListener('click', mobileMenuToggle);
  76. }
  77. // Show Featured Image
  78. //
  79. const showFeaturedImg = () => {
  80. document.getElementById('bg-img').classList.add('show-bg-img');
  81. }
  82. const showContent = () => {
  83. document.getElementById('bg-img').classList.remove('show-bg-img');
  84. }
  85. //Load Comments
  86. //
  87. let commentsLoaded = false;
  88. let comments = document.getElementById('comments');
  89. let commentsLoader = document.getElementById('comments-loader');
  90. const avJsUrl = '//cdn1.lncld.net/static/js/3.0.4/av-min.js';
  91. const valineJsUrl = '//unpkg.com/valine@1.3.1/dist/Valine.min.js';
  92. const loadComments = () => {
  93. loadScript(avJsUrl).then(() => {
  94. loadScript(valineJsUrl).then(() => {
  95. new Valine({
  96. el: '#comments',
  97. appId: 'QfBLso0johYg7AXtV9ODU6FC-gzGzoHsz',
  98. appKey: 'J1tpEEsENa48aLVsPdvwMP14',
  99. placeholder: '说点什么吧',
  100. verify: true
  101. });
  102. commentsLoader.style.display = 'none';
  103. }, () => {
  104. console.log('Failed to Load Valine.min.js');
  105. });
  106. }, () => {
  107. console.log('Failed to Load av-min.js');
  108. });
  109. }
  110. // Load comments if the window is not scrollable
  111. if ((haveComments == true) && (comments.offsetTop < window.innerHeight)) {
  112. commentsLoader.style.display = 'block';
  113. loadComments();
  114. commentsLoaded = true;
  115. }
  116. window.addEventListener('scroll', throttle(() => {
  117. if (haveHeader == true) {
  118. autoHideHeader();
  119. if (mobileMenuVisible == true) {
  120. mobileMenuToggle();
  121. }
  122. }
  123. if ((haveComments == true) && (commentsLoaded == false)) {
  124. if (window.pageYOffset + window.innerHeight > comments.offsetTop) {
  125. commentsLoader.style.display = 'block';
  126. loadComments();
  127. commentsLoaded = true;
  128. }
  129. }
  130. }, 250));