跨页面通讯 实现音乐播放

需求的效果

如图所示,页面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>
相关推荐
WYiQIU18 小时前
11月面了7.8家前端岗,兄弟们12月我先躺为敬...
前端·vue.js·react.js·面试·前端框架·飞书
谢尔登18 小时前
简单聊聊webpack摇树的原理
运维·前端·webpack
娃哈哈哈哈呀19 小时前
formData 传参 如何传数组
前端·javascript·vue.js
zhu_zhu_xia20 小时前
vue3+vite打包出现内存溢出问题
前端·vue
tsumikistep20 小时前
【前后端】接口文档与导入
前端·后端·python·硬件架构
行走的陀螺仪21 小时前
.vscode 文件夹配置详解
前端·ide·vscode·编辑器·开发实践
2503_9284115621 小时前
11.24 Vue-组件2
前端·javascript·vue.js
Bigger21 小时前
🎨 用一次就爱上的图标定制体验:CustomIcons 实战
前端·react.js·icon
谢尔登21 小时前
原来Webpack在大厂中这样进行性能优化!
前端·webpack·性能优化
cypking1 天前
Vue 3 + Vite + Router + Pinia + Element Plus + Monorepo + qiankun 构建企业级中后台前端框架
前端·javascript·vue.js