跨页面通讯 实现音乐播放

需求的效果

如图所示,页面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>
相关推荐
蜗牛快跑21312 分钟前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程
Dread_lxy13 分钟前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
涔溪1 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
榴莲千丞1 小时前
第8章利用CSS制作导航菜单
前端·css
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与1 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
guokanglun1 小时前
CSS样式实现3D效果
前端·css·3d
咔咔库奇2 小时前
ES6进阶知识一
前端·ecmascript·es6
渗透测试老鸟-九青2 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss
龙猫蓝图2 小时前
vue el-date-picker 日期选择器禁用失效问题
前端·javascript·vue.js