zoukankan      html  css  js  c++  java
  • Js的iframe相关问题,如何判断当前是否在iframe中,iframe和它的父窗口如何通信

     

    一、前言:

      在web中,为了丰富我们的内容,往往需要引用其它HTML文件,这时候就需要用到 iframe 标签,本文就主要记录一下使用iframe所需要注意的问题

     

      iframe 所使用的环境(笔者所遇到的)

      1. web代码兼容 PC端 和 移动端,这时候就想在移动端时把页面限制在固定的宽高范围中,于是就使用 iframe 把 相关页面限制在其中

      2. web引用别人的 HTML 内容,就使用iframe 来实现

     

    二、遇到的问题:

    1. 如何判断当前是否在iframe中

    // 1
    if (self.frameElement && self.frameElement.tagName == "IFRAME") {
      alert('在iframe中');
    }
    
    // 2
    if (window.frames.length != parent.frames.length) {
      alert('在iframe中');
    }
    
    // 3
    if (self != top) { 
      alert('在iframe中');
    }

     说明:

    • 三种方式都是根据当前的窗口层级进行判断,
    • 以上是针对有 <frameset> 或者 <iframe> 的页面,
    • self.frameElement 可以获取到当前的 iframe 节点(如果有的话),否则为null

     解释:window、top、parent、self 之间的联系和区别

    • window : 当前窗口
    • top: 顶层窗口,针对有很多层的iframe
    • parent: 父级窗口,即当前窗口的上一层窗口
    • self: 当前窗口,和window、window.self  等价

     

    2. iframe 和 它的父窗口如何通信

      注意有两种情况:

    • iframe 和 父窗口 同源(即不会跨域,相同域名下),可以直接使用 节点 或 window 调用
      • iframe 获取父窗口节点:parent.window.document.getElementById("parentNode")
      • iframe 调用父窗口方法:parent.parentFunc();
      • 父窗口获取 iframe节点:iframeObj.contentWindow.document.getElementById("childNode")   
        • this.myFrame表示 iframe对象
        • var obj=document.getElementsByTagName("iframe")[0].contentWindow;  
          var ifmObj=obj.document.getElementById("childNode");  
      • 父窗口调用 iframe方法:iframeObj.contentWindow.parentFunc()
        • var obj=document.getElementsByTagName("iframe")[0].contentWindow;  
          obj.parentFunc();

           

    • iframe 和 父窗口 跨域(一般是调用别人的HTML )
      • 必须使用安全的 postMessage方式来进行通信
      • // 向父窗口传值
        window.parent.postMessage({code: 1, msg: '向父窗口传值'},*);
        
        // 向iframe传值
        document.getElementsByTagName("iframe")[0].contentWindow.postMessage({code: 2, msg: '向iframe传值'},*);
        
        // 接收传值
        window.addEventList('message',  (e) => {
            try{
                if (e.data type e.data ==='string' ) {
                console.log(e.data);
                }
            } catch (err) {
                console.log(err)
            }
        });
        • event.source:发送消息的窗口,可以通过区分网址来接收消息
        • event.origin: 消息发向的网址,同上
        • event.data: 消息内容

    说明:

    otherWindow.postMessage(message,targetOrigin,[transfer]);
    • otherWindow: 其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames;
    • message: 将要发送到其他window的数据,这个数据会自动被序列化,数据格式也不受限制,String字符串,对象(包括JSON)都可以;
    • targetOrigin: 通过窗口的origin属性来指定哪些窗口能接收到消息事件,这个值可以是"*"(表示无限制),或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或者端口这三个的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是*。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
    • transfer(可选): 是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

     

     三、最后

      具体请看MDN: window.postMessage

     

  • 相关阅读:
    (转)基于REST架构的Web Service设计
    WPF 简易的喷泉效果
    C# 取Visio模型信息的简易方法
    WPF TextBox按字节长度限制输入
    NPOI导出WPF DataGrid控件显示数据
    WPF--TextBlock的ToolTip附加属性
    【转】WPF 从FlowDocument中找到Hyperlink
    WPF 初学VisifireChart
    WPF 简易进度条效果
    WPF 简易的跑马灯效果
  • 原文地址:https://www.cnblogs.com/nangezi/p/11703143.html
Copyright © 2011-2022 走看看