仅在触发模态后才延迟加载iframe [英] Lazy Load Iframe Only After Modal is Triggered

查看:60
本文介绍了仅在触发模态后才延迟加载iframe的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:我无法在模式窗口上本地延迟加载iframe.当我在检查元素>中检查瀑布时网络,iframe会立即加载.

Issue: I cannot natively lazy load an iframe on a modal window. When I check the waterfall in Inspect element > Network, the iframe loads immediately.

目标:触发模式后,iframe应该仅加载.你能帮忙吗?

Goal: The iframe should load ONLY when modal is triggered. Can you help please?

我不使用jQuery之类的依赖项,但是javascript如果可以提供解决方案,则可以.我尝试了本机和其他几种延迟加载解决方案,但均未成功.

I don't use dependencies like jQuery, but javascript is OK if it provides a solution. I tried the native and several other lazy loading solutions with no success.

我的代码:

.modal-state {
  display: none
}

.modal-state:checked+.modal {
  opacity: 1;
  visibility: visible
}

.modal-state:checked+.modal .modal__inner {
  top: 0
}

.modal {
  opacity: 0;
  visibility: hidden;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  text-align: left;
  background: #f2f2f2;
  transition: opacity .01s ease;
  z-index: 7;
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow-y: auto
}

.modal__bg {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  cursor: pointer
}

.modal__inner {
  transition: top .01s ease;
  height: max-content;
  position: relative;
  max-width: 1200px;
  width: -webkit-fill-available;
  margin: auto;
  padding: 1em 1em;
}

.modal__close {
  position: absolute;
  right: 1.1em;
  top: 0;
  /*-.3em*/
  width: 1.1em;
  height: 1.1em;
  cursor: pointer;
  z-index: 1
}

.modal__close:after,
.modal__close:before {
  content: '';
  position: absolute;
  width: 2px;
  height: 1.5em;
  background: #999;
  display: block;
  transform: rotate(45deg);
  left: 50%;
  margin: -3px 0 0 -1px;
  top: 0
}

.modal__close:hover:after,
.modal__close:hover:before {
  background: #000
}

.modal__close:before {
  transform: rotate(-45deg)
}

.container-pay {
  position: relative;
  width: 100%;
  height: 200px;
  overflow: hidden;
  padding-top: 56.25%;
  /* 16:9 Aspect Ratio */
}

.responsive-iframe-pay {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  width: 100%;
  height: 100%;
  border: none;
}

<p>In our <label for="modal-store">merchandize store</label>.</p>


<input class="modal-state" id="modal-store" type="checkbox" />

<div class="modal">
  <label class="modal__bg" for="modal-store"></label>
  <div class="modal__inner"><label class="modal__close" for="modal-store"></label>
    <p>
      <div class="container-pay">
        <iframe loading="lazy" class="responsive-iframe-pay" src="https://store.website.com"></iframe>
      </div>
    </p>
  </div>
</div>

推荐答案

在呈现的HTML DOM中遇到iFrame时,它们会加载.由于您的iFrame是最初加载的代码的一部分,因此它将在解析器访问HTML的那部分时加载.

iFrames load when they're encountered in the rendered HTML DOM. Since your iFrame exists as part of the initially loaded code, it will load when the parser hits that portion of the HTML.

您可以通过将iFrame添加到DOM或在打开模式窗口之前修改URL来击败该初始加载操作.

You can defeat that initial load action by either adding the iFrame to the DOM or modifying the URL right before the modal window is opened.

修改< iframe src ="/> 可能是最好的解决方案,因为它将在显示模态的任何其他时间保持加载的内容.

Modifying the <iframe src="" /> is likely the best solution since it will keep the loaded content for any additional times the modal is displayed.

您可以通过添加"onchange"来实现此目的.事件进入复选框,该复选框将运行javascript来更改iframe的src属性.

You can do this by adding an "onchange" event to the checkbox which will run the javascript to change the src attribute of the iframe.

请确保将iframe上的 src 更改为空字符串"" ,这样它就不会尝试立即加载任何内容.

Make sure to change the src on the iframe to an empty string"" so it doesn't try to load anything right away.

