If we use <iframe>
with other page in different domains. we can use CustomEvent
or postMessage
to communicate between each other.
Version
HTML 5
CustomEvent
parent -> child
Data is passed from the parent page to the child page.
parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Lab</title>
</head>
<script>
let onClick = () => {
let detail = 'Hello World'
let myIframe = document.querySelector('#myIframe').contentWindow
myIframe.dispatchEvent(new CustomEvent('myEvent', { detail }))
}
</script>
<body>
<div>
<span>Parent</span>
<button onclick="onClick()">Click Me</button>
</div>
<iframe id="myIframe" src="child.html"/>
</body>
</html>
Line 16
<div>
<span>Parent</span>
<button onclick="onClick()">Click Me</button>
</div>
<iframe id="myIframe" src="child.html"/>
child.html
is embedded in <iframe>
, and we want to send messages from parent.html
to child.html
.
Line 9
let onClick = () => {
let detail = 'Hello World'
let myIframe = document.querySelector('#myIframe').contentWindow
myIframe.dispatchEvent(new CustomEvent('myEvent', { detail }))
}
- Put messages on
detail
variable - Get iframe window by
document.querySelector().contentWindow
- Use
new CustomEvent
to create a new event and pass an Object withdetail
property about data - Use
dispatchEvent
to fire event on the child page
child.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Lab</title>
</head>
<script>
addEventListener('myEvent', e => {
let myMsg = document.querySelector('#myMsg')
myMsg.innerText = e.detail
})
</script>
<body>
<span>Child : </span><span id="myMsg"/>
</body>
</html>
Line 15
<span>Child : </span><span id="myMsg"/>
Display messages from parent site.
Line 9
addEventListener('myEvent', e => {
let myMsg = document.querySelector('#myMsg')
myMsg.innerText = e.detail
})
- Use
addEventListener
on the child page to handle the custom event - Use
e.detail
to get data passed from the parent page
child -> parent
Data is passed from the child page to the parent page.
child.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Lab</title>
</head>
<script>
let onClick = () => {
let detail = 'Hello World'
top.dispatchEvent(new CustomEvent('myEvent', { detail }))
}
</script>
<body>
<span>Child : </span>
<button onclick="onClick()">Click Me</button>
</body>
</html>
Line 9
let onClick = () => {
let detail = 'Hello World'
top.dispatchEvent(new CustomEvent('myEvent', { detail }))
}
- Use
top.dispatchEvent
to fire the custom event on the parent site
parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Lab</title>
</head>
<script>
addEventListener('myEvent', e => {
let myMsg = document.querySelector('#myMsg')
myMsg.innerText = e.detail
})
</script>
<body>
<div>
<span>Parent : </span><span id="myMsg"/>
</div>
<iframe id="myIframe" src="child.html"/>
</body>
</html>
Line 9
addEventListener('myEvent', e => {
let myMsg = document.querySelector('#myMsg')
myMsg.innerText = e.detail
})
- Use
addEventListener
on the parent page to handle the custom event - Use
e.detail
to get data passed by the child page
postMessage
parent -> child
Data is passed from the parent page to the child page but using postMessage
.
parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Lab</title>
</head>
<script>
let onClick = () => {
let myIframe = document.querySelector('#myIframe').contentWindow
myIframe.postMessage('Hello World', '*')
}
</script>
<body>
<div>
<span>Parent</span>
<button onclick="onClick()">Click Me</button>
</div>
<iframe id="myIframe" src="child.html"/>
</body>
</html>
Line 9
let onClick = () => {
let myIframe = document.querySelector('#myIframe').contentWindow
myIframe.postMessage('Hello World', '*')
}
- Get iframe window by
document.querySelector().contentWindow
- Use
postMessage
to post data directly on the child page,*
means all target origins
child.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Lab</title>
</head>
<script>
addEventListener('message', e => {
let myMsg = document.querySelector('#myMsg')
myMsg.innerText = e.data
})
</script>
<body>
<span>Child : </span><span id="myMsg"/>
</body>
</html>
Line 9
addEventListener('message', e => {
let myMsg = document.querySelector('#myMsg')
myMsg.innerText = e.data
})
- Use
addEventListener
on the child page to handle themessage
event - Use
e.data
to get data passed from the parent page
child -> parent
Data is passed from the child page to the parent page but using postMessage
.
child.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Lab</title>
</head>
<script>
let onClick = () => top.postMessage('Hello World', '*')
</script>
<body>
<span>Child : </span>
<button onclick="onClick()">Click Me</button>
</body>
</html>
Line 9
let onClick = () => top.postMessage('Hello World', '*')
Use top.postMessage
to post data directly on the parent site, *
means all target origins.
parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, init-scale=1.0">
<title>HTML Lab</title>
</head>
<script>
addEventListener('message', e => {
let myMsg = document.querySelector('#myMsg')
myMsg.innerText = e.data
})
</script>
<body>
<div>
<span>Parent : </span><span id="myMsg"/>
</div>
<iframe id="myIframe" src="child.html"/>
</body>
</html>
Line 9
addEventListener('message', e => {
let myMsg = document.querySelector('#myMsg')
myMsg.innerText = e.data
})
- Use
addEventListener
on the parent page to handle themessage
event - Use
e.data
to get data passed from the child page
Conclusion
- Creating a custom event is a traditional way to communicate between iframe and the parent site
postMessage
is new API from HTML 5, which is supported by the modern browser