小工具知识网

当前位置: 首页 > 行业知识 > 30天JS挑战(第十一天)-------JS原生实现视频控制

行业知识

30天JS挑战(第十一天)-------JS原生实现视频控制

2026-11-04 05:59:26 来源:互联网转载

第十一天挑战(视频控制)

地址:https://javascript30.com/

所有内容均上传至gitee,答案不唯一,仅代表本人思路

中文详解:https://github.com/soyaine/JavaScript30

该详解是Soyaine及其团队整理编撰的,是对源代码的详解,强烈推荐大家观看学习!!!

本人gitee:https://gitee.com/thats-all-right-ha-ha/30-days—js-challenge

效果

  • 样式分析

    • 组件总共分两个部分,首先是视频主体部分
    • 其次是控制部分,控制部分也分为两个部分,一个是视频进度条另一个是视频控件
    • 逻辑分析

      • 点击视频后视频开始播放和暂停,并且下方控制按钮根据视频状态切换

      • 进度条根据视频进度进行对应,拖动和点击进度条可以控制视频的进度

      • 左侧range条可以控制音量的大小(点击或拖动)

      • 右侧range条可以控制视频的倍速(点击或拖动)

      • 右侧控件可以根据对应的值对视频进行快进或快退

        本人代码及思路分析

        仅提供布局及逻辑代码

        结构:

                              ►            « 10s    25s »  

        逻辑:

        const player = document.querySelector('.player')const toggle = document.querySelector('.toggle')const volume = document.querySelector('[name="volume"]')const playbackRate = document.querySelector('[name="playbackRate"]')const skipButton = document.querySelectorAll('[data-skip]')const view = document.querySelector('.viewer')const progressFilled = document.querySelector('.progress__filled')const progress = document.querySelector('.progress')let isClick = false//视频播放开关function viewSwitch(){  view.paused ? view.play() : view.pause() }//播放图片切换function iconChange() {  const icon = this.paused ? '►' : '❚ ❚';  toggle.textContent = icon}//视频快进/快退function skip() {  console.log(view.currentTime)  view.currentTime += ~~this.dataset.skip}//视频倍速function videoRate(e){  view.playbackRate = e.target.value}//添加声音function videoVolume(e){  view.volume = e.target.value}//进度条function progressBar(){  const nowLoding = view.currentTime / view.duration  progressFilled.style.flexBasis = `${nowLoding * 100}%`}//控制进度条function changeProgressBar(e){  const nowWidth = e.offsetX / progress.offsetWidth  view.currentTime = view.duration * nowWidth}//视频控制view.addEventListener('click',viewSwitch)view.addEventListener('play', iconChange)view.addEventListener('pause',iconChange)view.addEventListener('timeupdate',progressBar)//播放按钮控制toggle.addEventListener('click',viewSwitch)//快进快退skipButton.forEach(element => {  element.addEventListener('click',skip)});//视频倍速playbackRate.addEventListener('input',videoRate)//视频音量volume.addEventListener('input',videoVolume)//拖动控制条progress.addEventListener('click',changeProgressBar)progress.addEventListener('mousedown', () => {  isClick = true})progress.addEventListener('mousemove', (e) => {  if(isClick){    changeProgressBar(e)  }})progress.addEventListener('mouseup', () => {  isClick = false})

        分析:

        • **整体思路:**获取所有需要添加事件的元素,并且添加事件,通过控制视频的属性来控制视频的播放,通过range的值更改视频的音量和倍速

        • 具体实现:

          • viewSwitch:通过paused属性判断当前的视频播放状态(paused返回布尔值)
          • iconChange:通过paused属性判断当前视频的播放状态,根据当前视频状态更改控件样式
          • skip:通过currentTime控制当前视频的进度,利用dataset获取标签上对应的自定义值,让其相加实现快进/快退效果(dataset标签上的值是字符类型,需要先进行转换)
          • videoRate:获取range标签的值,通过playbackRate更改视频的倍速,
          • videoVolume:获取range标签的值,通过volume更改视频的音量
          • progressBar:通过currentTime获取当前的时长,通过duration获取总视频的时长,让其相除,获取比例 *100更改进度条的百分比
          • changeProgressBar:通过offsetX获取当前鼠标点击的值,通过offsetWidth获取进度条总长度,让其相除获得比例,通过比例更改视频进度
          • 监听视频的 点击、开始、暂停、进度更改事件,并根据事件执行对应函数
          • 弊端分析(与官方方法对比):

            • mousemove事件仅作用于进度条内,如果移动的过程中鼠标脱离出了该范围,则会失效

              官方代码

              官方代码仅代表该案例原作者思路,不唯一

              结构

                                    ►            « 10s    25s »  

              逻辑

              /* Get Our Elements */const player = document.querySelector('.player');const video = player.querySelector('.viewer');const progress = player.querySelector('.progress');const progressBar = player.querySelector('.progress__filled');const toggle = player.querySelector('.toggle');const skipButtons = player.querySelectorAll('[data-skip]');const ranges = player.querySelectorAll('.player__slider');/* Build out functions */function togglePlay() {  const method = video.paused ? 'play' : 'pause';  video[method]();}function updateButton() {  const icon = this.paused ? '►' : '❚ ❚';  console.log(icon);  toggle.textContent = icon;}function skip() {  video.currentTime += parseFloat(this.dataset.skip);}function handleRangeUpdate() {  video[this.name] = this.value;}function handleProgress() {  const percent = (video.currentTime / video.duration) * 100;  progressBar.style.flexBasis = `${percent}%`;}function scrub(e) {  const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;  video.currentTime = scrubTime;}/* Hook up the event listeners */video.addEventListener('click', togglePlay);video.addEventListener('play', updateButton);video.addEventListener('pause', updateButton);video.addEventListener('timeupdate', handleProgress);toggle.addEventListener('click', togglePlay);skipButtons.forEach(button => button.addEventListener('click', skip));ranges.forEach(range => range.addEventListener('change', handleRangeUpdate));ranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate));let mousedown = false;progress.addEventListener('click', scrub);progress.addEventListener('mousemove', (e) => mousedown && scrub(e));progress.addEventListener('mousedown', () => mousedown = true);progress.addEventListener('mouseup', () => mousedown = false);

              建议直接去看Soyaine的中文详解

              ​

上一篇:轻松下载PCcharm,一站式解决方案教程!

下一篇:会员服务器怎么关闭?