原生JS实现音乐播放器的示例代码


Posted in Javascript onFebruary 25, 2021

本文主要介绍了原生JS实现音乐播放器的示例代码,分享给大家,具体如下:

效果图

原生JS实现音乐播放器的示例代码

音乐播放器

  • 播放控制
  • 播放进度条控制
  • 歌词显示及高亮
  • 播放模式设置

播放器属性归类

按照播放器的功能划分,对播放器的属性和DOM元素归类,实现同一功能的元素和属性保存在同一对象中,便于管理和操作

const control = { //存放播放器控制
  play: document.querySelector('#myplay'),
 ...
  index: 2,//当前播放歌曲序号
 ...
}

const audioFile = { //存放歌曲文件及相关信息
  file: document.getElementsByTagName('audio')[0],
  currentTime: 0,
  duration: 0,
}

const lyric = { // 歌词显示栏配置
  ele: null,
  totalLyricRows: 0,
  currentRows: 0,
  rowsHeight: 0,
}

const modeControl = { //播放模式
  mode: ['顺序', '随机', '单曲'],
  index: 0
}

const songInfo = { // 存放歌曲信息的DOM容器
  name: document.querySelector('.song-name'),
 ...
}

播放控制

功能:控制音乐的播放和暂停,上一首,下一首,播放完成及相应图标修改
audio所用API:audio.play() 和 audio.pause()和audio ended事件

// 音乐的播放和暂停,上一首,下一首控制
control.play.addEventListener('click',()=>{
  control.isPlay = !control.isPlay;
  playerHandle();
} );
control.prev.addEventListener('click', prevHandle);
control.next.addEventListener('click', nextHandle);
audioFile.file.addEventListener('ended', nextHandle);

function playerHandle() {
  const play = control.play;
  control.isPlay ? audioFile.file.play() : audioFile.file.pause();
  if (control.isPlay) {
 //音乐播放,更改图标及开启播放动画
    play.classList.remove('songStop');
    play.classList.add('songStart');
    control.albumCover.classList.add('albumRotate');
    control.albumCover.style.animationPlayState = 'running';
  } else {
    //音乐暂停,更改图标及暂停播放动画
 ...
  }
}


function prevHandle() {  // 根据播放模式重新加载歌曲
  const modeIndex = modeControl.index;
  const songListLens = songList.length;
  if (modeIndex == 0) {//顺序播放
    let index = --control.index;
    index == -1 ? (index = songListLens - 1) : index;
    control.index = index % songListLens;
  } else if (modeIndex == 1) {//随机播放
    const randomNum = Math.random() * (songListLens - 1);
    control.index = Math.round(randomNum);
  } else if (modeIndex == 2) {//单曲
  }
  reload(songList);
}

function nextHandle() {
  const modeIndex = modeControl.index;
  const songListLens = songList.length;
  if (modeIndex == 0) {//顺序播放
    control.index = ++control.index % songListLens;
  } else if (modeIndex == 1) {//随机播放
    const randomNum = Math.random() * (songListLens - 1);
    control.index = Math.round(randomNum);
  } else if (modeIndex == 2) {//单曲
  }
  reload(songList);
}

播放进度条控制

功能:实时更新播放进度,点击进度条调整歌曲播放进度
audio所用API:audio timeupdate事件,audio.currentTime

// 播放进度实时更新
audioFile.file.addEventListener('timeupdate', lyricAndProgressMove);
// 通过拖拽调整进度
control.progressDot.addEventListener('click', adjustProgressByDrag);
// 通过点击调整进度
control.progressWrap.addEventListener('click', adjustProgressByClick);

播放进度实时更新:通过修改相应DOM元素的位置或者宽度进行修改

function lyricAndProgressMove() {
  const audio = audioFile.file;
  const controlIndex = control.index;
 // 歌曲信息初始化
  const songLyricItem = document.getElementsByClassName('song-lyric-item');
  if (songLyricItem.length == 0) return;
  let currentTime = audioFile.currentTime = Math.round(audio.currentTime);
  let duration = audioFile.duration = Math.round(audio.duration);

  //进度条移动
  const progressWrapWidth = control.progressWrap.offsetWidth;
  const currentBarPOS = currentTime / duration * 100;
  control.progressBar.style.width = `${currentBarPOS.toFixed(2)}%`;
  const currentDotPOS = Math.round(currentTime / duration * progressWrapWidth);
  control.progressDot.style.left = `${currentDotPOS}px`;

  songInfo.currentTimeSpan.innerText = formatTime(currentTime);

}