var toggle = document.getElementById('modal-store');
var frame = document.getElementById('the-iframe');
var urlTarg = "https://google.com";
// put the page you want to load in the frame in the urlTarg

function toggleModal() {
  if(toggle.checked && frame.src != urlTarg){
     frame.src = urlTarg;
  }
}

.modal-state {
      display: none
    }

    .modal-state:checked+.modal {
      opacity: 1;
      visibility: visible
    }

    .modal-state:checked+.modal .modal__inner {
      top: 0
    }

    .modal {
      opacity: 0;
      visibility: hidden;
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      text-align: left;
      background: #f2f2f2;
      transition: opacity .01s ease;
      z-index: 7;
      display: flex;
      flex-direction: column;
      height: 100vh;
      overflow-y: auto
    }

    .modal__bg {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      cursor: pointer
    }

    .modal__inner {
      transition: top .01s ease;
      height: max-content;
      position: relative;
      max-width: 1200px;
      width: -webkit-fill-available;
      margin: auto;
      padding: 1em 1em;
    }

    .modal__close {
      position: absolute;
      right: 1.1em;
      top: 0;
      /*-.3em*/
      width: 1.1em;
      height: 1.1em;
      cursor: pointer;
      z-index: 1
    }

    .modal__close:after,
    .modal__close:before {
      content: '';
      position: absolute;
      width: 2px;
      height: 1.5em;
      background: #999;
      display: block;
      transform: rotate(45deg);
      left: 50%;
      margin: -3px 0 0 -1px;
      top: 0
    }

    .modal__close:hover:after,
    .modal__close:hover:before {
      background: #000
    }

    .modal__close:before {
      transform: rotate(-45deg)
    }

    .container-pay {
      position: relative;
      width: 100%;
      height: 200px;
      overflow: hidden;
      padding-top: 56.25%;
      /* 16:9 Aspect Ratio */
    }

    .responsive-iframe-pay {
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
      width: 100%;
      height: 100%;
      border: none;
    }

    <p>In our <label for="modal-store">merchandize store</label>.</p>

    <input class="modal-state" id="modal-store" type="checkbox" onchange="toggleModal" />

    <div class="modal">
      <label class="modal__bg" for="modal-store"></label>
      <div class="modal__inner"><label class="modal__close" for="modal-store"></label>
        <p>
          <div class="container-pay">
            <iframe id="the-iframe" loading="lazy" class="responsive-iframe-pay" src=""></iframe>
          </div>
        </p>
      </div>
    </div>

您可以通过一些修改将其应用于同一页面或同一网站上的多个iframe目标.假定:

You can apply this to multiple iframe targets on the same page or the same site with a few modifications. This assumes that:

  1. 您将重新使用模式窗口和iframe HTML代码.
  2. 您希望每次打开模式时都显示一个不同的URL
  3. 模态窗口HTML存在于您要使用模态+ iframe的每个HTML页面上.

您可以将Javascript修改为如下形式:

You would modify the Javascript to something like this:

    // you'll pass all the required values to the function

    function toggleModal(checkbox, frameTarg, urlTarg) {
      var frame = document.getElementById(frameTarg);
      if(checkbox.checked && frame.src != urlTarg){
         frame.src = urlTarg;
      }
    }

每个父页面只需要使用一次javascript,因为同一功能可以用于复选框,iframe和URL的任何组合

You will only need the javascript once per parent page since the same function can work for any combo of checkboxes, iframes, and URLs

和复选框HTML可以:(注意:同一功能可以应用于按钮,链接等)

And the checkbox HTML to: (Note: the same function could be applied to a button, link, etc)

<input class="modal-state" 
   id="modal-store" 
   type="checkbox" 
   onchange="toggleModal(this, 'the-iframe', 'https://theurltoloadinframe.com')" 
/>

<input class="modal-state2" 
   id="modal-store" 
   type="checkbox" 
   onchange="toggleModal(this, 'iframe2', 'https://someotherurltoload.com')" 
/>

基本上,该函数希望您传递:

Basically, the function expects you to pass in:

  1. 当前复选框-(由 this 表示)
  2. 您要更改的iframe的ID,请确保其为带引号的字符串
  3. 您要在iFrame中加载的URL也以字符串形式

这篇关于仅在触发模态后才延迟加载iframe的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