使用J*aScript构建功能完善的音乐播放器


使用JavaScript构建功能完善的音乐播放器

本教程详细介绍了如何使用j*ascript、html和css构建一个功能完善的网页音乐播放器。文章将从html结构、核心j*ascript逻辑、音乐列表管理、播放控制、进度与音量调节等方面进行深入讲解,并提供完整的示例代码。同时,我们也将探讨并解决在开发过程中可能遇到的常见错误,例如typeerror: cannot read properties of undefined (reading 'contains'),旨在帮助开发者构建稳定且用户体验良好的音乐播放功能。

在现代Web应用中,集成音频播放功能已成为一种常见需求。本教程将引导您从零开始,使用纯J*aScript构建一个功能丰富、交互性强的音乐播放器。我们将涵盖播放/暂停、上一曲/下一曲、音量控制、播放进度显示以及动态加载音乐列表等核心功能。

1. HTML 结构:构建播放器用户界面

音乐播放器的用户界面由一系列HTML元素组成,用于显示歌曲信息、控制按钮和进度条。以下是建议的HTML结构:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web 音乐播放器</title>
    <!-- 引入 Font Awesome 图标库 -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css">
    <!-- 引入自定义样式文件 -->
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <div class="player">
        <!-- 歌曲详情区域 -->
        <div class="details">
            <div class="now-playing">正在播放 x / y</div>
            <div class="track-art"></div> <!-- 歌曲封面 -->
            <div class="track-name">歌曲名称</div>
            <div class="track-artist">艺术家</div>
        </div>

        <!-- 控制按钮区域 -->
        <div class="buttons">
            <div class="prev-track" onclick="prevTrack()"><i class="fa fa-step-backward fa-2x"></i></div>
            <div class="playpause-track" onclick="playpauseTrack()"><i class="fa fa-play-circle fa-5x"></i></div>
            <div class="next-track" onclick="nextTrack()"><i class="fa fa-step-forward fa-2x"></i></div>
        </div>

        <!-- 进度条区域 -->
        <div class="slider_container">
            <div class="current-time">00:00</div>
            <input type="range" min="1" max="100" value="0" class="seek_slider" onchange="seekTo()">
            <div class="total-duration">00:00</div>
        </div>

        <!-- 音量控制区域 -->
        <div class="slider_container">
            <i class="fa fa-volume-down"></i>
            <input type="range" min="1" max="100" value="99" class="volume_slider" onchange="setVolume()">
            <i class="fa fa-volume-up"></i>
        </div>
    </div>

    <!-- 引入 J*aScript 文件 -->
    <script src="script.js"></script>
</body>
</html>

HTML 结构说明:

  • .player: 整个播放器的容器。
  • .details: 用于显示歌曲封面、名称和艺术家信息。
  • .buttons: 包含上一曲、播放/暂停、下一曲的控制按钮。onclick 属性直接绑定了 J*aScript 函数,简化了事件处理。
  • .slider_container: 分别用于播放进度和音量控制,内部包含一个 input 类型为 range 的滑块和时间/音量图标。

2. CSS 样式:美化播放器界面

为了让播放器具有良好的视觉效果,我们需要编写相应的CSS样式。虽然本教程的重点是J*aScript逻辑,但一个基础的style.css文件是必不可少的。您可以根据个人喜好进行设计,以下是一些关键元素的样式建议:

立即学习“J*a免费学习笔记(深入)”;

/* style.css */
body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
    font-family: Arial, sans-serif;
    background: linear-gradient(135deg, #f06, #f90); /* 示例背景 */
    transition: background-color 0.5s ease; /* 背景颜色过渡 */
}

.player {
    background-color: #fff;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
    text-align: center;
    width: 300px;
}

.details .track-art {
    width: 150px;
    height: 150px;
    background-size: cover;
    background-position: center;
    border-radius: 50%;
    margin: 20px auto;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}

.details .track-name {
    font-size: 1.5em;
    font-weight: bold;
    margin-bottom: 5px;
}

.details .track-artist {
    font-size: 1em;
    color: #555;
    margin-bottom: 20px;
}

.buttons div {
    display: inline-block;
    cursor: pointer;
    margin: 0 15px;
    color: #333;
}

.buttons div:hover {
    color: #007bff;
}

.playpause-track i {
    font-size: 5em; /* 播放/暂停按钮更大 */
}

.slider_container {
    display: flex;
    align-items: center;
    margin: 20px 0;
}

