跨页面通讯 实现音乐播放

需求的效果

如图所示,页面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>
相关推荐
mango_mangojuice5 分钟前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习
Days205028 分钟前
简单处理接口返回400条数据本地数据分页加载
前端
Novlan135 分钟前
@tdesign/uniapp 图标瘦身
前端
ManThink Technology38 分钟前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
. . . . .1 小时前
shadcn组件库
前端
2501_944711431 小时前
JS 对象遍历全解析
开发语言·前端·javascript
发现一只大呆瓜2 小时前
虚拟列表:支持“向上加载”的历史消息(Vue 3 & React 双版本)
前端·javascript·面试
css趣多多2 小时前
ctx 上下文对象控制新增 / 编辑表单显示隐藏的逻辑
前端
_codemonster2 小时前
Vue的三种使用方式对比
前端·javascript·vue.js
寻找奶酪的mouse2 小时前
30岁技术人对职业和生活的思考
前端·后端·年终总结