是否可以允许 iframe resizeTo/By moveTo/By?

Posted

技术标签:

【中文标题】是否可以允许 iframe resizeTo/By moveTo/By?【英文标题】:Is it possible to allow an iframe to resizeTo/By moveTo/By? 【发布时间】:2021-10-18 01:57:44 【问题描述】:

是否可以配置 iframe 的父级以允许 iframe 调整大小和类似功能 (moveTo) ?

还是我需要手动将消息传递给父级?

iframe

window.resizeTo = function(w,h)
 parent.postMessage(
  "command":"window_resizeTo",
  "data":width:w,height:h
 , "*")

父母

function receiveMessage(event)

 var message = event.data;
 var command = message.command;
 var properties = message.data;

 switch(command)
 
    case "window_resizeTo":
        $(#iframe").setAttribute("style", `width:$properties.widthpx;height:$properties.heightpx`)
        break;
    // and so on for every function I wish to proxy
 

编辑: iframe 和父级是同源的。 我知道我可以在 iframe 内部使用 window.parent (然后调整 iframe 的大小会很容易)。 我的问题更多的是关于允许自动绑定而不是自己做的 iframe 选项。

EDIT2 这可能不存在。因为用例会太窄。即使父母同意让 iframe 自行调整大小,父母也可能希望限制区域和/或添加偏移量。

答案是: iframe 中已经有 window.resizeTo 和类似的函数,但是(由于滥用)它们可能什么都不做。 如果您想在父级上下文中调整 iframe 的大小/移动 iframe,则必须自己进行“绑定”。 没有直接绑定:您必须在更改 iframe 偏移/宽度的函数中转换调整大小函数。如果 iframe 和父级具有相同的来源,您可以从父级本身操作父级(以及 iframe)。我不推荐这个。 更好的选择可能是向父母发送消息。

【问题讨论】:

IFrame 是否遵循同源策略? 是的。描述已更改以反映这一点。 【参考方案1】:

如果 IFrame-Content 是从不同的来源加载的,则必须使用 postMessage-Event 给 IFrame 更改其大小的机会。看看 MDN 上的Definition of an origin。

如果 IFrame-Content 遵循同源策略,您可以从 iframe 中访问 window.parent.document 并直接修改父节点。

可以使用以下方法找到父文档中的节点:

// script at the iframe document
try 
  const node = [...window.parent.document.querySelectorAll("iframe")]
     .find(iframe => 
       try  // avoid errors from inaccessible iframes
         return iframe.contentWindow == window
        catch (e) 
     );
  if (node) 
    node.setAttribute("style", "...");
  
 catch(e) 
  // unable to access parent

【讨论】:

想了想,我的问题没有多大意义。无论如何,我能想到的改变 iframe 属性的两种方法是你的(iframe 操作其父级)和我的(iframe 向其父级发送消息)。所以我标记了你的答案。【参考方案2】:

试试这个例子,为我工作,问候。

<script type="application/javascript">    

    function resizeIFrameToFitContent( iFrame ) 

        iFrame.width  = iFrame.contentWindow.document.body.scrollWidth;
        iFrame.height = iFrame.contentWindow.document.body.scrollHeight;
   

    window.addEventListener('DOMContentLoaded', function(e) 
            var iFrame = document.getElementById( 'iFrame1' );
            resizeIFrameToFitContent( iFrame );

            // or, to resize all iframes:
            var iframes = document.querySelectorAll("iframe");
            for( var i = 0; i < iframes.length; i++) 
            resizeIFrameToFitContent( iframes[i] );
       
    );

</script>

<iframe src="usagelogs/default.aspx" id="iFrame1"></iframe>

【讨论】:

欢迎来到 Stack Overflow!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。 感谢罗德梅森的回答。我不是 100% 确定“DOMContentLoaded”事件也适用于 iframe 的 domcontent。您的代码(如果我理解得很好)更多的是关于将一​​个(所有)iframe 调整为实际大小。这很好。但在我的情况下,iframe 的调整大小事件可以随时发生。我认为当 iframe 想要调整大小时,最好让 iframe 向其父级发出信号。 @v1nce DOMContentLoaded 仅适用于当前窗口,不适用于 iframe,但每次 iframe 更改其位置时都会触发 &lt;iframe onload&gt;,而不会告诉您其他任何信息,例如它已更改为的 uri .你可以看看这个小提琴:jsfiddle.net/ow6hm3qe

以上是关于是否可以允许 iframe resizeTo/By moveTo/By?的主要内容,如果未能解决你的问题,请参考以下文章

检查网站是不是不允许嵌入 iframe

听说<iframe>可以用作弹出窗口,请问是如何实现的?(最好有例子说明)

HTTP 和 HTTPS iframe

Magento - 如何在 Magento 的 CMS 编辑器中允许某些标签(iframe、嵌入)?

每个网页的最大 <iFrame> 标记数

获取 iframe 源?