.slider_container .seek_slider,
.slider_container .volume_slider {
    flex-grow: 1;
    margin: 0 10px;
    -webkit-appearance: none;
    height: 5px;
    background: #ddd;
    border-radius: 5px;
    outline: none;
}

/* 滑块样式 (Chrome/Safari) */
.slider_container .seek_slider::-webkit-slider-thumb,
.slider_container .volume_slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 15px;
    height: 15px;
    background: #007bff;
    border-radius: 50%;
    cursor: pointer;
}

.slider_container .current-time,
.slider_container .total-duration {
    font-size: 0.9em;
    color: #666;
}

3. J*aScript 核心逻辑:实现播放器功能

所有播放器的核心功能都将通过J*aScript实现。我们将创建一个 script.js 文件来承载这些逻辑。

3.1 全局变量和DOM元素获取

首先,定义一些全局变量来存储播放状态、当前曲目索引以及获取必要的DOM元素。

// script.js

// 获取DOM元素
let now_playing = document.querySelector(".now-playing");
let track_art = document.querySelector(".track-art");
let track_name = document.querySelector(".track-name");
let track_artist = document.querySelector(".track-artist");

let playpause_btn = document.querySelector(".playpause-track");
let next_btn = document.querySelector(".next-track");
let prev_btn = document.querySelector(".prev-track");

let seek_slider = document.querySelector(".seek_slider");
let volume_slider = document.querySelector(".volume_slider");
let curr_time = document.querySelector(".current-time");
let total_duration = document.querySelector(".total-duration");

// 播放器状态变量
let track_index = 0; // 当前播放曲目索引
let isPlaying = false; // 是否正在播放
let updateTimer; // 用于更新播放进度的计时器

// 创建一个新的 <audio> 元素
let curr_track = document.createElement('audio');

// 定义音乐列表
let track_list = [
  {
    name: "Night Owl",
    artist: "Broke For Free",
    image: "https://images.pexels.com/photos/2264753/pexels-photo-2264753.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250&w=250",
    path: "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/WFMU/Broke_For_Free/Directionless_EP/Broke_For_Free_-_01_-_Night_Owl.mp3"
  },
  {
    name: "Enthusiast",
    artist: "Tours",
    image: "https://images.pexels.com/photos/3100835/pexels-photo-3100835.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250&w=250",
    path: "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Tours/Enthusiast/Tours_-_01_-_Enthusiast.mp3"
  },
  {
    name: "Shipping Lanes",
    artist: "Chad Crouch",
    image: "https://images.pexels.com/photos/1717969/pexels-photo-1717969.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250&w=250",
    path: "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/Chad_Crouch/Arps/Chad_Crouch_-_Shipping_Lanes.mp3",
  },
];

注意事项:

  • 我们动态创建了一个 audio 元素 (curr_track),而不是直接使用HTML中的 标签。这使得管理和切换歌曲更加灵活。
  • track_list 数组存储了所有可播放的歌曲信息,包括名称、艺术家、封面图片URL和音乐文件路径。

3.2 辅助函数:背景颜色和重置UI

为了增强用户体验,我们添加了一个随机背景颜色函数,并在加载新歌曲时重置播放器UI状态。

Jaaz Jaaz

开源的AI设计智能体

Jaaz 216 查看详情 Jaaz
// 随机背景颜色
function random_bg_color() {
  let red = Math.floor(Math.random() * 256) + 64;
  let green = Math.floor(Math.random() * 256) + 64;
  let blue = Math.floor(Math.random() * 256) + 64;
  let bgColor = "rgb(" + red + "," + green + "," + blue + ")";
  document.body.style.background = bgColor;
}

// 重置播放器UI状态
function resetValues() {
  curr_time.textContent = "00:00";
  total_duration.textContent = "00:00";
  seek_slider.value = 0;
}

3.3 加载音乐轨道 (loadTrack)

loadTrack 函数负责加载指定索引的歌曲,并更新播放器UI。

function loadTrack(track_index) {
  clearInterval(updateTimer); // 清除旧的进度更新计时器
  resetValues(); // 重置UI显示

  curr_track.src = track_list[track_index].path; // 设置音频源
  curr_track.load(); // 加载音频

  track_art.style.backgroundImage = "url(" + track_list[track_index].image + ")"; // 更新封面
  track_name.textContent = track_list[track_index].name; // 更新歌曲名称
  track_artist.textContent = track_list[track_index].artist; // 更新艺术家
  now_playing.textContent = "正在播放 " + (track_index + 1) + " / " + track_list.length; // 更新当前播放信息

  updateTimer = setInterval(seekUpdate, 1000); // 每秒更新播放进度
  curr_track.addEventListener("ended", nextTrack); // 歌曲播放结束后自动播放下一曲
  random_bg_color(); // 更改背景颜色
}

