Vue中使用iframe踩坑问题记录 iframe+postMessage

目录
  • 使用iframe踩坑记录 iframe+postMessage
    • 1.iframe的初始高度问题
    • 2.postMessage的实现
  • iframe使用postMessage传值addEventListener未接收到却收到webpackwarning问题
    • bug如下
    • 问题解决

使用iframe踩坑记录 iframe+postMessage

需求:最近在写一个博客的功能模块,技术栈是单独选择的vuepress,完成后想要融合到一个vue工程里,考虑到后期维护的问题,就通过iframe将vuepress打包后的工程页面引入到vue工程的一个页面中,这样iframe的父子级页面之间也要进行信息的传递,比如说传递iframe的子页面的滚动高度给父页面,然后撑开页面高度。

1.iframe的初始高度问题

vue工程的一个组件,也就是iframe的父页面,引入html;这里出现第一个坑,就是iframe的初始高度一定要设置,具体高度值可以预估一下iframe子页面的高度,否则加载的时候就会出现闪屏的现象,体验不好;如果iframe的子页面高度是变化的,也就是说iframe要实现高度的自适应,接下往下看。。。

<div id="iframeBox">
   <iframe id="iframeCon" src="./blog/index.html" width="100%" height="800px"></iframe>
</div>

2.postMessage的实现

上面说到iframe要实现高度自适应,就需要借助postMessage来实现了,自己之前没用过这个,找了很多资料说的感觉都不是很好,就自己直接写了。

在iframe的子页面中:函数写在methods中,怎么去触发getScrollHeight()这个函数看你具体的情况。注意一下,postMessage的源路径,想要将信息传递到哪里。

为什么要写定时器?如果页面内容超多,高度值很大,像我的就到了2W多px,需要等到页面加载完成后才能获取滚动高度,延时短了什么的是不能够获取准确的高度值,会造成iframe的父级页面出现双滚动条,影响体验。

最后,在页面销毁之前记得要清除定时器。个人感觉如果只有一个定时器,或者这个setTimeout不是为了实现setInterval的效果,也没有其他的掺杂,是不用清除的。

beforeDestroy() {
   clearTimeout(this.timer);
},
 
methods: {
    getScrollHeight() {
       this.timer = setTimeout(() => {
         et height = document.body.scrollHeight;
          window.parent.postMessage(height, "/");
       }, 100);
    }
}

在iframe的父级页面中如何接收信息呢? 这里采用事件的监听,每次有子页面传递信息的出现,我们就获取到传递信息中的高度值,然后设置给当前页面。同样的记得移除监听。

created () {
  window.addEventListener('message', this.setHeightUpdate, false)
},
destroyed () {
  window.removeEventListener('message', this.setHeightUpdate, false)
},
methods: {
  setHeightUpdate () {
    let iframe = document.getElementById('iframeCon')
    iframe.height = event.data + 100 // 这里的event就是子页面传过来的信息,可以打印到控制台看
    window.scrollTo(0, 0) // 为了回到顶部
  }
}

我遇到的就是这些了,虽然简单,但是知识呀。。。

iframe使用postMessage传值addEventListener未接收到却收到webpackwarning问题

项目中使用到iframe,iframe跨域通信需要使用postMessage发送消息,addEventListener接收消息。

原先是获取当前窗口的数据发送过去。

const _iframe = document.getElementById('iframeViewer').contentWindow
          let _obj = res.data.data
          _obj.type = 'view'
          _obj.currentProcessInstanceId = row.id
          let Base64 = require('js-base64').Base64
          _obj.processXml = Base64.decode(res.data.data.processXml)
          _iframe.postMessage(JSON.stringify(_obj), '*')

后来项目需求更新,需要将本来的窗口多加几个菜单,可以进行页面切换。加了新的菜单之后就出现了问题,postMessage发送出了消息,控制台打印出来addEventListener接收到的消息变成了webpack相关。

bug如下

问了大哥,发现问题可能是因为webpack自身会发送postMessage,需要区分接收到的是webpack发的还是自己发的。另外iframe是动态生成的,未加载好就发送postMessage,webpack会帮助发送。(大概是因为这个,具体的不清楚)

问题解决

所以一个是需要在iframe加载好之后发送postMessage,另一个是区分接收到的是webpack发的还是自己发的。

定义 const _iframe = document.getElementById('iframeViewer').contentWindow 获取目标窗口的窗口对象

定义iframeViewer = document.getElementById('iframeViewer') 获取iframe元素对象

然后使用onload事件,window.οnlοad=function(){SomeJavaScriptCode};(onload事件会在页面或图像加载完成后立即发生)