拖拽调整进度:通过拖拽移动进度条,并且同步更新歌曲播放进度

function adjustProgressByDrag() {
  const fragBox = control.progressDot;
  const progressWrap = control.progressWrap
  drag(fragBox, progressWrap)
}

function drag(fragBox, wrap) {
  const wrapWidth = wrap.offsetWidth;
  const wrapLeft = getOffsetLeft(wrap);

  function dragMove(e) {
    let disX = e.pageX - wrapLeft;
    changeProgressBarPos(disX, wrapWidth)
  }
  fragBox.addEventListener('mousedown', () => { //拖拽操作
    //点击放大方便操作
    fragBox.style.width = `14px`;fragBox.style.height = `14px`;fragBox.style.top = `-7px`;
    document.addEventListener('mousemove', dragMove);
    document.addEventListener('mouseup', () => {
      document.removeEventListener('mousemove', dragMove);
      fragBox.style.width = `10px`;fragBox.style.height = `10px`;fragBox.style.top = `-4px`;
    })
  });
}

function changeProgressBarPos(disX, wrapWidth) { //进度条状态更新
  const audio = audioFile.file
  const duration = audioFile.duration
  let dotPos
  let barPos

  if (disX < 0) {
    dotPos = -4
    barPos = 0
    audio.currentTime = 0
  } else if (disX > 0 && disX < wrapWidth) {
    dotPos = disX
    barPos = 100 * (disX / wrapWidth)
    audio.currentTime = duration * (disX / wrapWidth)
  } else {
    dotPos = wrapWidth - 4
    barPos = 100
    audio.currentTime = duration
  }
  control.progressDot.style.left = `${dotPos}px`
  control.progressBar.style.width = `${barPos}%`
}

点击进度条调整:通过点击进度条,并且同步更新歌曲播放进度

function adjustProgressByClick(e) {

  const wrap = control.progressWrap;
  const wrapWidth = wrap.offsetWidth;
  const wrapLeft = getOffsetLeft(wrap);
  const disX = e.pageX - wrapLeft;
  changeProgressBarPos(disX, wrapWidth)
}

歌词显示及高亮

功能:根据播放进度,实时更新歌词显示,并高亮当前歌词(通过添加样式)
audio所用API:audio timeupdate事件,audio.currentTime

// 歌词显示实时更新
audioFile.file.addEventListener('timeupdate', lyricAndProgressMove);

function lyricAndProgressMove() {
  const audio = audioFile.file;
  const controlIndex = control.index;

  const songLyricItem = document.getElementsByClassName('song-lyric-item');
  if (songLyricItem.length == 0) return;
  let currentTime = audioFile.currentTime = Math.round(audio.currentTime);
  let duration = audioFile.duration = Math.round(audio.duration);
  let totalLyricRows = lyric.totalLyricRows = songLyricItem.length;
  let LyricEle = lyric.ele = songLyricItem[0];
  let rowsHeight = lyric.rowsHeight = LyricEle && LyricEle.offsetHeight;
  //歌词移动
  lrcs[controlIndex].lyric.forEach((item, index) => {
    if (currentTime === item.time) {
      lyric.currentRows = index;
      songLyricItem[index].classList.add('song-lyric-item-active');
      index > 0 && songLyricItem[index - 1].classList.remove('song-lyric-item-active');
      if (index > 5 && index < totalLyricRows - 5) {
        songInfo.lyricWrap.scrollTo(0, `${rowsHeight * (index - 5)}`)
      }

    }
  })
}

播放模式设置

功能:点击跳转播放模式,并修改相应图标
audio所用API:无

// 播放模式设置
control.mode.addEventListener('click', changePlayMode);

function changePlayMode() {
  modeControl.index = ++modeControl.index % 3;
  const mode = control.mode;
  modeControl.index === 0 ?
    mode.setAttribute("class", "playerIcon songCycleOrder") :
    modeControl.index === 1 ?
      mode.setAttribute("class", "playerIcon songCycleRandom ") :
      mode.setAttribute("class", "playerIcon songCycleOnly")
}

