最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

原生JS實(shí)現(xiàn)音樂(lè)播放器的示例代碼

 更新時(shí)間:2021年02月25日 10:31:43   作者:?jiǎn)尉€程_01  
這篇文章主要介紹了原生JS實(shí)現(xiàn)音樂(lè)播放器的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

本文主要介紹了原生JS實(shí)現(xiàn)音樂(lè)播放器的示例代碼,分享給大家,具體如下:

效果圖

音樂(lè)播放器

  • 播放控制
  • 播放進(jìn)度條控制
  • 歌詞顯示及高亮
  • 播放模式設(shè)置

播放器屬性歸類

按照播放器的功能劃分,對(duì)播放器的屬性和DOM元素歸類,實(shí)現(xiàn)同一功能的元素和屬性保存在同一對(duì)象中,便于管理和操作

const control = { //存放播放器控制
  play: document.querySelector('#myplay'),
 ...
  index: 2,//當(dāng)前播放歌曲序號(hào)
 ...
}

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

const lyric = { // 歌詞顯示欄配置
  ele: null,
  totalLyricRows: 0,
  currentRows: 0,
  rowsHeight: 0,
}

const modeControl = { //播放模式
  mode: ['順序', '隨機(jī)', '單曲'],
  index: 0
}

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

播放控制

功能:控制音樂(lè)的播放和暫停,上一首,下一首,播放完成及相應(yīng)圖標(biāo)修改
audio所用API:audio.play() 和 audio.pause()和audio ended事件

// 音樂(lè)的播放和暫停,上一首,下一首控制
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) {
 //音樂(lè)播放,更改圖標(biāo)及開(kāi)啟播放動(dòng)畫(huà)
    play.classList.remove('songStop');
    play.classList.add('songStart');
    control.albumCover.classList.add('albumRotate');
    control.albumCover.style.animationPlayState = 'running';
  } else {
    //音樂(lè)暫停,更改圖標(biāo)及暫停播放動(dòng)畫(huà)
 ...
  }
}


function prevHandle() {  // 根據(jù)播放模式重新加載歌曲
  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) {//隨機(jī)播放
    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) {//隨機(jī)播放
    const randomNum = Math.random() * (songListLens - 1);
    control.index = Math.round(randomNum);
  } else if (modeIndex == 2) {//單曲
  }
  reload(songList);
}

播放進(jìn)度條控制

功能:實(shí)時(shí)更新播放進(jìn)度,點(diǎn)擊進(jìn)度條調(diào)整歌曲播放進(jìn)度
audio所用API:audio timeupdate事件,audio.currentTime

// 播放進(jìn)度實(shí)時(shí)更新
audioFile.file.addEventListener('timeupdate', lyricAndProgressMove);
// 通過(guò)拖拽調(diào)整進(jìn)度
control.progressDot.addEventListener('click', adjustProgressByDrag);
// 通過(guò)點(diǎn)擊調(diào)整進(jìn)度
control.progressWrap.addEventListener('click', adjustProgressByClick);

播放進(jìn)度實(shí)時(shí)更新:通過(guò)修改相應(yīng)DOM元素的位置或者寬度進(jìn)行修改

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);

  //進(jìn)度條移動(dòng)
  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);

}

拖拽調(diào)整進(jìn)度:通過(guò)拖拽移動(dòng)進(jìn)度條,并且同步更新歌曲播放進(jìn)度

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', () => { //拖拽操作
    //點(diǎn)擊放大方便操作
    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) { //進(jìn)度條狀態(tài)更新
  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}%`
}

點(diǎn)擊進(jìn)度條調(diào)整:通過(guò)點(diǎn)擊進(jìn)度條,并且同步更新歌曲播放進(jìn)度

function adjustProgressByClick(e) {

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

歌詞顯示及高亮

功能:根據(jù)播放進(jìn)度,實(shí)時(shí)更新歌詞顯示,并高亮當(dāng)前歌詞(通過(guò)添加樣式)
audio所用API:audio timeupdate事件,audio.currentTime

// 歌詞顯示實(shí)時(shí)更新
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;
  //歌詞移動(dòng)
  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)}`)
      }

    }
  })
}

播放模式設(shè)置

功能:點(diǎn)擊跳轉(zhuǎn)播放模式,并修改相應(yīng)圖標(biāo)
audio所用API:無(wú)

// 播放模式設(shè)置
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")
}

項(xiàng)目預(yù)覽

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

