“This is the fifth day of my participation in the First Challenge 2022. For details: First Challenge 2022.”
Introduction to the
Words back, introduced the basic use of Postmate I believe we have a certain understanding of Postmate, also clear Postmate communication basic usage, next talk about the actual situation of the use of Postmate and will encounter problems
Postmate is actually used
Postmate addresses the issue of communication between two pages using iframe embedded in the page,
That’s the most practical example:
This is a page that needs a popover, and of course this popover can be imported from outside, so you can use iframe to import it
The main page and this popover are both relatively independent modules. There is no connection between them. Now iframe is used to link them together. For example, a simple requirement, click the screenshot button to obtain the parent page of the video screenshot, how to do?
There is no way to get the value of the parent page directly in the popover, and there is no way to call the method of the parent page, so you need Postmate to let them communicate
Postmate father-son communication — problem analysis
Article is about how to transfer value between father and son, but you have a problem, the parent page to monitor an event, when establishing connection with child pages, child pages immediately released this event, but this time we don’t need to let him triggering event, such as I just open the popup window, he cut a figure to me, I have not click the screenshot, He just took screenshots. Isn’t that unreasonable?
child
import PostMate from "Postmate"; / / create an instance const handshake = new PostMate. Model ({height: () = > document. The height | | document. The body. The offsetHeight}); Document.queryselector ().addeventListener ('click',()=>{handshake. Then (parent =>{parent. 'This is a child page!! ')}); })Copy the code
So write is very logical right, when click the button to trigger the release, in the message to the parent page, tell him that you need to do, this is normal situation, we need, but have you ever tried you will find a problem, you click on the event to trigger the parent, emit () event, you can print, But he just wouldn’t trigger it, which you’d think was weird, because that’s what I did
It has to do with Postmate’s handshake, but aside from that, it doesn’t work because they need to make a connection, you can’t click and then make a connection,
So what to do? If you want to publish, you need to create the parent object with Handshake. Then, you can publish the parent object. If you get the parent object, you can publish it freely.
Exactly, and that’s the logic of most people, because that’s it, but how do you do it?
My idea was to create a global variable and assign parent to the global variable to get it, but it turns out I was naive. Everyone should try it.
import PostMate from "Postmate"; const handshake = new PostMate.Model({ height: () => document.height || document.body.offsetHeight }); const getParent = null handshake.then(parent => { console.log(parent); GetParent = parent console.log(getParent); }); console.log(getParent); //nullCopy the code
This variable does get the value of parent, but it is changed back to null in the global printing process. I thought that this function does not allow assignment, but the value of getParent exists inside the function. Can a function be organized to bring out the values inside? That’s crazy, but I thought about it at the time, but it can’t be that far from the truth.
Thought for A long time, has also changed A lot of kinds of written code, all have no result found, found should not code issue, what is not given, so the thought of, this is to use the embedded iframe page, the two pages are independent of each other, found no everybody, there was no correlation between them, just A reference for B, but B itself, He has something that doesn’t go away, and what is B? It is a page, so it has its own scope, so:
import PostMate from "Postmate";
const handshake = new PostMate.Model({
height: () => document.height || document.body.offsetHeight
});
handshake.then(parent => {
console.log(parent);
window.getParent = parent
window.getParents = { "text": 'orange' }
});
Copy the code
So I mounted the parent under the window, guys, what was going on, there was no object under the window, and I was worried that there was something wrong with my code, so I created a new element and there was nothing, and I was really excited, because the truth was about to emerge, so I proved it again, I go to the parent page and mount an object under the window.
import PostMate from "Postmate"; const handshake = new PostMate({ container: document.getElementById('iframe-container'), url: '.. /.. /child/src/child.html', name: 'my-iframe-name', classListArray: ["myClass"] }); handshake.then(child => { child.on('someEvent', (data) => { console.log('someEvent', data); Const iframe = document. QuerySelector (' # iframe - container) iframe. ContentWindow. PostMessage ({the text: "receive! Over ~'}, '*'); }); }); window.getParents = { "text": 'orange' } //!!!Copy the code
The object I mounted appears in the console printgetParent
So when the child page is mounted, the control cannot print the mounted object, because the child page has its own window. Now I delete the mount of the parent page, leaving the mount of the child page, and THEN I think, How to mount the parent page to the window, so I thought for a long time, so I tried to mount the parent page to the window.
import PostMate from "Postmate";
const handshake = new PostMate.Model({
height: () => document.height || document.body.offsetHeight
});
handshake.then(parent => {
console.log(parent);
window.getParent = parent
window.parent.getParents = { "text": 'orange' }
});
Copy the code
Print Window on the console
The results of: find really mount up, that the results had come out, just need to the properties of the child pages, mounted to the window. The parent, will be able to mount to the parent window of the page, so you just need to customize a variable, mount to the parent page, so you can use it at any time, completes the click again after the needs of the publishing events.
conclusion
import PostMate from "Postmate";
const handshake = new PostMate.Model({
height: () => document.height || document.body.offsetHeight
});
handshake.then(parent => {
window.parent.getParent = parent
});
document.querySelector('.xxx').addEventListener('click',function(){
window.parent.getParent.emit("someEvent",data)
})
Copy the code
Mount the object returned after establishing the connection to the window of the parent page. When the click event occurs, send the corresponding event and data, and complete the free transmission of values in the parent page nested with iframe ~~