跨页面通讯 实现音乐播放

需求的效果

如图所示,页面A点击播放:

  • 若没有音乐播放界面新打开页面进行播放
  • 有音乐则更新

实现

首先想到了跨页面通讯的api。

页面通讯api有很多这里不多加赘述,我这里使用了BroadcastChannel,兼容下还ok,如果需要兼容ie可以选择本地存储也可实现

如何知道页面有没有新打开过呢?我首先想到一个方案即是A给B页面发消息,B收到再立即发消息给A,利用async await 配合settimeout,如果settimeout时间都过了,还没有接收到消息则说明这个页面不存在 ,window.open打开即可

A页面

html 复制代码
<body>

    <div class="main">
        <button data-id="1">播放▶《海阔天空》</button>

        <button data-id="2">播放▶《后来》</button>

        <button data-id="3">播放▶《我怀念的》</button>
    </div>

    <script>

        const dom = document.querySelector('.main');
        const channel = new BroadcastChannel('music');


        const ifOpen = async () => {
            return new Promise((resolve, _) => {
                channel.addEventListener("message", (e) => {
                    resolve(false)
                })
                setTimeout(() => {
                    resolve(true)
                }, 50);
            })
        }
        
        dom.addEventListener("click", async (e) => {

            if (!e.target.dataset.id) {
                return
            }
            
            // 发送消息 看看有没有回应
            channel.postMessage(e.target.dataset.id)
            // 没有回应则表示页面已经打开 否则直接用传过去的数据即可
            const data = await ifOpen()

            if (data) {
                window.open(`./music.html?id=${e.target.dataset.id}`, '_blank')
            }
        })

    </script>
    </body>

B页面

html 复制代码
<body>
    <h1>音乐播放器</h1>
    <audio controls>
        <source src="./后来.mp3" type="audio/mpeg" data-quality="highest">
        Your browser does not support the audio element.
    </audio>

    <script>

        const dom = document.querySelector('audio');
        const playMusic = (id) => {

            const enumData = {
                1: "海阔天空.mp3",
                2: "后来.mp3",
                3: "我怀念的.mp3",
            }
            dom.src = enumData[id]
            document.title = enumData[id]
            dom.play();
        }

        const url = new URL(window.location.href);
        const id = url.searchParams.get("id");
        playMusic(id)


        const channel = new BroadcastChannel('music');
        channel.addEventListener("message", (evt) => {
            channel.postMessage("music")
            playMusic(evt.data)
        })

    </script>
</body>
相关推荐
昔人'3 分钟前
`corepack` 安装pnpm
前端·pnpm·node·corepack
萌萌哒草头将军5 分钟前
pnpm + monorepo 才是 AI 协同开发的最佳方案!🚀🚀🚀
前端·react.js·ai编程
hboot1 小时前
💪别再迷茫!一份让你彻底掌控 TypeScript 类型系统的终极指南
前端·typescript
GISer_Jing1 小时前
深入拆解Taro框架多端适配原理
前端·javascript·taro
毕设源码-邱学长1 小时前
【开题答辩全过程】以 基于VUE的藏品管理系统的设计与实现为例,包含答辩的问题和答案
前端·javascript·vue.js
用户28907942162712 小时前
Spec-Kit应用指南
前端
酸菜土狗3 小时前
🔥 手写 Vue 自定义指令:实现内容区拖拽调整大小(超实用)
前端
ohyeah3 小时前
深入理解 React Hooks:useState 与 useEffect 的核心原理与最佳实践
前端·react.js
Cache技术分享3 小时前
275. Java Stream API - flatMap 操作:展开一对多的关系,拉平你的流!
前端·后端
apollo_qwe3 小时前
前端缓存深度解析:从基础到进阶的实现方式与实践指南
前端