js实现标签页打开控制

106 阅读1分钟

在两个同源页面中如果进行,会用到BroadcastChannel和postMessage,就跟类似的两个音频(视频)网站进行交互,那么在交互的时候会打开一个新的页签,并且在点击播放某一个音频(视频)的时候,就不会打开新的页面,而是会在原来打开的页签上进行刚点击音频(视频)上进行播放;

企鹅群: 306671879 欢迎加入

index.html 也就是列表页面

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document </title>
	<style>
         #app>div>span {
            display: block;
            height: 40px;
            background: #ccc;
            color: #000;
            margin-bottom: 10px;
        }
	</style>
</head>

<body>
	<div id="app">
		<div>
                <!-- 这里1.mp3  2.mp3 是音频播放资源  -->
			<span data-name="./1.mp3">播放</span>
		</div>
		<div>
		 <span data-name="./2.mp3">播放</span>
		</div>
	</div>
	<script src="./index.js"></script>
	<script>
		const playBtn = document.querySelectorAll('span[data-name]');
		// 创建一个全频道广播
		const channl = createChanenl('music');

		for (const btn of playBtn) {
			btn.onclick = (e) => {
				if (channl.listeners.size == 0) {
                                // 如果没有打开的页签则打开一个新的
					window.open('./music.html?name=' + e.target.dataset.name, '_blank')
				} else {
                                // 如果打开的了页签,则在当前的页签上重新播放当点击的
                                    channl.postMessage({
                                        musciName: e.target.dataset.name
                                    })
				}
			}
		}
	</script>
</body>

</html>
    

music.html

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document </title>
</head>

<body>
	<div id="app">
		<audio id="audio" controls></audio>
	</div>
	<script src="./index.js"></script>
	<script>
            const audio = document.getElementById('audio');
            audio.ondurationchange = () => {
                    audio.play()
            }
            function playSrc(name) {
                console.log(name);
                audio.src = name;
            }
            function init() {
                const url = new URL(location.href);
                const name = url.searchParams.get('name');
                if (!name) return;
                playSrc(name)
            }
            init()
            const channl = createChanenl('music');
            channl.addEventListener('message', e => {
                console.log(e.data);
                if (e.data.musciName) {
                    console.log(e.data.musciName);
                    playSrc(e.data.musciName)
                }
            })

	</script>
</body>

</html>

核心内容index.js 实现 页面控制

index.js

// 可根据实际情况进行修改
function createId(name) {
	const key = `channl-${name}`;
	let id = +localStorage.getItem(key);
	if (!id) {
		id = 0
	}
	id++;
	localStorage.setItem(key, id.toString())
	return id
}

function sendMas(msg, channl) {
	channl.postMessage({
		id: channl.id, msg
	})
}

function createChanenl(name) {
	const channl = new BroadcastChannel('music');
	channl.id = createId(name);
	channl.listeners = new Set()
	sendMas('嘿', channl);
	window.addEventListener('unload', () => {
		sendMas('哦豁', channl);
	})
	channl.addEventListener('message', (e) => {
            if (e.data.msg == '嘿') {
                sendMas('哈', channl);
                channl.listeners.add(e.data.id)
            }
            if (e.data.msg == '哈') {
                channl.listeners.add(e.data.id)
            }
            if (e.data.msg == '哦豁') {
                // 页面离开清空
                channl.listeners.delete(e.data.id)

            }
	})
	return channl
}