内外网页通信
集成山海鲸页面时,外部网页可以通过发送 postmessage 的形式来进行通信,同时也支持直接通过 postmessage 动态的修改属性值和触发交互。
1.同二开代码通信
最通用也是最灵活的方式就是外部发送 postmessage 给内部的二开代码,再有二开代码来决定下一步需要做什么操作,同时二开代码在收到 message 之后也可以向外部发送信息。
在前面文章集成了 iFrame 之后,我们在外部网页中再添加两个按钮,分别是白天和晚上。
我们看一下实例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <html> <style> html { background-color: cadetblue; } .controlbar { display: flex; } .controlbar button { width: 200px; height: 100px; margin-left: 50px; } </style> <body> <iframe id="shanhai-frame" width="1600" height="900" src="http://192.168.31.136:5057/uo0cu7q95zuq/" frameborder="0" allowfullscreen="true" ></iframe> <div class="controlbar"> <button onclick="setDaytime(12)">切换白天</button ><button onclick="setDaytime(0)">切换晚上</button> </div> </body>
<script> let iframeLoaded = false; let shanhaiFrame = document.getElementById("shanhai-frame"); shanhaiFrame.addEventListener("load", function (e) { iframeLoaded = true; }); function setDaytime(value) { if (iframeLoaded) { const postMessageData = { action: "customMessage", data: { daytime: value, }, }; shanhaiFrame.contentWindow.postMessage(postMessageData, "*"); } } </script> </html>
|
在山海鲸中,所有的组件的二开都会收到的这个 message,这里因为我们要修改鲸孪生场景上的当前时间,因此我们在鲸孪生场景上挂载以下二开代码:
二开代码内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export class SampleExtension { async init() { this.element.addEventListener("message", (ev) => { const { data, origin, source } = ev; if (data.action == "customMessage") { const customData = data.data; const daytime = customData.daytime; this.element.setOption(["daytime"], daytime); } }); } }
|
我们也可以在收到了 message 之后,通过 source 对象向外部发送 postmessage,也可以直接通过 window.parent 来发送。注意这两种形式的区别在于 source 必须收到 message 之后才能发送,window.parent 可以主动发送,我们修改一下代码,向网页发送一个回传消息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export class SampleExtension { async init() { this.element.addEventListener("message", (ev) => { const { data, origin, source } = ev; if (data.action == "customMessage") { const customData = data.data; const daytime = customData.daytime; this.element.setOption(["daytime"], daytime); window.parent.postMessage("Got it", "*"); } }); } }
|
在网页的代码中加上收消息的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| <html> <style> html { background-color: cadetblue; } .controlbar { display: flex; } .controlbar button { width: 200px; height: 100px; margin-left: 50px; } </style> <body> <iframe id="shanhai-frame" width="1600" height="900" src="http://192.168.31.136:5057/uo0cu7q95zuq/" frameborder="0" allowfullscreen="true" ></iframe> <div class="controlbar"> <button onclick="setDaytime(12)">切换白天</button ><button onclick="setDaytime(0)">切换晚上</button> </div> </body>
<script> let iframeLoaded = false; let shanhaiFrame = document.getElementById("shanhai-frame"); shanhaiFrame.addEventListener("load", function (e) { iframeLoaded = true; }); window.addEventListener("message", (ev) => { const { data } = ev; console.log("收到信息:", data); }); function setDaytime(value) { if (iframeLoaded) { const postMessageData = { action: "customMessage", data: { daytime: value, }, }; shanhaiFrame.contentWindow.postMessage(postMessageData, "*"); } } </script> </html>
|
2.动态修改组件设置
我们修改一下上一节代码的结构,不使用二开代码,直接修改设置项,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <html> <style> html { background-color: cadetblue; } .controlbar { display: flex; } .controlbar button { width: 200px; height: 100px; margin-left: 50px; } </style> <body> <iframe id="shanhai-frame" width="1600" height="900" src="http://192.168.31.136:5057/ap1guovmpedt/" frameborder="0" allowfullscreen="true" ></iframe> <div class="controlbar"> <button onclick="setDaytime(12)">切换白天</button ><button onclick="setDaytime(0)">切换晚上</button> </div> </body>
<script> let iframeLoaded = false; let shanhaiFrame = document.getElementById("shanhai-frame"); shanhaiFrame.addEventListener("load", function (e) { iframeLoaded = true; }); function setDaytime(value) { if (iframeLoaded) { const postMessageData = { action: "setOption", data: { elementUID: ["c9ozws2ktrjk", "9lj7ryar3jjz", "scene"], optionPath: ["daytime"], optionValue: value, }, }; shanhaiFrame.contentWindow.postMessage(postMessageData, "*"); } } </script> </html>
|
注意这段代码主要就是向按了按钮之后向山海鲸的页面中发送 postmessage,其中 elementUID 是我们需要修改的目标元素的 UID,我们可以通过点击对应的元素,然后再右侧面板中点击更多选项卡,可以看到 elementUID:
另外 optionPath 则是和其他二开一样,找到对应的属性,鼠标移动上去后,点击三个点,选择菜单中的调用代码示例:
弹出框中复制 getOption 或者 setOption 的第一个参数即可:
最终网页效果如下:
点击了切换晚上后得到以下结果:
3.动态触发交互
此功能暂未开放。