const _iframe = document.getElementById('iframeViewer').contentWindow
const iframeViewer = document.getElementById('iframeViewer')
let _obj = res.data.data
_obj.type = 'view'
_obj.currentProcessInstanceId = this.currentProcessInstanceId
let Base64 = require('js-base64').Base64 _obj.processXml = Base64.decode(res.data.data.processXml)
iframeViewer.onload = () => {
  console.log('iframeViewer已加载')
  _iframe.postMessage(JSON.stringify(_obj), '*')
}

这样就确保了在iframe加载后再发送postMessage。

在addEventListener接收时,因为postMessage发送的时候传了一个type,所以可以通过type来判断发过来的是哪个event。

window.addEventListener("message", function(event) {
   _this.parentData = event.data;
   if (JSON.parse(_this.parentData).type === "view") {
     _this.frontTask = JSON.parse(_this.parentData).frontTask;
     _this.currentTask = JSON.parse(_this.parentData).currentTask;
     _this.backTask = JSON.parse(_this.parentData).backTask;
     _this.historyTask = JSON.parse(_this.parentData).historyTask;
     _this.processInstanceId = JSON.parse(_this.parentData).currentProcessInstanceId;
     _this.createNewDiagram(JSON.parse(_this.parentData).processXml);
   }
})

写好之后记得刷新页面,不然就会像我一样明明已经改好了但还是看不到数据。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • vue中iframe使用以及结合postMessage实现跨域通信

    目录 使用场景 需求 iframe使用 基本使用 常用属性 iframe高度自适应 获取iframe的内容 同域下获取父级/子级内容 iframe跨域 postMessage通信 在vue中使用 使用场景 需求 在一个H5项目的页面中以url的方式嵌入另一个项目的页面.(不得不使用iframe) 而为了兼容移动端api(封装的一个移动端api,iframe内嵌页面不生效),需要实现父子页面的通信 (使用postMessage). iframe使用 基本使用 直接在页面嵌套iframe标签指定sr

  • vue中如何通过iframe方式加载本地的vue页面

    目录 通过iframe方式加载本地的vue页面 iframe方式加载本地的vue页面的第一种方法 iframe方式加载本地的vue页面的第二种方法 iframe方式加载本地的vue页面的第三种方法 关于iframe在vue中应用问题 iframe的宽高无法根据内容撑开 通过iframe方式加载本地的vue页面 也是在实际的项目中碰到一个奇葩的需求,用vue,居然还要用到iframe,真是脑壳大,试了好多次最后才找到了正确的方法. 总共有三种方法吧 iframe方式加载本地的vue页面的第一种方法

  • vue中使用iframe嵌入网页,页面可自适应问题

    目录 使用iframe嵌入网页,页面可自适应 vue iframe高度自适应 实用 实时刷新iframe高度变化 iframe高度有变的时候通知父级 iframe高度有变的时候直接修改iframe高度 使用iframe嵌入网页,页面可自适应 在项目中遇到要嵌入第三方网页的需求,因为没有同第三方页面交互的需求,只需展示即可,所以最终决定使用 iframe 将第三方的网页嵌入到系统中,并且做到自适应效果. 考虑到以后可能会增加嵌入页面的数量,故而封装成组件,供以后复用: 上图为系统整体结构图,需要在

  • vue与iframe之间的交互方式(一看就会)

    目录 vue与iframe之间的交互 子页面向父页面传值 父页面向子页面传值 vue与html之间iframe交互 1.父级调用子级ifram中的方法 2.子级iframe(html 或者vue)调用父级html中的方法 3.vue中调用子级iframe html 中的方法 4.在iframe中调用vue中的方法 vue与iframe之间的交互 首先介绍一下使用背景,前端采用html单页面引用vue的方式(逼不得已这么做,否则直接用vue不香嘛),废话不多说 页面大致是这样,现在需要做的是在if

  • vue中iframe的使用及说明

    目录 关于iframe的使用 获取iframe里面的内容 CDM跨域 使用iframe的总结 代码展示 关于iframe的使用 iframe在同域时能自由操作iframe和父框架的内容(DOM),在跨域时可以实现页面跳转. <iframe id="iframe" :src="iframeSrc" style="height: calc(100% - 50px)" width="100%" frameborder=&quo

  • Vue中使用iframe踩坑问题记录 iframe+postMessage

    目录 使用iframe踩坑记录 iframe+postMessage 1.iframe的初始高度问题 2.postMessage的实现 iframe使用postMessage传值addEventListener未接收到却收到webpackwarning问题 bug如下 问题解决 使用iframe踩坑记录 iframe+postMessage 需求:最近在写一个博客的功能模块,技术栈是单独选择的vuepress,完成后想要融合到一个vue工程里,考虑到后期维护的问题,就通过iframe将vuepr

  • 详解vue中使用protobuf踩坑记

    官方解释为: Protocol buffers are a flexible, efficient, automated mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source c

  • 详解Vue微信公众号开发踩坑全记录

    本文介绍了Vue微信公众号开发踩坑全记录,分享给大家,也给自己留个笔记. 需求 微信授权登录(基于公众号的登录方案) 接入JS-SDK实现图片上传,分享等功能 现状及难点 采用的Vue框架,前后端分离模式(vue工程仅作为客户端),用户通过域名访问的是客户端,但是微信授权中涉及签名和token校验依赖服务端 JS-SDK需要向服务端获取签名,且获取签名中需要的参数包括所在页面的url,但由于单页应用的路由特殊,其中涉及到IOS和android微信客户端浏览器内核的差异性导致的兼容问题 解决方案

  • 关于python scrapy中添加cookie踩坑记录

    问题发现: 前段时间项目中,为了防止被封号(提供的可用账号太少),对于能不登录就可以抓取的内容采用不带cookie的策略,只有必要的内容才带上cookie去访问. 本来想着很简单:在每个抛出来的Request的meta中带上一个标志位,通过在CookieMiddleware中查看这个标志位,决定是否是给这个Request是否装上Cookie. 实现的代码大致如下: class CookieMiddleware(object): """ 每次请求都随机从账号池中选择一个账号去访

  • Java中Objects.equals踩坑记录

    目录 前言 1. 案发现场 2. 判断相等的方法 2.1 使用==号 2.2 使用equals方法 3. 空指针异常 4. Objects.equals的作用 5. Objects.equals的坑 总结 前言 最近review别人代码的时候,发现有个同事,在某个业务场景下,使用Objects.equals方法判断两个值相等时,返回了跟预期不一致的结果,引起了我的兴趣. 原本以为判断结果会返回true的,但实际上返回了false. 记得很早之前,我使用Objects.equals方法也踩过类似的

  • 使用Pyinstaller的最新踩坑实战记录

    前言 将py编译成可执行文件需要使用PyInstaller,之前给大家介绍了关于利用PyInstaller将python程序.py转为.exe的方法,在开始本文之前推荐大家可以先看下这篇文章,本文主要给大家介绍了Pyinstaller最新踩坑实战记录,现在网上关于pyinstaller的问题充斥着各种copy过来copy过去的答案,这大概就是各种无脑博客爬虫站最让人讨厌的地方. 而且这方面的问题,stackoverflow也是回答的千奇百怪. 强烈推荐官方文档 http://pythonhost

  • 微信小程序自定义tabBar的踩坑实践记录

    微信官方文档对自定义 tabBar 的阐述较为潦草,在开发自定义 tabBar 过程中我踩了很多坑,因此在此处做个总结. 我使用 Vant Weapp作为 UI 组件库,下面以此组件库为例. 定义 tabBar 创建自定义 tabBar 文件 创建一个与 /pages 的同级目录,命名为  /custom-tab-bar,注意目录层级与目录命名问题,不可用其他名称命名. 在 /custom-tab-bar 下创建四个文件: index.js index.json index.wxml index

  • springboot中Excel文件下载踩坑大全

    目录 项目场景:Spring boot文件下载 问题一:下载的文件名称出现中文乱码的问题 问题二:在swagger中测试下载接口,点击下载的文件,发现文件名是乱码的问题 问题四:开发环境下载成功,打成jar包发布到服务器上部署就出现下载失败问题 完整代码 项目场景:Spring boot文件下载 调用接口下载spring boot工程的resources目录下的excel模板文件,非常常见的一个文件下载功能,但是却容易遇到很多坑,下面总结记录下. 问题一:下载的文件名称出现中文乱码的问题 解决方

  • SpringBoot 集成 Jasypt 对数据库加密以及踩坑的记录分享

    前言 密码安全是非常重要的,因此我们在代码中往往需要对密码进行加密,以此保证密码的安全 加依赖 <!-- jasypt --> <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.3</version> </depe

  • Go使用proto3的踩坑实战记录

    开发环境:windows10,golang1.18.2,goland2022.2 最近在写项目时,一些数据类的结构以protobuf文件给定.因此,需要将这些protobuf文件转换为golang代码. 首先,在下载解析protobuf的包的时候就碰到了第一个问题... go get -u github.com/golang/protobuf/protoc-gen-go 在我用上述命令后,终端提示该包已弃用 go: module github.com/golang/protobuf is dep

随机推荐