使用postMessage让 iframe自适应高度的方法示例


Posted in HTML / CSS onOctober 08, 2019

前言

有时候,我们会使用 iframe标签,将前端分离项目无感的嵌入 如以Freemark为主体较老的项目中。

我们知道,当iframe内部内容比父页面所指定的宽高大的时候,会出现滚动框。

所以,让iframe的宽高能根据自身内容自动改变,就成了一个必须要解决的问题。

使用HTML5中新定义的window.postMessage 可以实现跨window通信。

demo效果

演示地址: www.mixvjiezi.xyz/demo/iframe

使用postMessage让 iframe自适应高度的方法示例

我们要的效果如上图所示。

使用postMessage让 iframe自适应高度的方法示例

黄色区域 是通过 iframe标签引入 的body.html部分。

index.html :

<!DOCTYPE html>
<html lang="en">
    <script src="https://code.jquery.com/jquery-3.1.1.min.js">
    var $ = window.jQuery;
    </script>
  <style>
    .header{
      width: 100%;
      min-width: 1260px;
      height: 70px;
      background-color: red;
      box-shadow: 0 0 5px black;
      border-radius: 10px;
    }
    .center{
      width: 1560px;
      height: 1470px;
      margin: 20px auto;
    }
    .iframe{
      width: 250px;
      height: 250px;
      margin: 20px 0 0 40px;
    }
    .left-nav{
      width: 200px;
      height: 1470px;
      background-color: blue;
      float: left;
      margin-top: 10px;
      box-shadow: 0 0 5px black;
      border-radius: 10px;
    }

  </style>
  <head>
    <meta charset="utf-8" />
    <title>css study</title>
  </head>
<body>
  <div class="header">
  </div>
  <div class="center">
    <div class="left-nav"></div>
    <iframe class="iframe"   id="shopIframeId" src="./body.html" width="100%" height="100%" scrolling="no"  frameborder="0"></iframe>
  </div>
  <script type="text/JavaScript">
    window.addEventListener('message', e => {
      if (e.data.type === 1) {
        $('#shopIframeId').width(e.data.data.width + 50)
        $('#shopIframeId').height(e.data.data.height + 50)
      }
    });
  </script>
</body>
</html>

body.html:

<!DOCTYPE html>
 <html lang="en">
    <script src="https://code.jquery.com/jquery-3.1.1.min.js">
    var $ = window.jQuery;
    </script>
   <style>
   .box{
     width: 200px;
     height: 200px;
     box-shadow: 0 0 5px black;
     border-radius: 10px;
     background-color: yellow;
   }
   </style>
   <head>
     <meta charset="utf-8" />
     <title>css study</title>
   </head>
 <body>
   <div class="box">
   </div>
 </body>
 <script type="text/JavaScript">
 var data = {
   el: $('.box'),
   height: $('.box').outerHeight(),
   width: $('.box').outerWidth(),
   parent: window.parent
 }

 $('.box').on('click', function () {
   // 更新数据
   if (data.width < 1250) {
    data.width += 50
   }
   data.height += 50
   // 更新视图
   data.el.width(data.width)
   data.el.height(data.height)
   // 通知父window 自身高度变更
   data.parent.postMessage({
     type: 1,
     data: {
       width: data.width,
       height: data.height
     }
   }, '*')
 })
</script>
 </html>

正题

我们知道,把大象装进去需要四步。

使用postMessage API发送消息比装大象要少一步,只需要三步就行。

分别是:

1、找到发送对象

2、发送消息

3、设置消息处理

接下来,我们用上面的例子,一一来说。

1、找到发送目标对象

使用window.parent 就可以获取引入自身文档的父window对象。

var data = {
   el: $('.box'),
   height: $('.box').outerHeight(),
   width: $('.box').outerWidth(),
   parent: window.parent
 }

我在这一步中还初始化了鉴定dom,监听dom的height和width,核心是用window.parent获取 index.html文件的window对象 

2、在iframe中发送消息

$('.box').on('click', function () {   
// 更新数据
   if (data.width < 1250) {
    data.width += 50
   }
   data.height += 50
   // 更新视图
   data.el.width(data.width)
   data.el.height(data.height)
   // 通知父window 自身高度变更
   data.parent.postMessage({
     type: 1,
     data: {
       width: data.width,
       height: data.height
     }
   }, '*')
 })

给目标div挂在一个单机事件,每次点击时,都会增加50xp的宽高(如果宽度大于等于1250则宽度不增加)。

然后使用el.postMessage(message,  targetOrigin)方法发送消息。

el:

el是其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。

message:

message参数是要传输的数据消息体。

targetOrigin:

targetOrigin参数通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。

3、设置消息处理

window.addEventListener('message', e => {
      if (e.data.type === 1) {
        $('#shopIframeId').width(e.data.data.width + 50)
        $('#shopIframeId').height(e.data.data.height + 50)
      }
    });

我再index.html 添加了message监听,如果有消息被发送过来,则会触发处理函数,更新iframe标签的宽高。

