JavaScript 实现微信风格语音播放器的核心逻辑

作者:闭包旅人时间:2026-10-30 18:34:34浏览:397

本文详细解析了使用 JavaScript 实现仿微信语音播放器的核心思路。重点涵盖未读红点状态管理、音频播放完毕自动播放下一段、暂停与重播逻辑切换以及 CSS3 动画效果的应用。通过 HTML5 Audio 事件监听与 DOM 操作,实现流畅的语音交互体验。

近期观察到一款名为“轻客小伙伴”的微信服务号运营状况良好。该账号专注于英语在线培训,由教师录制语音课程,并配合图文内容呈现。

HTML 结构布局

HTML 结构布局

虽然完成了大部分功能的开发,但尚未将其封装为通用插件。直接展示完整代码可能因缺乏上下文而难以理解,因此本文主要阐述其实现思路。具体的 HTML 结构如下所示。


<div class="app-voice-you" voiceSrc="xx.mp3">
<img class="app-voice-headimg" src="xx.png" />
<div style="width: 60%;" class="app-voice-state-bg">
<div class="app-voice-state app-voice-pause"></div>
</div>
<div class="app-voice-time app-voice-unread">
1'6"
</div>
</div>
<!--语音播放控件-->
<audio id="audio_my" src="">
Your browser does not support the audio tag.
</audio>

核心功能实现逻辑

该组件的核心在于语音播放功能,主要包含以下几个关键功能点。

未读状态标记

界面通过红点标识未听语音,当用户听完某段语音后,对应的红点标记会自动消失。

实现方式是将“未读”状态的样式类独立定义。当语音被判定为“已读”时,只需移除该样式类即可。结合本地存储机制,即可轻松完成状态同步。


//this是点击的语音的document
var app_voice_time = this.getElementsByClassName("app-voice-time")[0];
  if(app_voice_time.className.indexOf("app-voice-unread") != -1){
    //存在红点时,把红点样式删除
    app_voice_time.className = app_voice_time.className.replace("app-voice-unread","");
  }

自动播放下一段

当用户首次播放某段语音时,系统会自动触发播放下一段语音的逻辑。

这一功能主要依赖 HTML5 Audio 控件提供的“播放结束”(ended)事件。具体逻辑为:在语音播放完毕后,定位到 DOM 结构中的下一个语音节点,并立即触发该节点的播放操作。


//语音播放完事件(PAGE.audio是audio控件的document)
 PAGE.audio.addEventListener('ended', function () {
   //循环获取下一个节点
  PAGE.preVoice = PAGE.currentVoice;
  var currentVoice = PAGE.currentVoice;
    while(true){
      currentVoice = currentVoice.nextElementSibling;//下一个兄弟节点
      //已经到达最底部
      if(!currentVoice){
        PAGE.preVoice.getElementsByClassName("app-voice-state")[0].className = "app-voice-state app-voice-pause";
        return false;
      }
      var voiceSrc = currentVoice.getAttribute("voiceSrc");
      if(voiceSrc && voiceSrc != ""){
        break;
      }
    }
    if(!PAGE.autoNextVoice){
      PAGE.preVoice.getElementsByClassName("app-voice-state")[0].className = "app-voice-state app-voice-pause";
      return false;
    }
    PAGE.currentVoice = currentVoice;
    //获取得到下一个语音节点,播放
      PAGE.audio.src = voiceSrc;
      PAGE.audio.play();
      PAGE.Event_PlayVoice();
}, false);

播放控制与状态切换

每段语音均支持暂停、继续播放以及重新播放的操作。

虽然逻辑相对基础,但涉及较多的状态判断与样式切换。系统需要通过变换图标样式来明确提示用户当前是处于“继续播放”还是“重新播放”的状态。

CSS3 动画效果

正在播放的语音会显示动态动画效果,而未处于播放状态的语音则停止动画,保持静态。

这部分效果主要通过 CSS3 动画技术实现,利用关键帧控制背景图片的位置变化以模拟播放进度或状态。


.app-voice-pause,.app-voice-play{
  height: 18px;
  background-repeat: no-repeat;
  background-image: url(../img/voice.png);
  background-size: 18px auto;
  opacity: 0.5;
}
 .app-voice-you .app-voice-pause{
  /*从未播放*/
  background-position: 0px -39px;
}
.app-voice-you .app-voice-play{
  /*播放中(不需要过渡动画)*/
  background-position: 0px -39px;
  -webkit-animation: voiceplay 1s infinite step-start;
  -moz-animation: voiceplay 1s infinite step-start;
  -o-animation: voiceplay 1s infinite step-start;
  animation: voiceplay 1s infinite step-start;
}
@-webkit-keyframes voiceplay {
  0%,
  100% {
    background-position: 0px -39px;
  }
  33.333333% {
    background-position: 0px -0px;
  }
  66.666666% {
    background-position: 0px -19.7px;
  }
}

以上内容即为本文的全部分享,希望能为读者的学习提供有益参考,同时也感谢大家的支持。

作者最新文章