Lazy loading Giscus on user interaction

47 Views Asked by At

I am integrating Giscus into my website for comments. I want to load the Giscus script dynamically after either a mouse movement or scrolling event on the page.

I would like to modify this script so that the Giscus script loads when the user moves the mouse or scrolls the page. I have tried adding event listeners for both mouse movement and scrolling, but I'm not getting the desired result.

Here's my attempt:

<!-- Modified Giscus Script with Event Listeners -->
  <script type="text/javascript">
    (function() {
      const themeToggle = document.querySelector('.darkmode-toggle input');
      const light = 'light';
      const dark = 'dark';
      let isDark = localStorage.theme === dark || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches);
      let theme = isDark ? dark : light;
  
      const s = document.createElement('script');
      s.type = 'text/javascript';
      const dataset = {
          repo: '{{ .repo }}',
          repoId: '{{ .repoId }}',
          category: '{{ .category }}',
          categoryId: '{{ .categoryId }}',
          mapping: '{{ .mapping }}',
          reactionsEnabled: '{{ .reactionsEnabled }}',
          emitMetadata: '{{ .emitMetadata }}',
          theme: theme,
          lang: '{{ .lang }}',
      };
      s.src = 'https://giscus.app/client.js';
      s.crossorigin = 'anonymous';
      s.async = true;
      Object.entries(dataset).forEach(function(a) {
          return s.dataset[a[0]] = a[1];
      });
  
      const curScriptElement = document.currentScript;
      curScriptElement.parentNode.insertBefore(s, curScriptElement);
  
      function sendMessage(message) {
        const iframe = document.querySelector('iframe.giscus-frame');
        // console.log(iframe);
        if (!iframe) return;
        iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
      }
  
      function loadGiscusScript() {
        if (!s.parentElement) {
          curScriptElement.parentNode.insertBefore(s, curScriptElement);
        }
      }
  
      document.addEventListener('mouse-move', loadGiscusScript);
      window.addEventListener('scroll-window', loadGiscusScript);
  
      themeToggle.addEventListener('change', function () {
        if (this.checked) {
          theme = dark;
        } else {
          theme = light;
        }
        sendMessage({
          setConfig: {
            theme: theme,
          }
        });
      });
    })();
  </script>

However, this doesn't seem to work as expected. The Giscus script doesn't load after mouse movement or scrolling.

Can someone please help me understand what I might be doing wrong, and suggest a solution to dynamically load the Giscus script after mouse movement or scrolling events?

Any insights or alternative approaches would be greatly appreciated! Thank you in advance.

1

There are 1 best solutions below

0
On

You have a typo, there are no such events as you have demonstrated. Instead the event is mousemove and scroll.

But, this is not an ideal approach. As coded, you're going to continually trigger the event listener. You can do this by adding the once option like this: listener.addEventListener(eventName, handler, { once: true }).

But what you should be looking at is an Intersection Observer, which will trigger when an element is in view