关于iframe的一些问题

329 阅读1分钟

这里记录日常工作中遇到的一些问题,便于日后查看,每解决一个问题,都是一次进步。

1. 获取iframe 中的元素

一开始的做法是通过普通的方法来实现,结果打印的一直都是 null,就查询原因,了解到了 iframe中元素不能用普通的方式获取。

错误的写法

<iframe id="demo_iframe" :src="src">
    <div id="area-code">
      ...这是内容
    </div>
</iframe>

<script>
    const el = document.querySelector('#area_code')
    console.log('get dom', el) // null
</script>

正确做法: 需要先获取 iframe元素, 通过 iframe 的 contenwidth 对象来获取 iframe中的dom元素。

<iframe id="demo_iframe" :src="src">
    <div id="area-code">
      ...这是内容
    </div>
</iframe>

<script>
    const iframe = document.getElementById('demo_iframe').contentWindow;
    const el = iframe.document.querySelector('#area-code')
    console.log('get dom', el) // 此时有值 <div id="area_code">...</div>

</script>

2. iframe中的通信问题

组件 dome.vue 中 存在 iframe; 组件 areaCode.vue 是 iframe中的结构; 需要:自己模拟的一个下拉选择框的效果,现在想要实现,点击下拉框之外的区域,下拉区域收起。

错误的做法 在 areaCode.vue 中监听 mouseDown 事件,关闭下拉框,发现当点击 areaCode.vue 组件之外的区域, 就监听不到 mouseDown 事件了。

<script>
export default {
// areaCode.vue
mounted() {
    window.addEventListener('mousedown', this.clickDom)
},
destroyed() {
    window.removeEventListener('mousedown', this.clickDom)
},
methods: {
    clickDom() {
      console.log('click out')
      this.visible = false
    }
},
}
</script>

然后以为是因为区域的问题,将监听的方法放在了 dome.vue 中,发现还是不行。 然后又 通过 eventBus,发现也不行。

向大佬请求帮助, 可以通过 postMessage 来进行 iframe的通信。 同时在维护的另一个项目中已经有使用了,参考着实现了需求。

最终的做法

// demo.vue 中
export default {
  mounted() {
    window.addEventListener('mousedown', this.clickDom)
  },
  destroyed() {
    window.removeEventListener('mousedown', this.clickDom)
  },
  methods: {
    clickDom() {
      const iframe = document.querySelector('#demo_iframe')
      // 给 iframe页面发送消息
      iframe.contentWindow.postMessage('click-dom');
    }
  },
};


// areaCode.vue 中, 监听 message 事件, 接收参数
export default {
  mounted() {
    window.addEventListener('message', this.clickDom)
  },
  methods: {
    clickDom(e) {
      console.log('=====', e)
      if(e.data === 'click-dom' && this.visible) {
        this.visible = false
      }
    }
  },
};

关于 iframe 的 通信,还可以反过来通信, message 事件的参数也有好几个值,更多具体细节可查看MDN

===== 待续 =====