iframe 子父传值封装 postmessage封装1.0

iframe 子父传值封装 postmessage封装1.0

近期公司项目需求
1.父页面中同时载入多个iframe
2.父页面主动调用子页面方法
3.父页面主动获取子页面值
4子页面主动获取父页面的值
其中主动是关键

postmessage.js

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
      (global = global || self, global.postmessage = factory())
}(this, function () {
  const commonMethod = 'haha'
  // 管道集合
  const queueMap = new Map()
  // 全局监听
  window.addEventListener('message', function (event) {
    const sourceUrl = event.data.sourceUrl
    console.log('[addEventListener][event]', event)
    console.log('我是' + location.href, '收到来自', sourceUrl + '的消息')
    console.log('[当前管道集合]===', queueMap)
    // 执行方法
    queueMap.get(event.data.method + location.href).fn(event.data.data)
  })

  /**
   * 给子页面传值
   * @param {*} iframe
   * @param {*} methodName
   * @param {*} data
   */
  function postToIframe (iframe, methodName, data, fn) {
    // 目标iframe地址 通常指子页面地址
    const iframeUrl = iframe.getAttribute('src') || iframe
    console.log('我是:' + location.href, '我要给' + iframeUrl + '发消息', '消息标识:', methodName, '消息内容:', data)
    iframe.contentWindow.postMessage({
      method: methodName || commonMethod,
      data: data,
      sourceUrl: window.location.href
    }, '*')
    fn && listen(methodName, fn)
  }

  /**
   * 给父级页面传值
   * @param {*} methodName
   * @param {*} data
   */
  function postToParent (methodName, data, fn) {
    window.parent.postMessage({
      method: methodName || commonMethod,
      data: data,
      sourceUrl: window.location.href
    }, '*')
    fn && listen(methodName, fn)
  }

  function listen (methodName, fn) {
    console.log('我是' + location.href, '注册' + methodName + '管道')
    queueMap.set(methodName + location.href, { fn })
    console.log('【当前订阅队列】', queueMap)
  }

  function trigger (iframe, methodName, data, fn) {
    if (iframe) {
      postToIframe(iframe, methodName, data, fn)
    } else {
      postToParent(methodName, data, fn)
    }
  }

  return {
    listen,
    trigger
  }
}))

parnet.html

<!DOCTYPE html>
<html lang="en">

<head>
  <title>parent</title>
</head>

<body>
<div id="app"></div>
<iframe id="childFrame" src="http://192.168.43.181:8080/child.html"></iframe>
<button onclick="checkForm1()">checkForm1</button>
<button onclick="getForm1()">getForm1</button>
<iframe id="childFrame2" src="http://192.168.43.181:8080/child2.html"></iframe>
<button onclick="checkForm2()">checkForm2</button>
<button onclick="getForm2()">getForm2</button>
<script src="./post-message.js"></script>
<script>
  const personInfo = {
    name: '666',
    sex: '女'
  }

  postmessage.listen('getPersonInfo', function (data) {
    const iframeDom = document.getElementById('childFrame')
    postmessage.trigger(iframeDom, 'getPersonInfo', personInfo)
  })

  postmessage.listen('handleAlert', function (data) {
    alert(data)
  })

  function checkForm1 () {
    console.log('checkForm=====================')
    const iframeDom = document.getElementById('childFrame')
    postmessage.trigger(iframeDom, 'checkForm', { test: '请' + iframeDom.src + '校验表单:' }, function (result) {
      console.log(iframeDom.src + '的表单校验结果:', result)
    })
  }

  function getForm1 () {
    console.log('getForm=======================')
    const iframeDom = document.getElementById('childFrame')
    postmessage.trigger(iframeDom, 'getForm', { test: '请给我表单' }, function (result) {
      console.log(iframeDom.src + '的表单结果:', result)
    })
  }

  function checkForm2 () {
    console.log('checkForm2=====================')
    const iframeDom = document.getElementById('childFrame2')
    postmessage.trigger(iframeDom, 'checkForm', { test: '请' + iframeDom.src + '校验表单:' }, function (result) {
      console.log(iframeDom.src + '的表单校验结果:', result)
    })
  }

  function getForm2 () {
    console.log('getForm2=======================')
    const iframeDom = document.getElementById('childFrame2')
    postmessage.trigger(iframeDom, 'getForm', { test: '请给我表单' }, function (result) {
      console.log(iframeDom.src + '的表单结果:', result)
    })
  }
</script>
</body>
</html>

child.html

<!DOCTYPE html>
<html lang="en">

<head>
  <title>inner</title>
</head>
<body>
<div id="app">
  <button onclick="getPersonInfo()">getPersonInfo</button>
  <button onclick="handleAlert()">handleAlert</button>
</div>
<script src="./post-message.js"></script>
<script>
  const form = {
    result: 111,
    aaa: 222,
    bbb: 333
  }
  const getFormKey = 'getForm'
  postmessage.listen(getFormKey, function (data) {
    console.log('[child]getForm方法', '当前收件人' + location.href, '收到了消息', data)
    postmessage.trigger(null, getFormKey, form)
  })
  const checkFormKey = 'checkForm'
  postmessage.listen(checkFormKey, function (data) {
    console.log('[child]checkForm方法', '当前收件人' + location.href, '收到了消息', data)
    const checkResult = true
    postmessage.trigger(null, checkFormKey, checkResult)
  })

  function getPersonInfo () {
    console.log('child click getPersonInfo========>')
    postmessage.trigger(null, 'getPersonInfo', 'test', function (result) {
      console.log('我是' + location.href, '我拿到了从父级得到的数据Person', result)
    })
  }

  function handleAlert () {
    console.log('child click handleAlert========>')
    postmessage.trigger(null, 'handleAlert', '我是child 传过去的值')
  }
</script>
</body>
</html>

child2.html

<!DOCTYPE html>
<html lang="en">
<head>
  <title>inner</title>
</head>
<body>
<div id="app">
  <button onclick="clickHandler()">post</button>
</div>
<script src="./post-message.js"></script>
<script>
  const form = {
    result: 'aaaaaaaaaaaaaaaaaa',
    aaa: 'bbbbbbbbbbbbbbbbbbbbb',
    bbb: '333'
  }
  postmessage.listen('getForm', function (data) {
    console.log('getForm2收件人:', location.href, '收到了消息', data)
    // setTimeout(function () {
    postmessage.trigger(null, 'getForm', form)
    // }, 2000)
  }, location.href)
  postmessage.listen('checkForm', function (data) {
    console.log('checkForm2收件人:', location.href, '收到了消息', data)
    const checkResult = false
    // setTimeout(function () {
    postmessage.trigger(null, 'checkForm', checkResult)
    // }, 2000)
  }, location.href)
</script>
</body>
</html>

简单解释一下,通过将回调方法写入执行map,通过key+href的方式实现精确调用特定方法
该版本为存在许多问题,以及使用上的限制,即将在接下来的2.0中引入id来解决目前存在的问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Saryz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值