当前位置: 首页 > news >正文

实现Web QQ音乐打开现有新标签页切换音乐

  • 若没有打开播放音乐标签页,则打开新标签页播放所选音乐
  • 如果已打开新标签页,则直接切换所选音乐

pageA.vue

<script setup lang="ts">
const tab2 = ref<any>(null);
const router = useRouter();interface Track {id: number;name: string;url: string;
}
const tracks = reactive<Track[]>([{id: 1,name: "Sample Track 1",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",},{id: 2,name: "Sample Track 2",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3",},{id: 3,name: "Sample Track 3",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3",},{id: 4,name: "Sample Track 4",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-4.mp3",},{id: 5,name: "Sample Track 5",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-5.mp3",},{id: 6,name: "Sample Track 6",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-6.mp3",},{id: 7,name: "Sample Track 7",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-7.mp3",},{id: 8,name: "Sample Track 8",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-8.mp3",},{id: 9,name: "Sample Track 9",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-9.mp3",},{id: 10,name: "Sample Track 10",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-10.mp3",},
]);
const openWindow = (track: Track) => {// 如果标签页 2 已经存在且未关闭if (tab2.value && !tab2.value.closed) {// 激活标签页 2tab2.value.focus();const channel = new BroadcastChannel("myChannel");channel.postMessage(JSON.stringify(track));channel.close();} else {const target = router.resolve({path: "communicationB",query: { isNew: 1, track: JSON.stringify(track) },});// 如果标签页 2 不存在或已经关闭,则打开新的标签页tab2.value = window.open(target.href, "_blank");}
};
</script><template><div class="music-list"><h1>Music Playlist</h1><ul><liv-for="track in tracks":key="track.id"class="track-item"@click="openWindow(track)"><span>{{ track.name }}</span></li></ul></div>
</template><style scoped lang="scss">
.music-list {max-width: 500px;padding: 20px;margin: 0 auto;background: linear-gradient(145deg, #f0f4ff, #cfd9ff);border-radius: 20px;box-shadow:5px 5px 15px rgb(0 0 0 / 10%),-5px -5px 15px rgb(255 255 255 / 70%);
}h1 {margin-bottom: 20px;font-size: 24px;font-weight: bold;color: #333;text-align: center;letter-spacing: 1px;
}ul {padding: 0;list-style-type: none;
}.track-item {display: flex;align-items: center;justify-content: space-between;padding: 15px;margin-bottom: 15px;cursor: pointer;background: #fff;border-radius: 12px;box-shadow:3px 3px 8px rgb(0 0 0 / 10%),-3px -3px 8px rgb(255 255 255 / 70%);transition:transform 0.2s,box-shadow 0.2s;
}.track-item:hover {box-shadow:8px 8px 20px rgb(0 0 0 / 15%),-8px -8px 20px rgb(255 255 255 / 70%);transform: translateY(-5px);
}span {font-size: 18px;font-weight: 500;color: #333;letter-spacing: 0.5px;
}
</style>

pageB.vue

<template><div class="music-list"><h1>Music Playlist</h1><ul><li v-for="track in tracks" :key="track.id" class="track-item"><button:class="{ active: currentTrack?.id === track.id }"@click="playMusic(track)">{{ track.name }}</button></li></ul><!-- 进度条 --><div v-if="currentTrack?.url" class="progress-container relative"><spanv-if="currentTrack.name"class="absolute left-50% transform-translate-x--50% bottom-20px">{{ currentTrack?.name }}</span><span>{{ formatTime(currentTime) }}</span><progress :value="currentTime" :max="duration" /><span>{{ formatTime(duration) }}</span><button class="!w-64px ml-10px" @click="togglePlay">{{ isPlaying ? "Pause" : "Play" }}</button></div><audio ref="audioPlayer" @timeupdate="updateProgress" @ended="onTrackEnd" /></div>
</template><script lang="ts">
import { ref, reactive, onMounted } from "vue";
const channel = ref<any>();interface Track {id: number;name: string;url: string;
}export default {setup() {const tracks = reactive<Track[]>([{id: 1,name: "Sample Track 1",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",},{id: 2,name: "Sample Track 2",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3",},{id: 3,name: "Sample Track 3",url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3",},]);const currentTrack = ref<Track>();const audioPlayer = ref<HTMLAudioElement | null>(null);const currentTime = ref(0); // 当前播放时间const duration = ref(0); // 当前音频时长const isPlaying = ref(false); // 播放状态const playMusic = (track: Track) => {if (audioPlayer.value) {currentTrack.value = track;audioPlayer.value.src = track.url;audioPlayer.value.play();isPlaying.value = true;// 每次播放新音乐时重置进度currentTime.value = 0;console.log(currentTime);duration.value = 0;}};const updateProgress = () => {if (audioPlayer.value) {currentTime.value = audioPlayer.value.currentTime; // 当前时间duration.value = audioPlayer.value.duration || 0; // 总时长}};const onTrackEnd = () => {isPlaying.value = false; // 播放结束时,暂停状态const index = tracks.findIndex((t) => t.id === currentTrack.value!.id);if (currentTrack.value!.url && index < tracks.length - 1) {const track = tracks[index + 1];playMusic(track); // 自动播放下一首} else {currentTrack.value = {id: -1,name: "",url: "",}; // 播放结束}};// 播放或暂停const togglePlay = () => {if (audioPlayer.value) {if (isPlaying.value) {audioPlayer.value.pause();} else {audioPlayer.value.play();}isPlaying.value = !isPlaying.value;}};const onPlay = () => {isPlaying.value = true;if (audioPlayer.value) {audioPlayer.value.play();}};const formatTime = (time: number): string => {const minutes = Math.floor(time / 60);const seconds = Math.floor(time % 60).toString().padStart(2, "0");return `${minutes}:${seconds}`;};onMounted(() => {if (audioPlayer.value) {audioPlayer.value.volume = 0.8; // 设置默认音量}channel.value = new BroadcastChannel("myChannel");channel.value.onmessage = (event: any) => {const data = JSON.parse(event.data);if (data.id !== currentTrack.value?.id) {playMusic(data);}onPlay();};});onMounted(() => {const route = useRoute();const router = useRouter();const { query } = route as any;// 判断是否是新打开的标签页if (query.isNew === "1") {console.log(query);// 清空地址栏参数router.replace({ query: {} });playMusic(JSON.parse(query.track));}});onBeforeUnmount(() => {channel.value.close();});return {tracks,currentTrack,currentTime,duration,playMusic,updateProgress,onTrackEnd,formatTime,audioPlayer,togglePlay,isPlaying,};},
};
</script><style scoped>
.music-list {max-width: 600px;padding: 20px;margin: 0 auto;background-color: #f4f4f4;border-radius: 8px;box-shadow: 0 2px 10px rgb(0 0 0 / 10%);
}h1 {color: #333;text-align: center;
}ul {padding: 0;list-style-type: none;
}.track-item {margin: 10px 0;
}button {width: 100%;padding: 10px;font-size: 16px;color: white;cursor: pointer;background-color: #6200ea;border: none;border-radius: 4px;transition: background-color 0.3s;
}button.active {background-color: #3700b3;
}button:hover {background-color: #5c00d2;
}.progress-container {display: flex;align-items: center;justify-content: space-between;margin-top: 20px;
}progress {flex: 1;height: 6px;margin: 0 10px;appearance: none;background-color: #ddd;
}progress::-webkit-progress-bar {background-color: #ddd;
}progress::-webkit-progress-value {background-color: #6200ea;
}progress::-moz-progress-bar {background-color: #6200ea;
}span {font-size: 14px;color: #333;
}
</style>

相关文章:

实现Web QQ音乐打开现有新标签页切换音乐

若没有打开播放音乐标签页&#xff0c;则打开新标签页播放所选音乐如果已打开新标签页&#xff0c;则直接切换所选音乐 pageA.vue <script setup lang"ts"> const tab2 ref<any>(null); const router useRouter();interface Track {id: number;name: …...

从底层结构开始学习FPGA(15)----时钟结构(通俗版)

目录 0、前言 1、IO Bank和Clock Region(时钟区域)是一个东西吗? 2、时钟输入管脚 3、时钟架构 3.1、全局时钟BUFG 3.2、水平时钟BUFH 3.3、IO时钟BUFIO 3.4、区域时钟BUFR/BUFMR 4、总结 《从底层结构开始学习FPGA》目录与传送门 0、前言 我思来想去,总觉…...

MacOS Sublime Text 解决中乱码

1. 安装Package Control 官方安装指南 手动安装 通过以此点击菜单 Sublime Text > Preferences > Browse Packages 打开Packages目录找到Packages的同级目录Installed Packages下载PackageControl.sublime-package并保存到Installed Packages中在菜单 Sublime Text &g…...

Python画笔案例-084 绘制 3D立方体

1、绘制 3D立方体 通过 python 的turtle 库绘制 3D立方体,如下图: 2、实现代码 绘制 3D立方体,以下为实现代码: import turtle import timeviewfactor = 150 xshift = 0 yshift = 0 zshift = 50...

“八股文”面试:助力、阻力还是空谈?

在当今的IT行业&#xff0c;面试程序员时提及“八股文”已成为一种普遍现象。所谓“八股文”&#xff0c;通常指的是一系列固定的、标准化的面试问题及其解答&#xff0c;这些问题往往涵盖了计算机科学和软件工程的基础知识&#xff0c;以及一些流行的技术框架和算法。然而&…...

如何实现弹出式窗口

文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了Sliver综合示例相关的内容,本章回中将介绍PopupMenuButton组件.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的PopupMenuButton组件位于AppBar右侧,通常显示三个圆点图标,点击该图标…...

Lua 函数

Lua 函数 Lua 是一种轻量级的编程语言&#xff0c;广泛用于游戏开发、脚本编写和其他应用程序中。在 Lua 中&#xff0c;函数是一等公民&#xff0c;这意味着它们可以被存储在变量中&#xff0c;作为参数传递给其他函数&#xff0c;以及作为其他函数的返回值。本文将详细介绍 …...

HTML_文本标签

概念&#xff1a; 1、用于包裹&#xff1a;词汇、短语等。 2、通常写在排版标签里面。 3、排版标签更宏观(大段的文字)&#xff0c;文本标签更微观(词汇、短语)。 4、文本标签通常都是行内元素。 常用的文本标签 标签名 全称 标签语义em Emphasized 加重(文本)。要着重阅…...

基于SpringBoot+Vue+uniapp的诗词学习系统的详细设计和实现(源码+lw+部署文档+讲解等)

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…...

健康睡眠的重要性

在快节奏的现代生活中&#xff0c;健康养生已成为人们日益关注的话题&#xff0c;而睡眠&#xff0c;这一看似平凡却至关重要的生理需求&#xff0c;往往被忽视在忙碌的缝隙中。今天&#xff0c;让我们深入探讨健康养生中的睡眠艺术&#xff0c;它不仅关乎身体的休息与恢复&…...

知道ip地址怎么看网络地址

在计算机网络的世界里&#xff0c;IP地址是设备之间通信的基础。然而&#xff0c;仅仅知道一个设备的IP地址并不足以完全理解它在网络中的位置和作用。网络地址&#xff0c;作为IP地址的一个重要组成部分&#xff0c;为我们提供了关于设备所属网络的更多信息。本文将深入探讨如…...

精心整理85道Java微服务面试题(含答案)

微服务 面试题 1、您对微服务有何了解&#xff1f; 2、微服务架构有哪些优势&#xff1f; 3。微服务有哪些特点&#xff1f; 4、设计微服务的最佳实践是什么&#xff1f; 5、微服务架构如何运作&#xff1f; 6、微服务架构的优缺点是什么&#xff1f; 7、单片&#xff0…...

MongoDB聚合管道(Aggregation Pipeline)

聚合管道&#xff08;Aggregation Pipeline&#xff09;是MongoDB中用于对数据进行处理和分析的一种强大机制。它由一系列的阶段&#xff08;Stage&#xff09;组成&#xff0c;每个阶段对输入的数据进行一种特定的操作&#xff0c;然后将结果传递给下一个阶段&#xff0c;就像…...

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——6.vector(无习题)

C 中的 vector 容器详细总结 1. 什么是 vector&#xff1f; vector 是 C 标准模板库 (STL) 中的一种动态数组容器。它的底层实现是一个可以自动扩展的数组&#xff0c;支持随机访问和动态调整大小&#xff0c;是 C 中最常用的序列容器之一。vector 在插入、删除、遍历以及随机…...

SpringBoot技术支持的桂林景点导航

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…...

利用vmware在移动硬盘安装Ubuntu2go

安装 买个移动硬盘&#xff0c;usb插电脑&#xff0c;磁盘管理看磁盘序列号 vmware新建虚拟机 这一步选择磁盘管理里面看到的磁盘4 先不要开机&#xff0c;选择设置里面UEFI 和安装正常Ubuntu一致操作即可&#xff0c;这里可以不选高级&#xff0c;默认一个引导分区&…...

Spring Boot:中小型医院网站的敏捷开发

摘 要 本基于Spring Boot的中小型医院网站设计目标是实现用户网络预约挂号的功能&#xff0c;同时提高医院管理效率&#xff0c;更好的为广大用户服务。 本文重点阐述了中小型医院网站的开发过程&#xff0c;以实际运用为开发背景&#xff0c;基于Spring Boot框架&#xff0c;运…...

241011-在jupyter中实现文件夹压缩后下载

241011-在jupyter中实现文件夹压缩后下载 在使用jupyter notebook过程中&#xff0c;我们经常会遇到成堆的文件无法批量下载的问题&#xff0c;这里提供压缩文件夹代码&#xff0c;压缩后即可右键文件选择download实现批量下载 import zipfile import os# 设置你想要压缩的文…...

.NET 一款用于转储指定进程内存的工具

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…...

Splunk 修补关键漏洞,包括远程代码执行漏洞

领先的数据分析和安全监控平台 Splunk 发布了一系列安全更新&#xff0c;以解决 Splunk Enterprise 和 Splunk Cloud Platform 中的多个漏洞。这些漏洞的严重程度不一&#xff0c;有些可实现远程代码执行&#xff08;RCE&#xff09;&#xff0c;有些则允许低权限用户访问敏感信…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

数据挖掘是什么?数据挖掘技术有哪些?

目录 一、数据挖掘是什么 二、常见的数据挖掘技术 1. 关联规则挖掘 2. 分类算法 3. 聚类分析 4. 回归分析 三、数据挖掘的应用领域 1. 商业领域 2. 医疗领域 3. 金融领域 4. 其他领域 四、数据挖掘面临的挑战和未来趋势 1. 面临的挑战 2. 未来趋势 五、总结 数据…...

Cursor AI 账号纯净度维护与高效注册指南

Cursor AI 账号纯净度维护与高效注册指南&#xff1a;解决限制问题的实战方案 风车无限免费邮箱系统网页端使用说明|快速获取邮箱|cursor|windsurf|augment 问题背景 在成功解决 Cursor 环境配置问题后&#xff0c;许多开发者仍面临账号纯净度不足导致的限制问题。无论使用 16…...

智警杯备赛--excel模块

数据透视与图表制作 创建步骤 创建 1.在Excel的插入或者数据标签页下找到数据透视表的按钮 2.将数据放进“请选择单元格区域“中&#xff0c;点击确定 这是最终结果&#xff0c;但是由于环境启不了&#xff0c;这里用的是自己的excel&#xff0c;真实的环境中的excel根据实训…...