Home > Back-end >  How to send a message to the iframe whose src has been changed
How to send a message to the iframe whose src has been changed

Time:03-02

I am working on an html page which hosts a iframe and will change depending upon situation. The iframe src change is easily accomplished but sending message to that iframe (through iframe.contentWindow.postMessage) isn't happening. I did some test run and saw that message being displayed on previous iframe.

After that I thought of using asynchronus approach (tries async/await and promise also) thinking my problem has to be because of that but the problem still persisted.

I am working with vanilla js and below is simplified snippet of codes.

Main index page

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

Now, below are html pages which have to be in 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 script.

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();

CodePudding user response:

You could use the iframe.onload event handler in your popup.js.

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();

I've created a CodeSandbox that demonstrate it.

  • Related