如何向更改了 src 的 iframe 发送消息

How to send a message to the iframe whose src has been changed

我正在开发一个 html 页面,该页面承载一个 iframe 并且会根据情况发生变化。 iframe src 更改很容易完成,但不会向该 iframe 发送消息(通过 iframe.contentWindow.postMessage)。我做了一些测试 运行 并看到该消息显示在以前的 iframe 上。

之后我想到使用异步方法(尝试 async/await 并承诺)认为我的问题必须是因为那个,但问题仍然存在。

我正在使用 vanilla js,下面是简化的代码片段。

主索引页

<!DOCTYPE html>
<html lang="en">
<body>
   <iframe id="bodyChange" src="pubMode.html" frameborder="0"></iframe>
   <script src="../script/popup.js"></script>
</body>
</html>

现在,以下 html 个页面必须位于 iframe 中。

pubMode.html

<!DOCTYPE html>
<html lang="en">
<body>
    <button id="settingBtn">Setting</button>
    <button id="privMode">Private Mode</button>

    <div id="container"></div>
   <script src="../script/frame.js"></script>
</body>
</html>

setting.html

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

<body>
    <div id="settingPage"></div>

    <script src="../script/setting.js"></script>
</body>

</html>

privMode.html

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

<body>
    <button id="settingBtn">Setting</button>
    <button id="pubMode">Public Mode</button>

    <div id="container"></div>

    <script src="../script/frame.js"></script>
</body>

</html>

Js脚本。

frame.js

var frame = {
init: function(){
    //msg sender
    document.addEventListener('click', (event) => {
        var message = JSON.stringify({
            id: event.target.id
        });
        window.parent.postMessage(message, '*');
    });

    //msg reciever
    window.addEventListener('message', function (e) {
        document.getElementById('container').innerHTML = e.data;
    });
   
}}
document.addEventListener('DOMContentLoaded', frame.init);

popup.js

class popup{
   iframeMap = {
    'settingBtn': 'setting.html',
    'privMode': 'privMode.html',
    'pubMode': 'pubMode.html',
    'editBtn': 'edit.html'
   }

  constructor(){
    window.addEventListener('message', (e) => {
            let data = JSON.parse(e.data);
            let myPromise = new Promise((resolve, error) => {
                let frameObj = document.getElementById('bodyChange');
                frameObj.src = this.iframeMap[data.id];

                resolve(frameObj);
            }); 
           
            myPromise.then(frameObj => {
                console.log(frameObj.src);
                frameObj.contentWindow.postMessage(response, '*');
            });
           }
         });
       }
    }

   var obj = new popup();

您可以在 popup.js 中使用 iframe.onload 事件处理程序。

popup.js

class popup {
  iframeMap = {
    settingBtn: "setting.html",
    privMode: "privMode.html",
    pubMode: "pubMode.html",
    editBtn: "edit.html"
  };
  constructor() {
    window.addEventListener("message", (e) => {
      let data = JSON.parse(e.data);
      let frameObj = document.getElementById("bodyChange");
      frameObj.src = this.iframeMap[data.id];
      console.log(frameObj.src);
      frameObj.onload = () => {
        // TODO: replace frameObj.src with response
        frameObj.contentWindow.postMessage(frameObj.src, "*");
      };
    });
  }
}

var obj = new popup();

我创建了一个 CodeSandbox 来演示它。