需求的效果
如图所示,页面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>