admin管理员组

文章数量:1202370

My web page has

var bc = new BroadcastChannel('Consumer');

bc.onmessage = function(event) {
  alert("a");
}

bc.postMessage("hello");

It broadcasts a message, and the page is also required to receive the same message.

However it doesn't work. Did I miss anything?

My web page has

var bc = new BroadcastChannel('Consumer');

bc.onmessage = function(event) {
  alert("a");
}

bc.postMessage("hello");

It broadcasts a message, and the page is also required to receive the same message.

However it doesn't work. Did I miss anything?

Share Improve this question asked Nov 29, 2017 at 1:59 user746461user746461 3
  • 2 the specs say Sends the given message to other BroadcastChannel objects set up for this channel. – Jaromanda X Commented Nov 29, 2017 at 2:08
  • @JaromandaX hmm... I need to broadcast to the current page as well as other pages.. What method should I use? – user746461 Commented Nov 29, 2017 at 4:55
  • 1 @Gqqnbig see my answer, it will broadcast too the current page and to all other pages. – ThdK Commented Oct 15, 2018 at 9:09
Add a comment  | 

4 Answers 4

Reset to default 21

You can create two instances of BroadcastChannel on your page. One can act as a broadcaster for messages, the other one for receiving messages.

var broadcaster = new BroadcastChannel('Consumer');
var messageReceiver= new BroadcastChannel('Consumer');

messageReceiver.onmessage = function(event) {
  alert(event.data);
}

broadcaster.postMessage("hello");

See this in action: https://jsfiddle.net/h56d3y27/

Or wrapped in a reusable class: (note: class is not supported by all browsers. See : https://caniuse.com/#search=class for browser compatibility)

class AllInclusiveBroadcaster {  
    constructor(listener, channelName) {
    if (!channelName) channelName = "channel";
    this.broadcaster = new BroadcastChannel(channelName);
    this.messageReceiver = new BroadcastChannel(channelName);

    this.messageReceiver.onmessage = (event) => {
        listener(event.data);
    }
    }

  postmessage(data) {
    this.broadcaster.postMessage(data);
  }
}


var broadcaster = new AllInclusiveBroadcaster((data) => alert(data));

broadcaster.postmessage("Hello BroadcastChannel");

See this also in action a JSFiddle

You could dispatch an event (call it what you like) to, say, document, with the same data ... then have a single handler that listens for BroadcastChannel messages and to the event name you created above

in the following, the code creates and listens for fakeBroadcastMessage

created a function to send both the bc message and the "local" message

var bc = new BroadcastChannel('Consumer');
function handleBroadcastMessage(event) {
    // do things here
}
bc.addEventHandler('message', handleBroadcastMessage);
document.addEventListener('fakeBroadcastMessage', handleBroadcastMessage);

function sendMessage(data) {
    bc.postMessage(data);
    var ev = new Event('fakeBroadcastMessage');
    ev.data = data;
    document.dispatchEvent(ev);
}

sendMessage('hello');

The solutions provided by people here are very nice but the main reason that BroadcastChannel behaves like this, is that you can almost always refactor it without using addEventListener. So in your example, instead of this:

messageReceiver.onmessage = function(event) {
  alert(event.data);
}

broadcaster.postMessage("hello");

you can simply write:

const message = "hello"
broadcaster.postMessage(message);
alert(message);

But it also may be a little out-of-sync with other instances of the channel (couple of milliseconds I suppose) and you want it to be exactly triggered together with the rest of the listeners. In that case, you can use the second instance similar to what @ThdK mentioned.

Below is a little module I made to abstract away the rough edges around which BroadcastChannel instance to send or receive with when publishing a message within the same page. You don't even need to worry about instantiating the class or BroadcastListneners involved, as that is covered by Proxy'd auto-creation:

let channelList = {};

class Channel {
  constructor(name) {
    channelList[name] = this;
    this.sender = new BroadcastChannel(name);
    this.receiver = new BroadcastChannel(name);
  }
  publish(message) {
    this.sender.postMessage(message);
  }
  subscribe(listener){
    this.receiver.addEventListener('message', listener);
  }
  unsubscribe(listener) {
    this.receiver.removeEventListener('message', listener);
  }
  close(){
    delete channelList[this.sender.name];
    this.sender.close();
    this.receiver.close();
  }
}

export const channels = new Proxy(channelList, {
  get(target, name) {
    return channelList[name] || new Channel(name);
  }
})

Which you can use like this:

channels.myCoolChannel.publish(MESSAGE)

channels.myCoolChannel.subscribe(YOUR_LISTENER)

channels.myCoolChannel.unsubscribe(YOUR_LISTENER)

channels.myCoolChannel.close()

本文标签: javascriptDoes BroadcastChannel work on the same pageStack Overflow