Dynamic Iframe With Communication channel
JavaScript
function createIframe ({left, width, background}) {
// prefix
const PREFIX = Math.random(),
symbol = name => `${PREFIX}:${name}`;
// create iframe
let iframe = document.createElement('iframe');
iframe.style.cssText = `
position: fixed;
left: ${left||'0px'};
background: ${background||'red'};
top: 0;
bottom: 0;
border: none;
padding: 0;
margin: 0;
width: ${width||'100px'};
height: 100%;
max-height: 100%;
zIndex: 1000000;
cursor: pointer;
`;
iframe.setAttribute('frameborder', 0);
iframe.setAttribute('scrolling', 'no');
document.body.appendChild(iframe);
// listen for a event from the iframe communcation channel
addEventListener('message', ({data}) => {
if (data.type === symbol('loaded')) {
console.log('loaded');
} else if (data.type === symbol('close')) {
iframe.style.maxHeight = '40px';
} else if (data.type === symbol('open')) {
iframe.style.maxHeight = '100%';
}
});
// run code within the iframes context
with (iframe.contentWindow) {
let state = {
isOpen: true
};
// send a loaded event
parent.postMessage({type: symbol('loaded')}, '*');
// bind open/close commands on click
document.body.addEventListener('click', () => {
state.isOpen = !state.isOpen;
if (!state.isOpen) {
parent.postMessage({type: symbol('close')}, '*');
} else {
parent.postMessage({type: symbol('open')}, '*');
}
})
}
}
createIframe({left: '0%', width: '33.33%', background: 'red'});
createIframe({left: '33.33%', width: '33.33%', background: 'green'});
createIframe({left: '66.66%', width: '33.33%', background: 'blue'});
addEventListener('message', ({data}) => console.log(data));