video标签自定义控制按钮--全屏与非全屏--播放与暂停

hover时,显示红色播放按钮和最大化按钮, 其余时刻隐藏,全屏时显示播放进度条,以及hover时,才显示红色暂停按钮和最小化按钮

html 复制代码
<template>
  <div class="item-wrapper-inner" ref="fullscreenDomRef">
    <!-- 
      muted: 出现该属性表示静音 
      autoplay: 出现该属性表示自动播放
      loop: 出现该属性表示循环播放
      preload: 出现该属性表示视频在页面加载前就开始加载
      disablepictureinpicture: 禁用画中画
    -->
    <video
      :controls="controls"
      preload
      muted
      autoplay
      loop
      disablepictureinpicture
      controlslist="nodownload noplaybackrate"
      ref="videoDomRef"
    >
      <source src="/01.mp4" />
    </video>
    <div class="full-screen-btn" @click="onToggleFullscreen">
      <a-icon type="fullscreen" />
    </div>
    <div class="play-stop-btn" @click="onTogglePlay">
      <a-icon type="pause-circle" v-if="playing" />
      <a-icon type="play-circle" v-else />
    </div>
  </div>
</template>

<script>
export default {
  name: "VideoPLayer",
  props: ["src"],
  data() {
    return {
      controls: false,
      playing: false
    };
  },
  methods: {
    onToggleFullscreen() {
      const fullscreenDom = this.$refs.fullscreenDomRef;
      console.log(document.fullscreenElement);
      if (document.fullscreenElement) {
        this.cancelFullscreen();
      } else {
        this.fullscreenFun(fullscreenDom);
      }
    },
    fullscreenFun(ele) {
      if (ele.requestFullscreen) {
        ele.requestFullscreen();
      } else if (ele.mozRequestFullScreen) {
        ele.mozRequestFullScreen();
      } else if (ele.webkitRequestFullScreen) {
        ele.webkitRequestFullScreen();
      }
    },
    cancelFullscreen() {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
      }
    },
    onFullscreenchange() {
      if (document.fullscreenElement) {
        console.log("元素已进入全屏状态");
        this.controls = true;
      } else {
        console.log("元素已退出全屏状态");
        this.controls = false;
      }
    },
    onTogglePlay() {
      const videoDom = this.$refs.videoDomRef;
      if (videoDom) {
        if (videoDom.paused) {
          videoDom.play();
        } else {
          videoDom.pause();
        }
      }
    },
    videoEvtListnerDestory() {
      const videoDom = this.$refs.videoDomRef;
      if (videoDom) {
        videoDom.removeEventListener("play");
        videoDom.removeEventListener("pause");
        videoDom.removeEventListener("ended");
      }
    },
    videoEvtListner() {
      const videoDom = this.$refs.videoDomRef;
      if (videoDom) {
        videoDom.addEventListener("play", () => {
          //播放
          console.log("开始播放");
          this.playing = true;
        });
        videoDom.addEventListener("pause", () => {
          //暂停
          console.log("暂停");
          this.playing = false;
        });
        videoDom.addEventListener(
          "ended",
          () => {
            //结束
            console.log("播放结束");
            this.playing = false;
          },
          false
        );
      }
    }
  },
  mounted() {
    this.videoEvtListner();
    document.addEventListener("fullscreenchange", this.onFullscreenchange);
  },
  beforeDestroy() {
    this.videoEvtListnerDestory();
    document.removeEventListener("fullscreenchange", this.onFullscreenchange);
  }
};
</script>
<style scoped lang="less">
.item-wrapper-inner {
  height: 100%;
  position: relative;
  video {
    width: 100%;
    height: 100%;
  }
  // 全屏按钮
  video::-webkit-media-controls-fullscreen-button {
    display: none;
  }
  //播放按钮
  video::-webkit-media-controls-play-button {
    display: none;
  }
  .full-screen-btn {
    position: absolute;
    top: 30px;
    right: 30px;
    color: red;
    display: none;
    cursor: pointer;
  }
  .play-stop-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    color: red;
    display: none;
    cursor: pointer;
    transform: translate(-50%);
  }
  &:hover {
    .full-screen-btn {
      display: block;
    }
    .play-stop-btn {
      display: block;
    }
  }
}
</style>
相关推荐
小楓12011 小时前
後端開發技術教學(三) 表單提交、數據處理
前端·后端·html·php
破刺不会编程1 小时前
linux信号量和日志
java·linux·运维·前端·算法
阿里小阿希2 小时前
Vue 3 表单数据缓存架构设计:从问题到解决方案
前端·vue.js·缓存
JefferyXZF2 小时前
Next.js 核心路由解析:动态路由、路由组、平行路由和拦截路由(四)
前端·全栈·next.js
汪子熙3 小时前
浏览器环境中 window.eval(vOnInit); // csp-ignore-legacy-api 的技术解析与实践意义
前端·javascript
还要啥名字3 小时前
elpis - 动态组件扩展设计
前端
BUG收容所所长3 小时前
🤖 零基础构建本地AI对话机器人:Ollama+React实战指南
前端·javascript·llm
鹏程十八少3 小时前
7. Android RecyclerView吃了80MB内存!KOOM定位+Profiler解剖+MAT验尸全记录
前端
小高0073 小时前
🚀前端异步编程:Promise vs Async/Await,实战对比与应用
前端·javascript·面试
用户87612829073743 小时前
对于通用组件如何获取表单输入,区分表单类型的试验
前端·javascript