使用iframe联合跨库房路由模块

需求布景

两个有路由转跳联系的模块(模块A和B,AB能够经过路由互相转跳)涣散在两个不同的项目中(比方搬迁库房没全搬迁完,只搬迁了A模块),此刻后端需求联调AB模块整体功能。

此刻能够凭借一个父项目,把A模块和B模块经过iframe嵌入,然后实现功能的组合。

实现思路

把A模块与B模块中路由转跳相关的代码修改为与父使用的通讯(window.parent.postMessage),意图是凭借父使用与另一个模块通讯,父使用中就能够经过接收到的路由参数拼接出方针的路由地址,然后操作另一个模块的iframe的src属性,然后完结正常的路由转跳。

demo模仿

结构说明

index.html相当于嵌入了很多子项意图主使用,里边经过iframe嵌入了child.html以及一个哔哩哔哩主页的iframe。

child.html相当于一个子使用,它能够读取一个id,然后向主使用发送音讯,主使用监听音讯事情,操作b站iframe的src,然后做到子使用之间的通讯。

运行方法

经过live-server启动index.html与child.html

在index.html使用中:操作上方child.html里的input,输入用户id,点击按钮。调查下方iframe的改变

代码分析

child.html

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>另一个iframe页面</title>
 </head>
 <body>
  <div>
    请输入用户主页id:<input type="text" />
   <button onclick="onBtnClick()">转跳至b站指定用户主页</button>
  </div>
  <script>
   function onBtnClick() {
    const input = document.querySelector("input");
    const userId = input.value;
    const params = {
     targetUrl: "https://space.bilibili.com",
     userId,
     };
    // 当本身作为一个iframe被嵌入时,经过window.parent拜访自己所在的父使用
    // window.parent.postMessage中的xxxWindow.postMessage方法即触发xxxWindow的message事情,第一个参数params即为传递的参数,第二个参数能够为详细的URI,只有URI与xxxWindow同源时xxxWindow才干接受到message,或者"*",表示不限制
    // 第二个参数为详细URI时意义需确认,总之便是同源限制
    window.parent.postMessage(params, "*");
    }
  </script>
 </body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
 </head>
 <style>
  .app {
   display: flex;
   flex-direction: column;
   height: 100vh;
   }
  .page2 {
   flex: 1;
   }
 </style>
 <body>
  <div class="app">
   <iframe
    src="http://127.0.0.1:5500/child.html"
    width="100%"
    height="40px"
    class="page1"
   ></iframe>
   <div class="page2">
    <iframe
     width="100%"
     frameborder="no"
     height="100%"
     src="https://www.bilibili.com/"
    ></iframe>
   </div>
  </div>
  <script>
   const page1 = document.querySelector(".page1");
   const page2 = document.querySelector(".page2");
   // 父使用监听child.html使用的message事情,并且操作b站iframe(视为另一个子使用)的src
   window.addEventListener("message", (e) => {
    const { targetUrl, userId } = e.data || {};
    if (targetUrl && userId) {
     page2.children[0].src = `${targetUrl}/${userId}`;
     }
    });
  </script>
 </body>
</html>

关于子使用款式

我们能够在父使用中在子使用的iframe的外层套一个div,这个盒子flex布局,并给iframe设置flex: 1;款式,能够封装成一个组件,伪代码:

<div flex width=props.width height=props.height>
 <iframe flex:1>
 </iframe>
</div>

子使用的展示大小(空间)此刻就由父使用中组件的props进行控制,我们的子使用最好设计成响应式的,以满足父使用中分配各种空间大小时,子使用的正常展示!

源码

gitee库房地址