3.4 播放控制功能

这些函数处理播放、暂停、上一曲和下一曲的逻辑。

// 播放/暂停切换
function playpauseTrack() {
  if (!isPlaying) playTrack();
  else pauseTrack();
}

// 播放歌曲
function playTrack() {
  curr_track.play();
  isPlaying = true;
  playpause_btn.innerHTML = '<i class="fa fa-pause-circle fa-5x"></i>'; // 切换为暂停图标
}

// 暂停歌曲
function pauseTrack() {
  curr_track.pause();
  isPlaying = false;
  playpause_btn.innerHTML = '<i class="fa fa-play-circle fa-5x"></i>'; // 切换为播放图标
}

// 播放下一曲
function nextTrack() {
  if (track_index < track_list.length - 1)
    track_index += 1;
  else track_index = 0; // 循环播放
  loadTrack(track_index);
  playTrack();
}

// 播放上一曲
function prevTrack() {
  if (track_index > 0)
    track_index -= 1;
  else track_index = track_list.length - 1; // 循环播放
  loadTrack(track_index);
  playTrack();
}

3.5 进度和音量控制

这些函数与滑块交互,控制播放进度和音量。

// 跳转到指定播放位置
function seekTo() {
  let seekto = curr_track.duration * (seek_slider.value / 100);
  curr_track.currentTime = seekto;
}

// 设置音量
function setVolume() {
  curr_track.volume = volume_slider.value / 100;
}

// 更新播放进度和时间显示
function seekUpdate() {
  let seekPosition = 0;

  if (!isNaN(curr_track.duration)) {
    seekPosition = curr_track.currentTime * (100 / curr_track.duration);
    seek_slider.value = seekPosition; // 更新进度条滑块位置

    // 计算并格式化当前时间和总时长
    let currentMinutes = Math.floor(curr_track.currentTime / 60);
    let currentSeconds = Math.floor(curr_track.currentTime - currentMinutes * 60);
    let durationMinutes = Math.floor(curr_track.duration / 60);
    let durationSeconds = Math.floor(curr_track.duration - durationMinutes * 60);

    if (currentSeconds < 10) { currentSeconds = "0" + currentSeconds; }
    if (durationSeconds < 10) { durationSeconds = "0" + durationSeconds; }
    if (currentMinutes < 10) { currentMinutes = "0" + currentMinutes; }
    if (durationMinutes < 10) { durationMinutes = "0" + durationMinutes; }

    curr_time.textContent = currentMinutes + ":" + currentSeconds;
    total_duration.textContent = durationMinutes + ":" + durationSeconds;
  }
}

3.6 初始化播放器

最后,在脚本加载时调用 loadTrack 来初始化播放器,加载第一首歌曲。

// 页面加载时加载第一首歌曲
loadTrack(track_index);

4. 常见问题与注意事项

4.1 TypeError: Cannot read properties of undefined (reading 'contains') 解析

在原始问题中,用户遇到了 Uncaught TypeError: Cannot read properties of undefined (reading 'contains') at HTMLElement 错误,这通常是由于以下原因造成的:

  1. document.querySelectorAll() 返回的是 NodeList:document.querySelectorAll('.player') 返回的是一个包含所有匹配元素的 NodeList(类似数组),而不是单个HTML元素。NodeList 没有 classList 属性。要访问单个元素的 classList,你需要指定具体的元素,例如 musicPlayer[0].classList。
  2. classList.contains() 参数错误:classList.contains() 方法期望一个不带前缀点(.)的类名字符串。例如,检查是否存在 play 类,应该使用 classList.contains('play'),而不是 classList.contains('.play')。

本教程的解决方案通过以下方式避免了这个问题:

  • 直接操作 isPlaying 布尔变量来管理播放状态,而不是依赖DOM元素的类名。
  • 使用 document.querySelector() 获取单个元素,确保操作的是正确的DOM对象。

4.2 DOM 操作的最佳实践

  • querySelector vs querySelectorAll: 当您预期只有一个元素时,使用 document.querySelector()。当您需要处理多个元素时,使用 document.querySelectorAll(),并记住它返回一个 NodeList,可能需要迭代处理或访问特定索引的元素。
  • 事件监听: 尽管本示例为了简洁使用了 onclick 属性直接绑定函数,但在更复杂的应用中,推荐使用 element.addEventListener('click', handlerFunction)。addEventListener 提供了更强大的功能,例如可以为同一事件添加多个处理程序,并且更好地分离了HTML和J*aScript。

