延迟加载 javascript 脚本?

Lazy-load a javascript script?

有没有一种方法可以包装具有延迟加载行为的外部 JS 脚本,使其仅在嵌入位于视口中时执行?

上下文:我有一个外部 javascript 嵌入,当 运行 时,生成一个带有计划小部件的 iframe。工作得很好,除了当脚本执行时,它 steals focus 并在完成执行后将您向下滚动到小部件。供应商几周来一直在寻找修复方法,但它弄乱了我的页面。否则我喜欢供应商。

Javascript 嵌入调用:

<a href=https://10to8.com/book/zgdmlguizqqyrsxvzo/ id="TTE-871dab0c-4011-4293-bee3-7aabab857cfd" target="_blank">See
    Online Booking Page</a>
<script src=https://d3saea0ftg7bjt.cloudfront.net/embed/js/embed.min.js> </script> <script>
    window.TTE.init({
        targetDivId: "TTE-871dab0c-4011-4293-bee3-7aabab857cfd",
        uuid: "871dab0c-4011-4293-bee3-7aabab857cfd",
        service: 1158717
    });
</script>

当我在等待供应商修复他们的 js 时,我想知道延迟加载 JS 嵌入是否实际上可以消除糟糕的用户体验。警告:我是一个 JS/webdev 菜鸟,所以可能无法做任何复杂的事情。基于计时器的解决方法并不理想,因为当计时器 运行 结束时,用户可能仍在查看页面的其他部分。以下是我尝试过的方法以及发生的情况:

I tried: What happened:
Add async to one or both of the script declarations above Either only shows the link or keeps stealing focus.
Adding type=”module” to one or both script declarations above Only rendered the link.
Wrapping the above code in an iframe with the appropriate lazy-loading tags When I tried, it rendered a blank space.

此外,我意识到这基本上与 this 相同的问题,但没有得到任何可行的答案。

其实我也会说法语,不过我会用英文回复大家。

你的问题很有趣,因为我也想尝试一些延迟加载,所以我用你的例子在 Codepen 上玩了一下(使用你的预订 ID)。

我使用了 appear.js 库,因为我真的不想花时间尝试其他一些 API(考虑到可能更轻量)。

我写的主要JS部分是这样的:

// The code to init the appear.js lib and add our logic for the booking links.
(function(){
  // Perhaps these constants could be put in the generated HTML. I don't really know
  // where they come from but they seem to be related to an account.
  const VENDOR_LIB_SRC = "https://d3saea0ftg7bjt.cloudfront.net/embed/js/embed.min.js";
  const UUID = "871dab0c-4011-4293-bee3-7aabab857cfd";
  const SERVICE = 1158717;
  
  let vendorLibLoaded = false; // Just to avoid loading several times the vendor's lib.

  appear({
    elements: function() {
      return document.querySelectorAll('a.booking-link');
    },
    appear: function(bookingLink) {
      console.log('booking link is visible', bookingLink);
      
      /**
       * A function which we'll be able to execute once the vendor's
       * script has been loaded or later when we see other booking links
       * in the page.
       */
      function initBookingLink(bookingLink) {
        window.TTE.init({
          targetDivId: bookingLink.getAttribute('id'),
          uuid: UUID,
          service: SERVICE
        });
      }
      
      if (!vendorLibLoaded) {
        // Load the vendor's JS and once it's loaded then init the link.
        let script = document.createElement('script');
        script.onload = function() {
          vendorLibLoaded = true;
          initBookingLink(bookingLink);
        };
        script.src = VENDOR_LIB_SRC;
        document.head.appendChild(script);
      } else {
        initBookingLink(bookingLink);
      }
    },
    
    reappear: false
  });
})();

我让你在这里试试我的代码笔:https://codepen.io/patacra/pen/gOmaKev?editors=1111

如果它包含敏感数据,请告诉我何时删除它!

亲切的问候,

帕特里克

此方法仅在用户可见时延迟加载 HTML 元素,如果元素未滚动到视口中,则不会加载,其工作方式类似于延迟加载图像。

LazyHTML 脚本添加到 Head。

<script async src="https://cdn.jsdelivr.net/npm/lazyhtml@1.0.0/dist/lazyhtml.min.js" crossorigin="anonymous" debug></script>

在 LazyHTML 包装器中包装元素。

<div class="lazyhtml" data-lazyhtml onvisible>
<script type="text/lazyhtml">
      <!--
       <a href=https://10to8.com/book/zgdmlguizqqyrsxvzo/ id="TTE-871dab0c-4011-4293-bee3-7aabab857cfd" target="_blank">See
      Online Booking Page</a>
      <script src=https://d3saea0ftg7bjt.cloudfront.net/embed/js/embed.min.js>
   </script> 
   <script>
      window.TTE.init({
      targetDivId: "TTE-871dab0c-4011-4293-bee3-7aabab857cfd",
      uuid: "871dab0c-4011-4293-bee3-7aabab857cfd",
      service: 1158717
      });
   </script>
   -->
</script>
</div>