Hibop / Hibop.github.io

Hibop 个人博客
https://hibop.github.io/
23 stars 1 forks source link

关于iframe一些问题汇总 #39

Open Hibop opened 6 years ago

Hibop commented 6 years ago

关于实现iframe功能替代方案

使用iframe能很好的嵌入其他的网页或者网站,但是iframe每次加载都会浪费好多的时间,且会阻止其他元素的加载,搜索引擎也不能识别页面ifram框架中被调用的链接、文本、图片等等内容的。

Html代码

<ul class="list-side">
  <li><a target="a.html" >about</a></li>
  <li><a target="b.html" >news</a></li>
  <li><a target="c.html" >product</a></li>
  <li><a href="http://ucmic.blogspot.com/" target="_blank" >contact</a></li>
</ul>

<div id="iframe">
  <!--jquery 插入html 位址-->
</div>

实现功能的Javascript代码

$(document).ready(function(){ 
  $.get("a.html",function(data){ //初始將a.html include div#iframe
    $("#iframe").html(data);
  }); 
$(function(){
  $('.list-side li').click(function() {
    // 找出 li 中的超链接 href(#id)
     var $this = $(this),
     _clickTab = $this.find('a').attr('target'); // 找到链接a中的targer的值
     $.get(_clickTab,function(data){
       $("#iframe").html(data); 
     });
  });
});

iframe 父子通信

同域: 数据交换和DOM元素互访就简单的多 , 其实质是DOM元素的访问 父 =>子 : window.parent window.top 子 => 父: window.getElementsByName('iframe')

注意事项 要确保在Iframe加载完成后再进行操作,如果Iframe还未加载完成就开始调用里面的方法或变量,无疑会产生错误。判断Iframe是否加载完毕有两种方法: 1.在Iframe上用onload事件; 2.用document.readyState=="complete"来判断

跨域: 安全机制则不能使用同域名下的通信方式 跨域iframe是实现前端微服务最简单易行的方式。

父页面向子页面传递数据

实现的技巧就是利用 location 对象的 hash 值,通过它传递通信数据,我们只需要在父页面设置 iframe的 src 后面多加个#data 字符串(data就是你要传递的数据),然后在 子页面 中通过某种方式能即时的获取到这儿 data 就可以了,其实常用的一种方式就是:

  1. 在 子页面 中通过 setInterval 方法设置定时器, 监听 location.href 的变化即可获得上面的 data 信息
  2. 然后 子页面 就能根据这个 data 信息进行相应的逻辑处理。

子页面向父页面传递数据 [比较复杂]

实现的技巧就是利用一个代理 Iframe C,它嵌入到 子页面中,并且和父页面必须保持是同域,然后我们通过它充分利用上面第一种通信方式的实现原理就能把 子页面的数据传递给 iframeC,接下来的问题就是怎么让iframeC把数据传递给主页面A ,因为,iframeC 和主页面是同域的,所以它们之间传递数据就变得简单多了,属于同域名下的通信问题了,如前面所讨论的,在这里的可以使用一个经常使用的属性 window.top (也可以使用window.parent.parent),它返回对载入浏览器得最顶层 window 对象的引用,这样我们就能直接条用父页面中方法啦。

这种页面代理的方式有个显著问题: 不可避免的要产生网络请求,我们原本希望它们能够直接在客户端通信,避免不必要的网络请求开销

postMessage 方案 : IE8以上

  • 定义 trustedOrigin
  • 发送信息: document.getElementById("widget").contentWindow.postMessage(data, trustedOrigin);
  • 订阅信息: window.addEventListener('message', msgHandler(data) {

})