跨页面通讯 实现音乐播放

需求的效果

如图所示,页面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>
相关推荐
小小小小宇27 分钟前
前端转后端基础- 变量和类型
前端
Cobyte1 小时前
1.基于依赖追踪和触发的响应式系统的本质
前端·javascript·vue.js
主宰者1 小时前
C# CommunityToolkit.Mvvm全局事件
java·前端·c#
前端小咸鱼一条2 小时前
16.迭代器 和 生成器
开发语言·前端·javascript
小江的记录本2 小时前
【注解】常见 Java 注解系统性知识体系总结(附《全方位对比表》+ 思维导图)
java·前端·spring boot·后端·spring·mybatis·web
web守墓人2 小时前
【前端】记一次将ruoyi vue3 element-plus迁移到arco design vue的经历
前端·vue.js·arco design
伊步沁心2 小时前
Webpack & Vite 深度解析
前端
libokaifa2 小时前
OpenSpec + TDD:让 AI 写代码,用测试兜底
前端·ai编程
用户15815963743702 小时前
搭 AI Agent 团队踩了 18 个坑,总结出这 5 个关键步骤
前端
Kellen2 小时前
Fumadocs 基础概念:从内容源到页面渲染
前端