到此這篇關(guān)于原生JS實(shí)現(xiàn)音樂(lè)播放器的示例代碼的文章就介紹到這了,更多相關(guān)JS 音樂(lè)播放器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js實(shí)現(xiàn)base64文件的處理以及下載方法

    js實(shí)現(xiàn)base64文件的處理以及下載方法

    Base64是一種將二進(jìn)制數(shù)據(jù)編碼為ASCII字符的編碼方式,這篇文章主要給大家介紹了關(guān)于js實(shí)現(xiàn)base64文件的處理以及下載的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • 多瀏覽器兼容的動(dòng)態(tài)加載 JavaScript 與 CSS

    多瀏覽器兼容的動(dòng)態(tài)加載 JavaScript 與 CSS

    Omar AL Zabir這位MVP總是喜歡搞些稀奇古怪同時(shí)又很實(shí)用的小東西,并且還十分值得參考。最近他就做了一個(gè)叫做ensure的小工具用于動(dòng)態(tài)加載JavaScript、CSS與HTML,而且IE、Firefox、Opera、Safari都支持了,那么我們就來(lái)看看ensure是如何做到動(dòng)態(tài)加載JavaScript與CSS的。
    2008-09-09
  • js 學(xué)習(xí)筆記(三)

    js 學(xué)習(xí)筆記(三)

    JavaScript的對(duì)象基礎(chǔ) 本篇主要講解本地對(duì)象Array的各種方法。
    2009-12-12
  • JavaScript中AOP的實(shí)現(xiàn)與應(yīng)用

    JavaScript中AOP的實(shí)現(xiàn)與應(yīng)用

    這篇文章主要給大家介紹了關(guān)于JavaScript中AOP的實(shí)現(xiàn)與應(yīng)用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用JavaScript具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 淺析JavaScript 函數(shù)柯里化

    淺析JavaScript 函數(shù)柯里化

    這篇文章主要介紹了JavaScript 函數(shù)柯里化的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)JavaScript,感興趣的朋友可以了解下
    2020-09-09
  • JavaScript復(fù)制變量三種方法實(shí)例詳解

    JavaScript復(fù)制變量三種方法實(shí)例詳解

    這篇文章主要介紹了JavaScript復(fù)制變量三種方法實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Bootbox將后臺(tái)JSON數(shù)據(jù)填充Form表單的實(shí)例代碼

    Bootbox將后臺(tái)JSON數(shù)據(jù)填充Form表單的實(shí)例代碼

    通過(guò)控制器創(chuàng)建一個(gè)Index視圖,寫(xiě)入下列HTML代碼,這里我創(chuàng)建了一個(gè)分部視圖,不創(chuàng)建直接寫(xiě)在同一個(gè)頁(yè)面也是一樣的效果。這篇文章主要介紹了Bootbox將后臺(tái)JSON數(shù)據(jù)填充Form表單 ,需要的朋友可以參考下
    2018-09-09
  • js使用遞歸解析xml

    js使用遞歸解析xml

    這篇文章主要介紹了js使用遞歸解析xml,需要的朋友可以參考下
    2014-12-12
  • 如何檢測(cè)JavaScript的各種類型

    如何檢測(cè)JavaScript的各種類型

    在寫(xiě)js腳本的時(shí)候我們必須對(duì)一件事保持警惕,就是避免異常的發(fā)生。在本篇文章里面,我想談?wù)勔徊糠诸愋蜋z測(cè),有需要的可以參考學(xué)習(xí)。
    2016-07-07
  • javascript 去字符串空格終極版(支持utf8)

    javascript 去字符串空格終極版(支持utf8)

    其實(shí)空格有兩個(gè),一個(gè)ASCII編號(hào)是32,另一個(gè)是ASCII編號(hào)是160.后者是unicode編碼。以前寫(xiě)一個(gè)貼子ie6下準(zhǔn)確判斷空格還以是IE6不能正確判斷空格。
    2009-11-11

最新評(píng)論

南宁市| 温州市| 老河口市| 青州市| 昔阳县| 开原市| 城固县| 石首市| 铜梁县| 巫山县| 临清市| 泌阳县| 稷山县| 鄯善县| 拉萨市| 敦化市| 南和县| 稷山县| 黄龙县| 高青县| 阿拉善左旗| 金门县| 永修县| 英吉沙县| 改则县| 榆社县| 阿坝县| 台北县| 从化市| 策勒县| 高雄市| 莲花县| 孟村| 呈贡县| 剑阁县| 乡宁县| 讷河市| 宁阳县| 丰县| 呼伦贝尔市| 广丰县|