当前位置:首页 > JavaScript

js如何实现歌词

2026-02-02 16:45:05JavaScript

实现歌词滚动的基本思路

歌词滚动功能通常需要同步音频播放时间与歌词显示。核心是将歌词文本按时间轴解析为数组,监听音频播放进度并匹配对应歌词行。

歌词数据格式处理

常见歌词格式为LRC,每行包含时间标签和文本。解析示例:

js如何实现歌词

const lrcText = `[00:01.00]这是第一行歌词
[00:03.50]这是第二行歌词`;

function parseLRC(text) {
  const lines = text.split('\n');
  return lines.map(line => {
    const timeMatch = line.match(/\[(\d{2}):(\d{2})\.(\d{2})\]/);
    if (!timeMatch) return null;
    const min = parseInt(timeMatch[1]);
    const sec = parseInt(timeMatch[2]);
    const ms = parseInt(timeMatch[3]);
    const time = min * 60 + sec + ms / 100;
    const text = line.replace(timeMatch[0], '').trim();
    return { time, text };
  }).filter(Boolean);
}

歌词同步实现

监听音频时间更新并匹配当前歌词:

const audio = document.querySelector('audio');
const lyrics = parseLRC(lrcText);
let currentLine = 0;

audio.addEventListener('timeupdate', () => {
  const currentTime = audio.currentTime;
  while (
    currentLine < lyrics.length - 1 && 
    currentTime >= lyrics[currentLine + 1].time
  ) {
    currentLine++;
  }
  highlightLyric(currentLine);
});

界面渲染与高亮

动态更新DOM显示当前歌词:

js如何实现歌词

function renderLyrics(container) {
  lyrics.forEach((line, index) => {
    const div = document.createElement('div');
    div.className = 'lyric-line';
    div.dataset.index = index;
    div.textContent = line.text;
    container.appendChild(div);
  });
}

function highlightLyric(index) {
  document.querySelectorAll('.lyric-line').forEach(el => {
    el.classList.remove('active');
  });
  const activeLine = document.querySelector(`[data-index="${index}"]`);
  if (activeLine) activeLine.classList.add('active');
}

平滑滚动优化

添加CSS实现平滑滚动效果:

.lyrics-container {
  height: 300px;
  overflow-y: auto;
  scroll-behavior: smooth;
}

.lyric-line {
  padding: 8px;
  transition: all 0.3s;
}

.lyric-line.active {
  color: #ff0000;
  font-size: 1.2em;
}

完整实现示例

结合所有功能的完整示例:

class LyricsPlayer {
  constructor(container, audioElement) {
    this.container = container;
    this.audio = audioElement;
    this.lines = [];
    this.currentLine = 0;
  }

  loadLRC(text) {
    this.lines = parseLRC(text);
    this.render();
  }

  render() {
    this.container.innerHTML = '';
    this.lines.forEach((line, index) => {
      const div = document.createElement('div');
      div.className = 'lyric-line';
      div.dataset.index = index;
      div.textContent = line.text;
      this.container.appendChild(div);
    });

    this.audio.addEventListener('timeupdate', this.update.bind(this));
  }

  update() {
    const currentTime = this.audio.currentTime;
    while (
      this.currentLine < this.lines.length - 1 && 
      currentTime >= this.lines[this.currentLine + 1].time
    ) {
      this.currentLine++;
    }
    this.highlight();
  }

  highlight() {
    const activeElement = this.container.querySelector('.active');
    if (activeElement) activeElement.classList.remove('active');

    const currentElement = this.container.querySelector(
      `[data-index="${this.currentLine}"]`
    );
    if (currentElement) {
      currentElement.classList.add('active');
      currentElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
    }
  }
}

分享给朋友:

相关文章

vue如何实现拖动

vue如何实现拖动

Vue 实现拖动的常用方法 使用 HTML5 原生拖放 API HTML5 提供了原生的拖放 API,可以通过 draggable 属性和相关事件实现拖动功能。 <template>…

vue如何实现加减

vue如何实现加减

在 Vue 中实现加减功能 使用数据绑定和事件处理 通过 Vue 的数据绑定和事件处理机制可以轻松实现加减功能。定义一个数据变量存储数值,通过方法增减该变量。 <template>…

vue如何实现筛选

vue如何实现筛选

在Vue中实现筛选功能 Vue提供了多种方式实现数据筛选,可以根据需求选择合适的方法。以下是几种常见的实现方式: 使用计算属性实现筛选 计算属性是Vue中实现筛选功能的推荐方式,它会自动缓存结果,…

vue如何实现echarts

vue如何实现echarts

Vue 中集成 ECharts 的方法 安装 ECharts 依赖包 通过 npm 或 yarn 安装核心库: npm install echarts --save # 或 yarn add e…

vue如何实现发票

vue如何实现发票

在Vue中实现发票功能通常需要结合前端展示、数据绑定和打印功能。以下是实现发票功能的关键步骤和代码示例: 发票模板设计 使用Vue的模板语法设计发票的HTML结构,结合CSS美化样式。发票模板通常包…

vue如何实现餐桌

vue如何实现餐桌

Vue 实现餐桌功能 数据绑定与状态管理 使用 Vue 的响应式数据特性管理餐桌状态,例如桌号、座位数、是否占用等。通过 data 或 Vuex 存储餐桌信息: data() { return…