乐趣区

关于html5:vue中audio自定义样式页面中包含多个audio

前言

一开始看到 UI 设计稿,我心田是非常抗拒的。感觉用原生 audio 的款式就能够了,也不是特地丑,毕竟工夫给的不多,自定义款式还要改逻辑啥的。在网上搜寻了一番有没有适合的插件,没有看到心动的。最初还是硬着头皮本人写了。

参考了一个博客,很感激这位博主,逻辑都能够用。不过原博用的 jquery,我本人用 vue,而且我的页面可能有不止一个 audio,设计稿和原博也很不一样,所以改代码还是花了一番心理。

参考链接:音频(audio)自定义款式以及管制操作面板
vue 版本:2.6.12

我这里是依照我的设计稿做进去的样子,如果你的设计稿跟我的不一样,那也只须要改一下 css 局部和 html,js 还是能间接套用的。

如果急用的同学能够间接跳到最初看残缺的代码,复制了不出意外能够间接用的,只须要把播放按钮的图片改成你本人的图片,再增加可用的 audio 链接就能够了。

html 代码:

<div class="page-container">
    <div v-for="(item, index) in content" :key="index" class="list-box">
      <audio ref="audio" :src="item.audio_url" controls @loadedmetadata="fillTime($event, index)"
        @timeupdate.stop="updateProgress(index)" @ended.stop="audioEnded(index)">
      </audio>
      <!-- 音频名字 -->
      <div class="audio-name">{{item.audio_name}}</div>
      <div class="control-row">
        <!-- 管制播放暂停的按钮 -->
        <img src="@/assets/play.png" class="play-icon" alt=""@click="playAudio(index)">
        <div class="row-right">
          <!-- 进度条 -->
          <div class="pgs">
            <div class="pgs-play"></div>
          </div>
          <!-- 以后播放时长和总时长 -->
          <div class="time-row">
            <span class="played-time">{{audioArr[index].currentTime }}</span>
            <span class="audio-time">{{audioArr[index].duration }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>

js 代码:

export default {data() {
      return {audioNodes: [],    // 用于寄存所有 audio 的 DOM 节点
        audioArr: [],       // 用于保护 audio 的总时长和以后播放工夫的数组
        content: [           // 寄存 audio 的地址信息,个别是接口返回
            {"audio_name":"20210112_1056.m4a","audio_url":"https://xxx.com/android1610420451567524.m4a"},
            {"audio_name":"20210112_1056.m4a","audio_url":"https://xxx.com/android1610420451567524.m4a"},
        ]
      }
    },
    mounted() {this.audioNodes = document.getElementsByClassName('list-box')
      this.content.forEach((item, index) => {this.$set(this.audioArr, index, { duration: '', currentTime:'00:00'})
      })
    },
    methods: {
      // 切换播放,暂停按钮的事件
      playAudio(index) {let audio = this.audioNodes[index].firstChild
        if (audio.paused) {audio.play()
        } else {audio.pause()
        }
      },
      
      // 获取音频的总时长
      fillTime(event, index) {this.audioArr[index].duration = this.transTime(event.target.duration)
      },

      // 将秒数转化成 (分: 秒) 格局
      transTime(time) {let duration = parseInt(time)
        let minute = parseInt(duration / 60).toString().padStart(2, '0')
        let sec = (duration % 60).toString().padStart(2, '0')
        return `${minute}:${sec}`
      },

      // 进度条播放的事件
      updateProgress(index) {let audio = this.audioNodes[index].firstChild
        let value = Math.round((Math.floor(audio.currentTime) / Math.floor(audio.duration)) * 100, 0)
        this.audioArr[index].currentTime = this.transTime(audio.currentTime)
        let progressTag = this.audioNodes[index].getElementsByClassName('pgs-play')[0]
        progressTag.style.left = `${value}%`
      },

      // 播放完结的解决动作
      audioEnded(index) {let audio = this.audioNodes[index].firstChild
        audio.currentTime = 0
        audio.pause()},
    }
  }

css 代码:

.pgs {
      background-color: #D8D4D1;
      text-align: center;
      position: relative;
      height: 2px;
      margin-bottom: 10px;
    }

    .pgs-play {
      position: absolute;
      top: -2.5px;
      left: 0;
      width: 7px;
      height: 7px;
      border-radius: 50%;
      background-color: #B03F28;
      z-index: 1;
    }

    .play-icon {
      width: 45px;
      height: 45px;
      margin-right: 15px;
    }
    audio {
      display: block;
      height: 0;
    }
    .audio-box {
      background: #F5F5F5;
      border: 1px solid #D8D4D1;
      border-radius: 5px;
      width: 100%;
      padding: 15px 12px;
      box-sizing: border-box;
    }
    .audio-name {
      font-size: 15px;
      color: #252120;
      margin-bottom: 15px;
      overflow:hidden; // 超出的文本暗藏
      text-overflow:ellipsis; // 溢出用省略号显示
      white-space:nowrap; // 溢出不换行
    }
    .control-row {
      display: flex;
      align-items: flex-end;
    }
    .row-right {flex-grow: 100;}
    .time-row {
      position: relative;
      color: #B0AFAD;
      font-size: 12px;
      margin-bottom: 3px;
    }
    .audio-time {
      position: absolute;
      right: 0;
    }

残缺代码(audio.vue)

  • 能够间接套用,只须要改 control-row 外面的图片地址,这是播放按钮的图片。
<style lang="scss">
  .page-container {
    .pgs {
      background-color: #D8D4D1;
      text-align: center;
      position: relative;
      height: 2px;
      margin-bottom: 10px;
    }

    .pgs-play {
      position: absolute;
      top: -2.5px;
      left: 0;
      width: 7px;
      height: 7px;
      border-radius: 50%;
      background-color: #B03F28;
      z-index: 1;
    }

    .play-icon {
      width: 45px;
      height: 45px;
      margin-right: 15px;
    }

    audio {
      display: block;
      height: 0;
    }

    .audio-box {
      background: #F5F5F5;
      border: 1px solid #D8D4D1;
      border-radius: 5px;
      width: 100%;
      padding: 15px 12px;
      box-sizing: border-box;
    }

    .audio-name {
      font-size: 15px;
      color: #252120;
      margin-bottom: 15px;
      overflow: hidden; // 超出的文本暗藏
      text-overflow: ellipsis; // 溢出用省略号显示
      white-space: nowrap; // 溢出不换行
    }

    .control-row {
      display: flex;
      align-items: flex-end;
    }

    .row-right {flex-grow: 100;}

    .time-row {
      position: relative;
      color: #B0AFAD;
      font-size: 12px;
      margin-bottom: 3px;
    }

    .audio-time {
      position: absolute;
      right: 0;
    }
  }
</style>

<template>
  <div class="page-container">
    <div v-for="(item, index) in content" :key="index" class="list-box">
      <audio ref="audio" :src="item.audio_url" controls @loadedmetadata="fillTime($event, index)"
        @timeupdate.stop="updateProgress(index)" @ended.stop="audioEnded(index)">
      </audio>
      <!-- 音频名字 -->
      <div class="audio-name">{{item.audio_name}}</div>
      <div class="control-row">
        <!-- 管制播放暂停的按钮 -->
        <img src="@/assets/play.png" class="play-icon" alt=""@click="playAudio(index)">
        <div class="row-right">
          <!-- 进度条 -->
          <div class="pgs">
            <div class="pgs-play"></div>
          </div>
          <!-- 以后播放时长和总时长 -->
          <div class="time-row">
            <span class="played-time">{{audioArr[index].currentTime }}</span>
            <span class="audio-time">{{audioArr[index].duration }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  export default {data() {
      return {audioNodes: [],    // 用于寄存所有 audio 的 DOM 节点
        audioArr: [],       // 用于保护 audio 的总时长和以后播放工夫的数组
        content: [           // 寄存 audio 的地址信息,个别是接口返回
            {"audio_name":"20210112_1056.m4a","audio_url":"https://xxx.com/android1610420451567524.m4a"},
            {"audio_name":"20210112_1056.m4a","audio_url":"https://xxx.com/android1610420451567524.m4a"},
        ]
      }
    },
    mounted() {this.audioNodes = document.getElementsByClassName('list-box')
      this.content.forEach((item, index) => {this.$set(this.audioArr, index, { duration: '', currentTime:'00:00'})
      })
    },
    methods: {
      // 切换播放,暂停按钮的事件
      playAudio(index) {let audio = this.audioNodes[index].firstChild
        if (audio.paused) {audio.play()
        } else {audio.pause()
        }
      },
      
      // 获取音频的总时长
      fillTime(event, index) {this.audioArr[index].duration = this.transTime(event.target.duration)
      },

      // 将秒数转化成 (分: 秒) 格局
      transTime(time) {let duration = parseInt(time)
        let minute = parseInt(duration / 60).toString().padStart(2, '0')
        let sec = (duration % 60).toString().padStart(2, '0')
        return `${minute}:${sec}`
      },

      // 进度条播放的事件
      updateProgress(index) {let audio = this.audioNodes[index].firstChild
        let value = Math.round((Math.floor(audio.currentTime) / Math.floor(audio.duration)) * 100, 0)
        this.audioArr[index].currentTime = this.transTime(audio.currentTime)
        let progressTag = this.audioNodes[index].getElementsByClassName('pgs-play')[0]
        progressTag.style.left = `${value}%`
      },

      // 播放完结的解决动作
      audioEnded(index) {let audio = this.audioNodes[index].firstChild
        audio.currentTime = 0
        audio.pause()},
    }
  }
</script>

文章到这里就完结了,如果对你有帮忙,欢送点赞,珍藏,谢谢~

退出移动版