4.3 资源路径

确保 track_list 中 path 和 image 字段的URL是可访问的。对于本地文件,您需要将音乐文件和图片放置在项目目录中,并提供正确的相对路径。例如,如果您的音乐文件在 music/ 目录下,图片在 images/ 目录下,则路径应为 `"music/Ace of Base -

以上就是使用J*aScript构建功能完善的音乐播放器的详细内容,更多请关注其它相关文章!


# 新城 峯璟 营销推广  # 而不是  # 滑块  # 音量控制  # 正在播放  # 全局变量  # 多个  # 青海酸奶淘宝网站推广  # 五金网站建设造价  # 的是  # 东至网站优化推荐  # 相城网站推广优化  # 宝山爱采购seo  # 南昌推广服务网站  # 眉山移动营销推广招聘  # 项目辨答seo  # 网站优化有几家上市公司  # css  # 加载  # 一曲  # 播放器  # c  # 音乐  # ai  # safari  # ssl  # app  # node  # ajax  # js  # html  # java  # javascript 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 如何查询个人病历记录  C++ switch case字符串_C++如何实现字符串switch匹配  word文档中的分隔符有哪些不同类型和用途_Word分隔符类型与用途方法  Win10显卡驱动安装失败怎么办 Win10使用DDU彻底卸载驱动【解决】  抖音号升级成企业资质怎么弄?有什么好处?  掌握CSS :has() 选择器:父选择器、嵌套限制与常见陷阱解析  PHP动态导航按钮:根据用户登录状态切换链接与文本  支付宝登录刷脸不是本人如何解决  J*aScript深度克隆:实现高效、健壮与安全的复杂对象复制  Flexbox布局:实现粘性导航与底部页脚的完美结合  在Dash应用中自定义HTML标题和网站图标  猫眼app抢票快还是小程序快  LocoySpider如何批量采集电商商品_LocoySpider电商采集的模板应用  J*aScript模拟悬停与点击:自动化网页动态元素交互指南  WPS文字如何进行简繁转换  抖音火山版如何进行提现  《华夏千秋》龙女试炼功法获取方法  Symfony路由参数转换器:实体存在性验证与错误处理策略  Excel宏怎么删除_Excel中删除宏的详细操作流程  word页码灰色不能用如何解决  WooCommerce购物车:强制显示所有交叉销售商品教程  TikTok网页版入口快速访问 TikTok官网账号登录方法  什么是Satis,如何用它搭建一个私有的composer仓库?  三角洲行动2025年9月10日摩斯密码分享  雨课堂官网在线登录 网页版雨课堂登录链接  PHP中实现JSON数据数组分页的教程  顺丰速运官网查询入口 顺丰物流查询官网入口链接  晓晓优选app支付宝绑定方法  《土豆雅思》修改密码方法  抖音号显示企业机构号是什么意思?企业机构号申请条件是什么?  GBA模拟器手柄按键设置  抖音手机分身两个账号怎么切换?分身两个系统是一样的吗?  小红书如何引流到私信?引流到私信有用吗?  植物大战僵尸95版游戏版下载_植物大战僵尸95版游戏版安装指南  WooCommerce 新客户订单自动添加管理员备注教程  键盘测试软件哪个好_键盘故障检测工具推荐  实时数据流中高效查找最小值与最大值  C++ priority_queue怎么用_C++优先队列底层实现与自定义比较器  OPPO A3 WiFi频繁断开怎么办 OPPO A3网络优化技巧  Safari浏览器自动填表功能失效怎么办 Safari表单管理修复  谷歌浏览器怎么把网页翻译成中文_Chrome网页翻译功能使用方法  汽水音乐在线入口 汽水音乐网页端官方页面快速打开  t3出行如何使用微信支付  使用 J*aScript 随机化 CSS Grid 布局中的元素顺序  如何快速去除厨房重油污? 2025年最好用的厨房清洁剂推荐  免费占卜在线神算_免费占卜手机神算  金牛福袋获取攻略  《七读免费小说》开通会员方法  Win10截图远程协助 Win10远程桌面截屏法【场景应用】  如何用mysql开发用户注册登录功能_mysql用户注册登录数据库设计 

 2025-11-16

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.