切换歌词滚动错误的bug(vue音乐项目)

238 阅读1分钟

1.第一次歌词滚动正常

image.png

2.当切换歌曲时就会发生歌词在上一首歌词的进度和当前的来回跳动

3.经过分析

  1. 是因为当我们正常播放时,然后切换歌曲
  2. 这时请求歌词时没有去停止以前的歌词,以及清除以前的歌词
  3. 因为只停止以前的歌词播放是不行的
  4. 因为当切换歌曲时,虽然在歌词没有加载出来不会播放歌词
  5. 但是我们在因为准备好时也会执行播放歌词的方法
  6. 所以只停止歌词,他还会再次开始开始以前的歌词播放
  // 监听歌曲变化
  watch(currentSong, async (newSong) => {
    if (!newSong.url || !newSong.id) {
      return
    }

    stopLyric()
    currentLyric.value = null

    // 请求歌词
    const lyric = await getLyric(newSong)
    store.commit('addSongLyric', {
      song: newSong,
      lyric
    })
    // 1. 这个判断是为了解决, currentSong是响应式的,歌曲切换了,可是请求的歌曲还是上一首歌
    // 2. 这里的判断是为了,如果a歌曲切换b歌曲,b又切换C,歌词获取是异步的,需要时间
    // 3. 所以在a切换b的这一次的操作后面就不需要再去执行了
    if (currentSong.value.lyric !== lyric) {
      return
    }
    // 解析歌词
    currentLyric.value = new Lyric(lyric, handleLyric)
    // 歌曲准备好
    if (songReady.value) {
      playLyric()
    }
  })

  function playLyric () {
    const currentLyricVal = currentLyric.value
    if (currentLyricVal) {
      currentLyricVal.seek(currentTime.value * 1000)
    }
  }

  function stopLyric () {
    const currentLyricVal = currentLyric.value
    if (currentLyricVal) {
      currentLyricVal.stop()
    }
  }

  // 每行歌词都会执行handleLyric函数
  function handleLyric ({ lineNum }) {
    currentLineNum.value = lineNum
    const scrollComp = lyricScrollRef.value
    const listEl = lyricListRef.value
    if (!listEl) {
      return
    }
    if (lineNum > 5) {
      const lineEl = listEl.children[lineNum - 5]
      scrollComp.scroll.scrollToElement(lineEl, 1000)
    } else {
      scrollComp.scroll.scrollTo(0, 0, 1000)
    }
  }