零基础学习 Postmate库

1,432 阅读4分钟

正文

一、了解Postmate

一个强大的、简单的、基于 promise 的 postMessage iFrame 通信库。 Postmate 是一个建立在 postMessage 上的基于 promise 的 API。它允许父页面与子 iFrame 跨源对话,而且工作量很小。

简单理解:就是支持iframe之间的通信,

举个例子:一个页面使用iframe引入了另一个页面,两个页面要相互传值,就可以用到Postmate

image.png

AB是两个独立的页面,要在A中引入B就要使用iframe,而他们之间的通信就可以使用Postmate

现在应该清楚Postmate的具体作用了吧

二、Postmate的特性

  • 基于 promise 的 API,用于优雅和简单的通信。
  • 安全的双向父 <-> 子握手,并带有消息验证。
  • 子代暴露一个可检索的模型对象,父代可以访问。
  • 子代发出事件,父代可以监听。
  • 父代可以调用子代的函数。
  • 零依赖性。如果需要的话,可以为 Promise API 提供自己的 polyfill 或抽象。
  • 轻量级,大小约为1.6kb(缩小和压缩后)。

三、安装

//yarn
$ yarn add postmate # Install via Yarn
//npm
$ npm i postmate --save # Install via NPM

四、用法

这里使用一个简单的例子让初学者轻松上手使用

4.1 结构搭建

首先先创建两个文件夹,一个父页面(parent)一个子页面(child)

image.png

为什么要两个文件夹呢? 因为这是两个不同页面,也不一定在本地,两个是单独的模块。本地测试所以建在同一个文件夹下。

先看一下页面结构

image.png

先创建src来存放页面资源,一个html和一个js

然后使用命令npm init -yes初始化项目

然后使用命令npm install --save-dev webpack安装webpack (请先跳转下面webpack)

4.2 初始化页面

parent:使用parent标记父页面,并在下方使用iframe嵌入子页面

<style>
        .content {
            width: 200px;
            height: 100px;
            text-align: center;
            font-size: 28px;
            font-weight: 700;
            background-color: pink;
            color: #fff;
        }
    </style>
<body>
    <div class="content">
        parent
    </div>
    <div>
        <iframe src="./child.html" frameborder="0" id="iframe-container"></iframe>
    </div>
</body>
<script src="./parent.js"></script>

child:

<style>
        .content {
            width: 200px;
            height: 100px;
            text-align: center;
            font-size: 28px;
            font-weight: 700;
            background-color: skyblue;
            color: #fff;
        }
</style>
<body>
    <div class="content">
    child
    </div>
</body>
<script src="./child.js"></script>

嵌入之后的效果是这样的:

image.png

4.3 如何传值

当页面复杂之后就需要相互传值,但该如何传值呢,继续看

在一开始就已经安装了Postmate,所以在父页面和子页面都需要引入这个插件

4.3.1 子传父

parent:先看代码,下面解析

import PostMate from "Postmate";

const handshake = new PostMate({
    container: document.getElementById('iframe-container'),
    url: './child.html',
    name: 'my-iframe-name',
    classListArray: ["myClass"]
});
handshake.then(child => {
    child.on('someEvent', (data) => {
        console.log('someEvent', data);
    });
});
  • 首先先引入Postmate插件
  • 创建Postmate实例
    • 参数
    • container:获取iframe的dom元素,-- 这里是用id获取
    • url:子页面的路径 -- 这里是绝对路径
    • ... -- 后面暂时不重要
  • 使用.then的方式与子页面建立联系
  • child.on是监听事件 当子页面发布这个事件的时候就会触发回调函数,不清楚的可以去看看发布订阅模式
    child:先看代码,下面解析
import PostMate from "Postmate";
​
const handshake = new PostMate.Model({
    height: () => document.height || document.body.offsetHeight
});
​
handshake.then(parent => {
    parent.emit('someEvent', '这是子页面!!')
});
  • 同上先引入
  • 创建子页面实例 -- 先这么理解
  • 然后与父页面建立联系,
  • 建立完联系发布一个事件parent.emit('someEvent', '这是子页面!!')
  • someEvent是事件名,这边发布这个事件名,在父页面就会触发相应事件名的回调
  • 后面的是传过去的数据

image.png

这就实现了子页面传数据到父页面

4.3.2 父传子

parent:

handshake.then(child => {
    child.on('someEvent', (data) => {
        console.log('someEvent', data);
        const iframe = document.querySelector('#iframe-container')
        iframe.contentWindow.postMessage({
            text: '收到!这里是父页面over~'
        }, '*');
    });
});

当你收到子页面发布的信息后就会调用这个方法,那我们就返回一个信息回去,

先获取iframe的dom元素,然后就使用iframe.contentWindow.postMessage的方式把数据传回去

child

window.addEventListener('message', function(e) {
    console.log(e);
    console.log(e.data);
    console.log(e.data.text);
})

子页面就监听message事件就可以获取父页面传回来的数据啦

image.png 当子页面发布(emit)这个事件的时候把someEvent 这是子页面!!发送给父页面,父页面收到之后并传回一个数据给子页面下面

讲到这里Postmate的最基础的使用就已经讲完了,还有更加进阶的使用,还是要根据具体的项目来改变逻辑,但是方法就是这么简单,可以参考文档Postmate文档

ps:

总结

这里需要讲一下为什么要使用到webpack,如果你有在跟着写的话应该已经发现问题了,一定会报错,为什么呢? 因为原生js使用import导入就使用了esmodule的方式,所以会出现问题,这里最合理的方式就是将js打包后引入,就可以完美解决这个问题。

webpack

如果不会使用webpack打包的同学,可以参考文档webpack文档,我也写了一篇webpack的基础使用也可以看看

本章完