I’m wanting a JavaScript file to control two HTML files simultaneously.
<!DOCTYPE html> <html> <head> <title>tryAgainPage1</title> <meta charset="UTF-8"> </head> <body> <div id="page1"></div> <script src="tryAgain.js"></script> </body> </html>
That’s page one. Next is page two.
<!DOCTYPE html> <html> <head> <title>tryAgainPage2</title> <meta charset="UTF-8"> </head> <body> <div id="page2"></div> <script src="tryAgain.js"></script> </body> </html>
And here is the JavaScript:
newFunction(); function newFunction() { document.getElementById("page1").innerHTML = "page one says hello"; document.getElementById("page2").innerHTML = "page two says goodbye"; }
Page one is working, page two isn’t. I’ve been trying for a day to get pages talking to each other, without success. I’m not sure I understand how to implement Broadcast channel in this instance (if indeed that is appropriate.) Can anyone help?
Advertisement
Answer
postMessage
If you’re looking for a way to make two pages or tabs communicate you can take a look at:
MDN Window.postMessage, and read this postMessage article
or MDN Broadcast_Channel_API
Using Broadcast Channel API page1 — page2
How it works:
- pageX subscribes to a named Broadcast Channel object
- pageY broadcasts to the same Channel name using
postMessage
- pageX listens to
"message"
events and prints theEvent.data
And vice-versa.
page1.html
<h1>PAGE 1</h1> <p><button data-broadcast="Page 1 talking!">BROADCAST</button></p> Page 2 says: <div id="page2"></div> <script src="comm.js"></script>
page2.html
<h1>PAGE 2</h1> <p><button data-broadcast="Page 2! 'Allo 'Allo!">BROADCAST</button></p> Page 1 says: <div id="page1"></div> <script src="comm.js"></script>
comm.js
var bc = new BroadcastChannel('comm'); document.querySelector("[data-broadcast]").addEventListener("click", ev => { bc.postMessage( ev.target.dataset.broadcast ); }); const targetEl = document.querySelectorAll("#page1, #page2"); bc.addEventListener("message", ev => { [...targetEl].forEach( el => el.innerHTML = ev.data ); });
localStorage
and the storage
Event
Another simple, yet cool way, if both tabs are on the same domain is by using
Window.localStorageMDN and its Storage Event
.
How it works:
- pageX writes to
localstorage[pageX]
- pageY‘s
window
will trigger astorage
event - pageY can now read
localstorage[pageX]
or better (to make it simpler (and pageN agnostic)) theEvent.newValue
sent by the storage event
And vice-versa.
For starters: DEMO: page1 — page2
page1.html
<h1>PAGE 1</h1> <textarea data-sender="page1" placeholder="Write to page 2"></textarea> Page 2 says: <div id="page2"></div> <script src="comm.js"></script>
page2.html
<h1>PAGE 2</h1> <textarea data-sender="page2" placeholder="Write to page 1"></textarea> Page 1 says: <div id="page1"></div> <script src="comm.js"></script>
comm.js
// RECEIVER window.addEventListener("storage", ev => { document.getElementById( ev.key ).innerHTML = ev.newValue; }); // SENDER [...document.querySelectorAll("[data-sender]")].forEach( el => el.addEventListener("input", ev => localStorage[el.dataset.sender] = el.value ) );
Web RTC
You could use Web RTC (Web Real-Time Communications). A technology which enables Web applications and sites to capture and optionally stream audio and/or video media, as well as to exchange arbitrary data between browsers
Your main errors:
Your script was not working on one page… actually on both, the only difference was that on page 1 broke after realizing #page2
Element could not be found – Inversely on the other page broke immediately after realizing there is no "#page1"
Element (since first in order).
You should always check if al element exists using if ( someElement ) { /*found!*/ }
.
And yes, you cannot make communicate two pages that way. They will only share / include the same JS file.