1

我有一个主(父)页面,其中托管了同一域下的 3 个 iframe。iframe 的 src 属性是在点击事件上添加的,因此 iframe 直到需要时才会加载。

我想要的是当我单击主页上的某个 div 时,它会触发对同时位于所有 3 个 iframe 内的特定 div 的单击。

我在父页面中尝试了以下代码:

function myFunction() {
  var iframe = document.getElementById("iframe1");
  var elmnt = iframe.contentWindow.document.getElementById("btn").click()
}

#iframe2并为 iframe和.重复了两次#iframe3。但是,除非我加载 iframe 以便将它们写在我的页面上,否则它不起作用。(即点击事件#iframe2直到 after 事件才执行#iframe1)。这是一个问题,因为我无法控制 iframe 访问者首先加载的内容。我尝试给它们单独的 function() 名称,但发生了同样的事情 - 一次只影响一个 iframe。请注意,当我使用 iframe 已经像正常一样拥有它们的 src 进行测试时,这工作正常,只是在手动添加它们时不行。

我还尝试在 iframe 页面中添加它:

parent.document.getElementById('btn').onclick = function(){
 document.getElementById('btn').click();
}

但是,这仅适用于加载的第一个 iframe(即,如果#iframe2先加载,则iframe1's 和iframe3' 事件不会执行)

我可以尝试其他解决方案吗?我的目的是创建一个昼夜切换classList.toggle,我希望iframes同时切换所有的 CSS,切换按钮位于主页上。

(我的主页更喜欢 vanilla javascript,但 iframe 页面上的 jQuery 很好)

4

2 回答 2

1

假设用户加载,您正在动态加载 iframe 的 src ,但是您的代码的编写方式是它试图在内部(尚未加载)<iframe3>做某事会发生什么?它会抛出错误并中断执行,这就是为什么它不适合你的原因你需要先看看它们当前是否在那里你也在使用,但我在你发布的小提琴上看不到任何 id<div><iframe1>var iframe = document.getElementById("iframe1");

试试这个

<body>

<style>
body {
  background:#fff;
  color:#000
}

body.toggled 
{
    background:#000;
    color:#fff
}
</style>

<div id="btn">click here to toggle css</div>
<p>page content</p>

<a href="/iframe1" target="iframe1">add src to iframe one</a><br>
<a href="/iframe2" target="iframe2">add src to iframe two</a><br>
<a href="/iframe3" target="iframe3">add src to iframe three</a>

<p>iframe 1:</p>
<iframe src="about:blank" id="iframe1" name="iframe1"></iframe>

<p>iframe 2:</p>
<iframe src="about:blank" id="iframe2" name="iframe2"></iframe>

<p>iframe 3:</p>
<iframe src="about:blank" id="iframe3" name="iframe3"></iframe>
</body>

<script>

    document.querySelector('#btn').addEventListener('click', function(e) {
    [].map.call(document.querySelectorAll('body,a'), function(el) {
     el.classList.toggle('toggled');
    });


    var iframe1 = document.getElementById("iframe1");
    var iframe1btn = iframe1.contentWindow.document.getElementById("btn");
    if(iframe1btn) //<-- check if that element really exists within <iframe>
        iframe1.contentWindow.document.getElementById("btn").click()
    // you could've also used <iframe>'s loaded event but this is better way

    var iframe2 = document.getElementById("iframe2");
    var iframe2btn = iframe2.contentWindow.document.getElementById("btn");
    if(iframe2btn)
        iframe2.contentWindow.document.getElementById("btn").click()

    var iframe3 = document.getElementById("iframe3");
    var iframe3btn = iframe3.contentWindow.document.getElementById("btn");
    if(iframe3btn)
        iframe3.contentWindow.document.getElementById("btn").click()

});

</script>
于 2020-01-04T05:52:55.613 回答
1

我不是特别确定你做错了什么,但我想我明白你想做什么。要重现此示例,请在本地 PC 中创建一个 HTML 文件(名称为index.html)并在浏览器上运行此文件:

<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        background: #fff;
        color: #000;
      }


      body.toggled {
        background: #000;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div id="btn">click here to toggle css</div>
    <p>page content</p>

    <a href = "" target="iframe1">add src to iframe one</a><br>
    <a href = "" target="iframe2">add src to iframe two</a><br>
    <a href = "" target="iframe3">add src to iframe three</a>

    <p>iframe 1:</p>
    <iframe src="about:blank" name="iframe1"></iframe>

    <p>iframe 2:</p>
    <iframe src="about:blank" name="iframe2"></iframe>

    <p>iframe 3:</p>
    <iframe src="about:blank" name="iframe3"></iframe>

    <script>
      let outerBody = document.querySelector('body')
      let toggleButton = document.querySelector('#btn')
      let iframes = document.querySelectorAll('iframe')
      let anchors = document.querySelectorAll('a')

      toggleButton.addEventListener('click', () => {
        let body = document.querySelector('body')
        body.classList.toggle('toggled')
        Array.from(iframes).forEach(iframe => {
          toggleIframe(iframe)
        })    
      })

      Array.from(iframes).forEach(iframe => {
        iframe.addEventListener('load', e => {
          toggleIframe(iframe)
        })
      })

      Array.from(anchors).forEach(anchor => {
        anchor.addEventListener('click', e => {
          let targetedIframe = document.querySelector(`iframe[name=${anchor.target}]`)
          targetedIframe.src = './index.html'
        })
      })

      function toggleIframe(iframe) {
        let iframeBody = iframe.contentWindow.document.querySelector('body')
        let iframeToggleButton = iframe.contentWindow.document.querySelector('#btn')
        let isOuterBodyToggled = outerBody.classList.contains('toggled')
        let isIframeBodyToggled = iframeBody.classList.contains('toggled')

        if (isOuterBodyToggled && iframeToggleButton && !isIframeBodyToggled)
          iframeToggleButton.click()
        else if (!isOuterBodyToggled && iframeToggleButton && isIframeBodyToggled)
          iframeToggleButton.click()
      }
    </script>
  </body>
</html> 

我将您a的 '更改href为空 ( #)。我还更改了您的 JS 文件。基本上,我指定了s 以在单击它时a更改其关联的来源。此外,每次单击'(父浏览上下文)按钮时,我还将通过单击' 按钮来切换其包含的 ' 正文。这已经奏效了。但是,您的问题是您不知道何时加载。在您的. 当 an被加载(an将在其源更改时再次加载)时,我将使用该事件侦听器来检查其父浏览上下文的主体是否被切换。如果是,那么只需切换iframeaddEventListener('click')outerBodyiframesiframesiframesaddEventListener('load')iframesiframeiframeiframe的身体也通过执行点击。

瞧,它有效。如前所述,请尝试将上面的代码粘贴到 PC 的本地文件中,然后在浏览器中运行。

于 2020-01-04T08:31:00.597 回答