某Q音乐标签页通信

235 阅读5分钟

场景:

最近发现一个好玩的,打开某Q音乐节目,播放列表点击播放歌曲。 qq音乐-新开tab页.gif

观察详情:

当在列表页面点击歌曲播放时,若当前不存在音乐播放详情页,则打开一个新的播放详情页。然而,若已经存在一个音乐播放详情页,则直接使用该已存在的页面,而不是再次打开新的播放详情页。

qq音乐-tab页.jpg

传送门:

🚄✈️🚀 :github.com/BigPengZai/…

梳理需求:

1.点击播发歌曲会打开一个新的窗口

2.再次点击其他歌曲未打开新的窗口,在原有的窗口打开新的歌曲

3.打开一个页面 musi 无感刷新

实现一:

mock出一个music-list. 创建歌曲item

<div class="music-item" data-name="晴天">

<div class="song-info">

<span class="play-title">晴天</span>

</div>

<i class="play-icon"></i>

</div>

通常,通过 window.open('./src/static/Audio.html?name=' + name, '_blank') 打开一个新的标签页是常见的做法,但每次点击歌曲切换都会刷新页面,这会影响用户体验,尤其在大列表界面更为明显。

一种优化方式是使用 window.open('./src/static/Audio.html?name=' + name, 'music'),将后面的参数统一为一个标签名,比如 'music'。但是这种方法同样存在刷新页面的问题。

观察了某Q音乐平台,发现他们在切换歌曲时并未刷新页面,这提供了一个更好的用户体验。

因此,需要一种方法,在切换歌曲时不刷新页面,同时保持在同一个标签页中播放音乐。

实现二:

思考其实这里要使用跨标签页通信的技术,实现跨标签页通信可以通过以下几种方式:

  1. BroadcastChannel APIBroadcastChannel API 允许在同一浏览器中的不同标签页之间进行实时通信。通过创建一个共享的频道,不同标签页可以发送和接收消息。

  2. LocalStorage 或 SessionStorage:使用 LocalStorageSessionStorage 存储数据,并监听 storage 事件。当一个标签页修改了存储的数据时,其他标签页可以通过监听 storage 事件来感知到数据的变化,从而实现通信。

  3. Cookies:通过设置和读取 Cookie 来进行通信。虽然 Cookies 通常用于客户端和服务器之间的通信,但它们也可以在同一域名下的不同标签页之间进行通信。

  4. PostMessage API:使用 window.postMessage() API 可以实现跨窗口通信,包括不同标签页之间的通信。通过指定目标窗口的 origin,可以确保安全性。

  5. SharedWorkerSharedWorker 是一种特殊的 Web Worker,可以被多个浏览上下文(如标签页)共享。通过 SharedWorker,多个标签页可以共享同一个上下文,从而实现通信。

  6. Server-Sent Events (SSE):使用 SSE 技术,服务器可以向客户端推送事件流。不同标签页可以通过监听相同的事件流来进行通信。

  7. WebSocket:WebSocket 是一种双向通信协议,可以在客户端和服务器之间建立持久连接。通过 WebSocket,不同标签页可以连接到同一个 WebSocket 服务器,实现实时通信。

每种方式都有自己的特点和适用场景,选择合适的方式取决于具体的需求和应用场景。

这里我们使用 BroadcastChannel

//  1.创建一个 music 的频道
const channel = new BroadcastChannel('music')

//  2. 发送消息
channel.postMessage(name)

// 3. 在播放页面进行监听

channel.addEventListener('message', e => {

    console.log(e.data)

})

是的核心api 就这三步,最后完善一些细节代码。是否开启新页面、修改urlname等。完成demo请参考:github.com/BigPengZai/…

qqcross-demo.gif

最后:

BroadcastChannel 是 Web API 提供的一种机制,用于在同一浏览器中的不同上下文(例如不同的标签页、不同的窗口或同一窗口的不同 iframe)之间进行消息通信。以下是它的优缺点:

优点:

  1. 跨上下文通信BroadcastChannel 允许在同一浏览器中的不同上下文之间进行实时通信,这对于需要跨标签页或跨窗口共享数据的应用非常有用。
  2. 简单易用:使用 BroadcastChannel API 相对简单,只需实例化一个频道并监听消息即可,它提供了基本的发布-订阅模式。
  3. 实时性:消息传递是实时的,一旦消息发送,接收方会立即收到,这使得 BroadcastChannel 适用于需要快速响应的场景。
  4. 多对多通信:一个频道可以被多个上下文同时监听,因此它支持多对多的通信模式。

缺点:

  1. 同源策略限制BroadcastChannel 遵循同源策略,因此只能在同源的上下文之间进行通信,无法跨域进行消息传递。
  2. 安全性考虑:因为消息是在浏览器端进行传递的,所以存在一定的安全风险,需要谨慎处理敏感信息的传递。
  3. 兼容性问题:虽然大多数现代浏览器都支持 BroadcastChannel,但在一些旧版本浏览器中可能存在兼容性问题,需要额外的处理措施。
  4. 性能考虑:频繁地发送大量消息可能会影响页面的性能,因此需要注意控制消息的数量和大小。

总的来说,BroadcastChannel 提供了一种方便的方式来实现同一浏览器中不同上下文之间的实时通信,但在使用时需要考虑安全性、兼容性和性能等方面的问题。