处理函数传入一个参数e,e是一个消息对象,包含如下重要属性:

data:

从其他 window 中传递过来的对象。

origin:

调用 postMessage 时消息发送方窗口的origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成。例如 “ https://example.org (隐含端口 443 )”、“ http://example.net (隐含端口 80 )”、“ http://example.com:8080 ”。请注意,这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置。

source:

对发送消息的窗口对象的引用; 您可以使用此来在具有不同origin的两个窗口之间建立双向通信。

小结

在消息传输中,我使用type属性,在iframe中传输不同的message.type和message.data,父window中就可以根据不同的message.type做出相应的处理。

譬如message.type如果等于2,则可以设置弹出一个带弹层的alert,内容从message.data获取

这样就可以解决,在iframe中弹层不能覆盖到外部的问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
详解纯CSS3制作的20种loading动效
Jul 05 HTML / CSS
真正了解CSS3背景下的@font face规则
May 04 HTML / CSS
今天学到的CSS最新技术(与图片背景相关)
Dec 24 HTML / CSS
纯CSS3编写的的精美动画进度条(无flash/无图像/无脚本/附源码)
Jan 07 HTML / CSS
HTML5边玩边学(2)基础绘图实现方法
Sep 21 HTML / CSS
HTML5的表单(绝对特别强大的功能)使用示例
Jun 20 HTML / CSS
html5实现多文件的上传示例代码
Feb 13 HTML / CSS
canvas离屏技术与放大镜实现代码示例
Aug 31 HTML / CSS
如何让pre和textarea等HTML元素去掉滚动条自动换行自适应文本内容高度
Aug 01 HTML / CSS
萌新的HTML5 入门指南
Nov 06 HTML / CSS
HTML5适合的情人节礼物有纪念日期功能
Jan 25 HTML / CSS
html+css合并表格边框的示例代码
Mar 31 HTML / CSS
基于 HTML5 WebGL 实现的医疗物流系统
Oct 08 #HTML / CSS
html2canvas生成清晰的图片实现打印的示例代码
Sep 30 #HTML / CSS
html5视频媒体标签video的使用方法及完整参数说明详解
Sep 27 #HTML / CSS
Html5实现首页动态视频背景的示例代码
Sep 25 #HTML / CSS
HTML5自定义元素播放焦点图动画的实现
Sep 25 #HTML / CSS
使用Html5中的cavas画一面国旗
Sep 25 #HTML / CSS
关于canvas绘制模糊问题的解决方法
Sep 24 #HTML / CSS
You might like
关于时间计算的结总
2006/12/06 PHP
比较简单实用的PHP无限分类源码分享(思路不错)
2011/10/13 PHP
php+jQuery.uploadify实现文件上传教程
2014/12/26 PHP
详解PHP实现执行定时任务
2015/12/21 PHP
[原创]php token使用与验证示例【测试可用】
2017/08/30 PHP
PHP fprintf()函数用法讲解
2019/02/16 PHP
与Math.pow 相反的函数使用介绍
2014/08/04 Javascript
jquery文档操作wrap()方法实例简述
2015/01/10 Javascript
mvc中form表单提交的三种方式(推荐)
2016/08/10 Javascript
JS实现JSON.stringify的实例代码讲解
2017/02/07 Javascript
Vue中引入样式文件的方法
2017/08/18 Javascript
JavaScript查看代码运行效率console.time()与console.timeEnd()用法
2019/01/18 Javascript
js实现表格单列按字母排序
2020/08/12 Javascript
python使用rabbitmq实现网络爬虫示例
2014/02/20 Python
python调用机器喇叭发出蜂鸣声(Beep)的方法
2015/03/23 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
2017/04/05 Python
Python实现好友全头像的拼接实例(推荐)
2017/06/24 Python
pandas DataFrame 交集并集补集的实现
2019/06/24 Python
python模拟鼠标点击和键盘输入的操作
2019/08/04 Python
Flask项目中实现短信验证码和邮箱验证码功能
2019/12/05 Python
python 实现在无序数组中找到中位数方法
2020/03/03 Python
python使用paramiko实现ssh的功能详解
2020/03/06 Python
基于python实现可视化生成二维码工具
2020/07/08 Python
Python 添加文件注释和函数注释操作
2020/08/09 Python
Wiggle中国:英国骑行、跑步、游泳 & 铁三运动装备专卖网店
2016/08/02 全球购物
百丽国际旗下购物网站:优购
2017/02/28 全球购物
进程的查看和调度分别使用什么命令
2013/12/14 面试题
信息专业大学生自我评价分享
2014/01/17 职场文书
大学社团活动总结
2014/04/26 职场文书
实习生矿工检讨书
2014/10/13 职场文书
爱岗敬业事迹材料
2014/12/24 职场文书
骨干教师个人总结
2015/02/11 职场文书
唐山大地震观后感
2015/06/05 职场文书
围城读书笔记
2015/06/26 职场文书
小学生读书笔记
2015/07/01 职场文书
关于python中readlines函数的参数hint的相关知识总结
2021/06/24 Python