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.