3

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?

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
nooby
  • 87
  • 7
  • 1
    `document.getElementById("page1").innerHTML = "page one says hello";` is an error on pages with no `page1` element. Errors cause the rest of the script to be aborted so that other lines don't run. Your script has nothing to do with communication between two tabs though. It's just a single script that both tabs run every time they're loaded. If you need tabs to communicate you might want to look at this: https://stackoverflow.com/questions/28230845/communication-between-tabs-or-windows – Paul Jan 22 '18 at 21:21
  • It's not entirely clear what your end goal is. You mention [broadcast channels](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API) and pages "talking" to each other, but your example seems to simply be a single JS file that is intended to interact with more than one page. – Herohtar Jan 22 '18 at 21:39
  • My eventual goal is to use user input on one page and have it displayed on another page simultaneously – nooby Jan 23 '18 at 04:28
  • Does this answer your question? [calling a function or communicating from one browser window to another using Jquery / javascript](https://stackoverflow.com/questions/2437088/calling-a-function-or-communicating-from-one-browser-window-to-another-using-jqu) – outis Oct 11 '21 at 09:58

2 Answers2

10

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 page1page2

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 the Event.data

And vice-versa.

JavaScript Communicate between tabs using Broadcast Channel API

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 a storage event
  • pageY can now read localstorage[pageX] or better (to make it simpler (and pageN agnostic)) the Event.newValue sent by the storage event

And vice-versa.

For starters: DEMO: page1page2

JavaScript Communicate between tabs using localStorage

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.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
  • Your answer is good. However the question is about usage of [broadcast channel](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API) – RaphaMex Jan 23 '18 at 00:50
  • @RaphaMex thx I noticed that from the OP's Q. It just took some time to expand. – Roko C. Buljan Jan 23 '18 at 02:08
  • How do I access the text in the data-broadcast message that is sent, as I want to alter it's content? It won't work trying to id it and using innerHTML. – nooby Jan 23 '18 at 06:24
  • I should add that the content of the data-broadcast message will be generated from an input box by users. – nooby Jan 23 '18 at 06:26
  • @nooby simply use the `ev.data`. If you want to find out what you can access try `console.log( ev )` and explore the returned object. Instead of buttons use ``, instead of `click` use the `input` Event. You can find most of the underlying logic in the second example. Mix the two :) – Roko C. Buljan Jan 23 '18 at 21:25
0

Both pages are throwing an error, the difference is, on the first page the error doesn't happen until after the div is changed.

Here's one possible approach.

newFunction();

function newFunction() {
  var page = document.getElementById("page1") ? "1" : "2";
  var msg = page == "1" ? "page one says hello" : "page two says goodbye";
  document.getElementById("page"+page).innerHTML = msg;
}
I wrestled a bear once.
  • 22,983
  • 19
  • 69
  • 116
  • That will indeed make the single JS file work on the two different pages, but that is not the same as the two pages "talking" to each other. – Herohtar Jan 22 '18 at 21:37
  • You are right, but it does not answer the question. The question is about communication between 2 tabs in a same browser (hence 2 pages). – RaphaMex Jan 23 '18 at 00:47
  • @RaphaMex that's a pretty good assumption, but it's still an assumption. despite requests for clarification OP has not shed any light on the subject. – I wrestled a bear once. Jan 23 '18 at 00:49
  • Hi I wrested a bear. My goal is for a 'controller' page (tab one)which has controller input, which in turn sends data to a 'user page' (tab 2.). – nooby Jan 23 '18 at 05:37