项目预览

代码地址:https://github.com/hcm083214/audio-player

到此这篇关于原生JS实现音乐播放器的示例代码的文章就介绍到这了,更多相关JS 音乐播放器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript 支持链式调用的异步调用框架Async.Operation
Aug 04 Javascript
Extjs中常用表单介绍与应用
Jun 07 Javascript
jQuery通过点击行来删除HTML表格行的实现示例
Sep 10 Javascript
javascript实现rgb颜色转换成16进制格式
Jul 10 Javascript
javascript+html5实现绘制圆环的方法
Jul 28 Javascript
基于jquery实现全屏滚动效果
Nov 26 Javascript
基于JS实现回到页面顶部的五种写法(从实现到增强)
Sep 03 Javascript
Vue.js实现模拟微信朋友圈开发demo
Apr 20 Javascript
js循环map 获取所有的key和value的实现代码(json)
May 09 Javascript
JavaScript中var、let、const区别浅析
Jun 24 Javascript
vue初始化动画加载的实例
Sep 01 Javascript
Javascript删除数组里的某个元素
Feb 28 Javascript
详解vite2.0配置学习(typescript版本)
Feb 25 #Javascript
详解vite+ts快速搭建vue3项目以及介绍相关特性
Feb 25 #Vue.js
利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化)
Feb 24 #Javascript
Nest.js散列与加密实例详解
Feb 24 #Javascript
JS canvas实现画板和签字板功能
Feb 23 #Javascript
基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能
Feb 23 #Vue.js
js实现验证码干扰(动态)
Feb 23 #Javascript
You might like
PHP从零开始打造自己的MVC框架之路由类实现方法分析
2019/06/03 PHP
禁止直接访问php文件代码分享
2020/05/05 PHP
延时重复执行函数 lLoopRun.js
2007/05/08 Javascript
js跟随滚动条滚动浮动代码
2009/12/31 Javascript
Jquery下判断Id是否存在的代码
2011/01/06 Javascript
jQuery Tools tab(幻灯片)
2012/07/14 Javascript
JS 实现导航栏悬停效果
2013/09/23 Javascript
javascipt匹配单行和多行注释的正则表达式
2013/11/20 Javascript
JS长整型精度问题实例分析
2015/01/13 Javascript
JavaScript检测鼠标移动方向的方法
2015/05/22 Javascript
总结JavaScript中布尔操作符||与&amp;&amp;的使用技巧
2015/11/17 Javascript
轻松掌握JavaScript中的Math object数学对象
2016/05/26 Javascript
使用jQuery调用XML实现无刷新即时聊天
2016/08/07 Javascript
nodejs基础应用
2017/02/03 NodeJs
jQuery使用DataTable实现删除数据后重新加载功能
2017/02/27 Javascript
nodejs搭建本地服务器并访问文件的方法
2017/03/03 NodeJs
详解nodejs中的process进程
2017/03/19 NodeJs
jQuery插件HighCharts绘制简单2D柱状图效果示例【附demo源码】
2017/03/21 jQuery
利用JavaScript的%做隔行换色的实例
2017/11/25 Javascript
Vue实现点击时间获取时间段查询功能
2020/08/21 Javascript
VUE安装使用教程详解
2019/06/03 Javascript
Vuex的实战使用详解
2019/10/31 Javascript
jQuery实现异步上传一个或多个文件
2020/08/17 jQuery
vue实现几秒后跳转新页面代码
2020/09/09 Javascript
python实现移位加密和解密
2019/03/22 Python
pytorch 更改预训练模型网络结构的方法
2019/08/19 Python
Python devel安装失败问题解决方案
2020/06/09 Python
Python3实现建造者模式的示例代码
2020/06/28 Python
用html5实现语音搜索框的方法
2014/03/18 HTML / CSS
应届生求职信写作技巧
2013/10/24 职场文书
经管应届生求职信
2013/11/17 职场文书
乔迁宴答谢词
2014/01/21 职场文书
致200米运动员广播稿
2014/02/06 职场文书
学校食堂标语
2014/10/06 职场文书
高中生个性发展自我评价
2015/03/09 职场文书
2016年第十四个公民道德宣传日活动总
2016/04/01 职场文书