当前位置: 首页 > 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;有些则允许低权限用户访问敏感信…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...