自学完H5后来写个简单的视频播放器
前言
自学了一系列HTML5后,了解了H5好多新标签,像canvas,像可以直接操作类的classList(虽然兼容性不好),当然还有新增了众多的表单属性和控件。但最让我迫不及待的想用下的是video,audio(天天用播放器,自己做一个才快乐),所以正好写个视频播放器来梳理下一些知识吧,也希望能给你们提供一点思路
上个完整效果预览图吧(简单,但也有好多坑)

一、首先先把大概框架搭起来吧(html)

1 <div id="wrap"> 2 <video src="https://blz-videos.nosdn.127.net/1/OverWatch/AnimatedShots/Overwatch_AnimatedShot_Bastion_TheLastBastion.mp4"></video> 3 <div class="control"> 4 <div class="btns"> 5 <span class="start"></span> 6 <span class="reset"></span> 7 </div> 8 <div class="process"> 9 <div class="process_up"> 10 <div class="inner"></div> 11 </div> 12 <div class="process_down"></div> 13 </div> 14 <div class="volume"> 15 <span class="text">00:00:00</span> /<span class="duration">10:04:70</span> 16 <span class="volumecontorl"></span> 17 <div class="volume_wrap"> 18 <div class="volume_up"> 19 <div class="volume_inner"></div> 20 </div> 21 <div class="volume_down"></div> 22 </div> 23 <span class="full"></span> 24 </div> 25 </div> 26 </div>
二、再给它加点基础css

1 html,body{ 2 height: 100%; 3 overflow: hidden;//取消浏览器自带滚动条 4 } 5 #wrap{ 6 background-color: #383838; 7 } 8 #wrap>.control{ 9 position: relative; 10 height: 25px; 11 background-color: #2A2A2A; 12 } 13 #wrap>video{ 14 margin: auto; 15 } 16 #wrap>.control>.btns{ 17 position: absolute; 18 width: 55px; 19 height: 25px; 20 } 21 .start,.reset,.pause{ 22 width: 13px; 23 height: 13px; 24 position: absolute; 25 margin-top: 6px; 26 } 27 .start{ 28 background: url(img/开始.png); 29 background-size: 100% 100%; 30 margin-left: 10px; 31 } 32 .pause{ 33 background: url(img/暂停.png); 34 background-size: 100% 100%; 35 margin-left: 10px; 36 } 37 .reset{ 38 background: url(img/重置.png); 39 background-size: 100% 100%; 40 margin-left: 30px; 41 } 42 43 #wrap>.control>.process{ 44 position: relative; 45 width: auto; 46 height: 25px; 47 margin: 0 230px 0 55px; 48 } 49 .process>.process_up{ 50 position: absolute; 51 width: 100%;/*脱离文档流了*/ 52 height: 3px; 53 margin-top: 11px; 54 background-color: #737373; 55 } 56 .process>.process_up>.inner{ 57 position: absolute; 58 width: 9px; 59 height: 7px; 60 margin-top: -2px; 61 background-color: white; 62 border-radius: 50%; 63 } 64 .process>.process_down{ 65 position: absolute; 66 height: 3px; 67 width: 0px; 68 margin-top: 11px; 69 background-color: deeppink; 70 } 71 #wrap>.control>.volume{ 72 position: absolute; 73 width: 230px; 74 height: 25px; 75 right: 0; 76 top: 0; 77 color: white; 78 font-size: 12px; 79 } 80 .text{ 81 display: inline-block; 82 width:40px; 83 margin-left: 10px; 84 margin-top: 6px; 85 } 86 .volumecontorl,.volumecontorl2{ 87 position: absolute; 88 width: 20px; 89 height:20px; 90 } 91 .volumecontorl{ 92 background: url(img/音量.png); 93 background-repeat: no-repeat; 94 background-size: 50% 50%; 95 margin-top: 7px; 96 margin-left: 9px; 97 } 98 .volumecontorl2{ 99 background: url(img/静音.png); 100 background-repeat: no-repeat; 101 background-size: 60% 60%; 102 margin-top: 6px; 103 margin-left: 11px; 104 } 105 .volume_up{ 106 position: absolute; 107 width: 60px;/*脱离文档流了*/ 108 height: 5px; 109 margin: -8px 132px; 110 background-color: #737373; 111 } 112 .volume_inner{ 113 position: absolute; 114 width: 9px; 115 height: 7px; 116 background-color: white; 117 margin-top: -1px; 118 left: 51px; 119 border-radius: 50%; 120 } 121 .volume_down{ 122 position: absolute; 123 height: 5px; 124 width: 51px; 125 margin: -8px 132px; 126 background-color: deeppink; 127 } 128 .full{ 129 position: absolute; 130 width: 20px; 131 height:20px; 132 background: url(img/全屏.png); 133 background-repeat: no-repeat; 134 background-size: 50% 50%; 135 margin-top: -11px; 136 margin-left: 200px; 137 }
这里还需要一点js来设置下视频的高宽,以及设置视频总时长(固定的)
1 video.width=document.documentElement.clientWidth 2 video.height=document.documentElement.clientHeight-control.offsetHeight 3 setTimeout(function(){ 4 duration.innerText=getTime(video.duration)//这里注意,如果直接获取video的duration,有可能视频还没加载完,所以通过定时器或者视频事件后再获取 5 },500)
以上就可以搭建出一个简单的视频播放器(当然点击是没有效果)
三、接下来是逻辑最复杂且最容易出错的功能实现,从左到右一个个实现
1)第一步让我们先把这个视频播放功能实现
首先我们要点击播放按钮,视频开始播放,并且播放图标切换为暂停图标,再次点击则暂停视频,图标再切换为开始按钮
1 start.onclick=function(ev){ 2 ev=ev||event 3 if(video.paused){//处于播放 4 start.classList.remove('start')//利用H5的classList切换类达到切换图标的效果 5 start.classList.add('pause') 6 video.play()//调用video的函数播放视频 7 }else{ 8 start.classList.remove('pause') 9 start.classList.add('start') 10 video.pause()//调用函数暂停视频 11 } 12 }
这时候发现虽然可以播放了,但是视频进度条一动不动,当然了,我们还没有对它进行操作,让我们先来分析下进度条是怎么变化的:
假设整个进度条长度是X,我们也可以通过函数知道目前播放的时间S,和视频的总时间E,那么S/E*X不就是播放目前时长,拖拽块和进度条走了多少吗,让我们用js写出来,如下
1 var inner=document.querySelector('#wrap>.control .inner') 2 var process=document.querySelector('#wrap>.control .process') 3 var process_down=document.querySelector('#wrap>.control .process_down') 4 timer=setInterval(function(){//我们需要用利用定时器不断的获取进度条目前的长度和拖拽块的位置 5 process_down.style.width=video.currentTime/video.duration*process.offsetWidth+'px' 6 inner.style.left=video.currentTime/video.duration*process.offsetWidth+'px' 7 },100)
播放起来的时候,时长也应该随之变化,注意他的样式是00:00:00
首先我们应该获取下当前的播放时间,但是他是一个数,我们需要转换下时分秒格式,同时对小于两位数的数进行前补0,因为这个功能很多地方用到,我封装成了函数,在需要的地方调用
1 //时间格式转换 2 function getTime(time){ 3 var s,f,h 4 time=parseInt(time) 5 h=toZero(Math.floor(time/3600)) 6 f=toZero(Math.floor(time%3600/60)) 7 s=toZero(Math.floor(time%60)) 8 return h+':'+f+':'+s 9 } 10 //少于两位数时间补0 11 function toZero(n){ 12 if(n<10) 13 n="0"+n 14 return n 15 } 16 //当前时间格式转换 17 function getCurrTime(){ 18 var currTime 19 currTime=setInterval(function(){ 20 var t=video.currentTime 21 current.innerText=getTime(t) 22 },500) 23 return currTime 24 }
播放的时候变化的功能都已经初步实现了,但是暂停的功能实现了吗?
暂停的功能不就是把播放动起来的元素停掉吗?(当前播放时间,进度条)
进度条不就是按照定时器不断的根据当前播放时间计算出进度条的长度,当前播放时间的字符串不也是按照当前播放时间计算的。
所以当我们点击暂停,播放时间就停止了,进度条和播放时间字符串也随之停止,不需要额外操作就完成了暂停的功能。但是在上面我们开启了两个定时器,如果暂停需要消除下,以防止内存泄漏
2)第二步实现点击重置按钮的功能
点击重置的时候,所有东西都回到一开始,播放时间置为0,进度条长度为0,播放时间文本回到00:00:00,视频暂停播放,暂停按钮图标重置为播放。当然同样的,把前面开启的两个定时器清除
1 //点击重置 2 reset.onclick=function(ev){ 3 ev=ev||event 4 start.classList.remove('pause') 5 start.classList.add('start') 6 video.pause() 7 clearInterval(timer) 8 clearInterval(currTime) 9 video.currentTime=0;//把视频播放时间置为0 10 process_down.style.width='0px'//进度条宽度为0 11 inner.style.left='0px'//拖拽块到最左边 12 current.innerText='00:00:00'//播放时间文本置为初始 13 }
3)第三步实现点击视频进度条,视频跳转
点击了进度条,我们就需要跳转到对应比例的视频位置。假设点的进度条为X,进度条总长度为Y,总时间为E,那么当前播放时间不就是X/Y*E.
如果视频是暂停的,那就播放视频,执行播放视频的那些操作。接下来利用js实现
1 //点击视频进度条 2 process.onclick=function(ev){//点击视频进度条 3 ev=ev||event 4 clearInterval(timer) 5 clearInterval(currTime) 6 if(video.paused){//处于暂停 7 start.classList.remove('start') 8 start.classList.add('pause') 9 video.play() 10 } 11 inner.style.left=ev.clientX-process.offsetLeft-inner.clientWidth/2+'px' 12 video.currentTime=(ev.clientX-process.offsetLeft)/process.clientWidth*video.duration 13 process_down.style.width=ev.clientX-process.offsetLeft-inner.clientWidth/2+'px' 14 timer=setInterval(function(){ 15 process_down.style.width=video.currentTime/video.duration*process.offsetWidth+'px' 16 inner.style.left=video.currentTime/video.duration*process.offsetWidth+'px' 17 },100) 18 currTime=getCurrTime() 19 }
4)第四步实现拖拉视频进度条,视频跳转
这一步的重点不就是拖拽拖拽块吗?那我们先开始了解怎么拖拽一个物体
分析下拖拽的思路:
1.拿到鼠标点击元素时,元素一开始的位置:testNodeStart
2.拿到鼠标移动的距离:nowNode-mouseStartNode
3.确定鼠标移动后,元素的位置
元素一开始的位置+鼠标移动的距离:testNodeStart+nowNode-mouseStartNode,如果元素的位置超出范围,我们需要调整位置
这个拖拽功能经常使用,我这里封装成一个组件如下
1 (function(w){ 2 w.drag=function(testnode,callback){ 3 var testNodeStart={x:0,y:0} 4 testnode.onmousedown=function(ev){ 5 ev=ev||event 6 testnodeStart.x=testnode.offsetLeft//按住滑动块时,获取他相对父元素的位置 7 if(testnode.setCapture){ 8 testnode.setCapture()//开启鼠标捕获,让IE8只能获取到鼠标点击的元素,间接达到效果 9 } 10 var mouseStartNode=ev.clientX//鼠标一开始的位置 11 document.onmousemove=function(ev){ 12 ev=ev||event 13 var nowNode=ev.clientX//鼠标开始移动的位置 14 var L=testnodeStart.x+nowNode-mouseStartNode//元素现在的位置 15 if(L<0)L=0//控制元素位置范围 16 else if(L>testnode.parentNode.clientWidth-testnode.clientWidth)L=testnode.parentNode.clientWidth-testnode.clientWidth 17 testnode.style.left=L+'px' 18 if(callback&&callback['move']&&typeof callback['move']=='function'){ 19 callback['move'].call(testnode,ev)//让回调函数的this指向元素,并把鼠标信息作为参数传递过去 20 } 21 } 22 document.onmouseup=function(){ 23 document.onmouseup=document.onmousemove=null 24 if(document.releaseCapture){ 25 document.releaseCapture()//释放鼠标捕获 26 } 27 } 28 return false//取消浏览器默认行为 29 } 30 } 31 })(window)
在主页面引入drag.js文件,再传入对象callback。
1 var callback={ 2 move:function(ev){ 3 process_down.style.width=this.offsetLeft+'px'//让进度条随着鼠标移动而移动,中间的差值需要理清楚 4 video.currentTime=(ev.clientX-process.offsetLeft)/process.clientWidth*video.duration 5 } 6 } 7 drag(inner,callback)//拖拉视频进度
拖拉和点击进度条做好后要注意当视频播放完毕应该进行什么操作?
当当前播放时间大于等于总时间,说明播放结束,首先应该把前面播放开启的定时器关闭,再停止视频,切换播放图标
if(video.currentTime>=video.duration){ start.classList.remove('pause') start.classList.add('start') video.pause() clearInterval(timer)//播放结束,清除定时器 clearInterval(currTime) }
5)第五步点击音量,实现开启静音和关闭静音
如果是静音状态,点击后
则需要切换图标为静音图标,视频的muted置为false,volume置为1,因为video的volume和muted不会同步,再把音量进度条置为最大长度
如果非静音状态,点击后
则需要切换图标为非静音图标,视频的muted置为true,volume置为0,因为video的volume和muted不会同步,再把音量进度条置为0,js如下
1 //实现静音 2 function muted(){ 3 video.muted=true//静音 4 video.volume=0 5 volumecontorl.classList.add('volumecontorl2') 6 volumecontorl.classList.remove('volumecontorl') 7 } 8 //取消静音 9 function removeMuted(){ 10 video.muted=false 11 video.volume=1 12 volumecontorl.classList.remove('volumecontorl2') 13 volumecontorl.classList.add('volumecontorl') 14 }
6)第六步点击和拖拉音量进度条,与上面cd基本一致,不再赘余
7)最后一步,点击全屏,实现全屏和退出全屏
这里基本都是调用api,但要考虑浏览器兼容性以及因为视频的高宽上面是通过js获取的固定值,如果不改变会出现空白(别问我为啥知道,因为我卡这好久),所以我们需要当触发全屏时,重新获取高宽
1 window.onresize=function(){//点击全屏和退出全屏,改变高宽 2 video.width=document.documentElement.clientWidth 3 video.height=document.documentElement.clientHeight-control.offsetHeight 4 } 5 var isFullScreen=false 6 //点击全屏 7 fullScreen.onclick=function(){ 8 if(isFullScreen){ 9 isFullScreen = false 10 if (document.exitFullscreen){ 11 document.exitFullscreen(); 12 } 13 else if (document.mozCancelFullScreen){ 14 document.mozCancelFullScreen(); 15 } 16 else if (document.webkitCancelFullScreen) { 17 document.webkitCancelFullScreen(); 18 } 19 else if (document.msExitFullscreen) { 20 document.msExitFullscreen(); 21 } 22 }else{ 23 isFullScreen = true 24 var docElm = document.documentElement; 25 //W3C 26 if (docElm.requestFullscreen){ 27 docElm.requestFullscreen(); 28 } 29 //FireFox 30 else if (docElm.mozRequestFullScreen) { 31 docElm.mozRequestFullScreen(); 32 } 33 //Chrome等 34 else if (docElm.webkitRequestFullScreen){ 35 docElm.webkitRequestFullScreen(); 36 } 37 //IE11 38 else if(doctlm.msRequestFullscreen) { 39 docElm.msReguestFullscreen() 40 } 41 42 } 43 }
终于大功告成,一个基本的播放器以及搭建好了,这边跟大家分享下踩到的一些坑(泪与血)
1)定时器没清除,因为需要一段时间获取下数据,开启了几个定时器,一开始忘了清除,也没输出一直没发现,后面浏览器卡炸了。所以开启定时器一定要记得关闭,不然会造成内存泄漏,进而容易导致 内存溢出。这里顺便分享下 意外的全局变量,没有及时清理的计时器或回调函数,闭包都容易引起内存泄漏。
2)在chrome下运行项目,发现html5设置video.currentTime无效,一开始没发现,查了好久的错,经过了解,好像是chrome对本地视频的限制,改成网络视频就没有这个问题了。
3)也就是上面提过的需要重新设置视频的高宽,不然会出现空白区。
4)因为进度条是盖在总进度条上的,而事件又要绑定在总进度上,一旦进度条完全盖住总进度条,就无法拖拉点击。所以最好给他们一个包裹区,将事件绑定在包裹区
下面分享下完整代码,如果有问题或者发现什么bug可以私信我

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>视频播放器</title> 6 <link rel="stylesheet" type="text/css" href="../reset.css"/> 7 <link rel="stylesheet" type="text/css" href="24.videoplay.css"/> 8 </head> 9 <body> 10 <div id="wrap"> 11 <video src="https://blz-videos.nosdn.127.net/1/OverWatch/AnimatedShots/Overwatch_AnimatedShot_Bastion_TheLastBastion.mp4"></video> 12 <div class="control"> 13 <div class="btns"> 14 <span class="start"></span> 15 <span class="reset"></span> 16 </div> 17 <div class="process"> 18 <div class="process_up"> 19 <div class="inner"></div> 20 </div> 21 <div class="process_down"></div> 22 </div> 23 <div class="volume"> 24 <span class="text">00:00:00</span> /<span class="duration">10:04:70</span> 25 <span class="volumecontorl"></span> 26 <div class="volume_wrap"> 27 <div class="volume_up"> 28 <div class="volume_inner"></div> 29 </div> 30 <div class="volume_down"></div> 31 </div> 32 <span class="full"></span> 33 </div> 34 </div> 35 </div> 36 </body> 37 <script src="24.videoplay.js" type="text/javascript" charset="utf-8"></script> 38 <script type="text/javascript"> 39 window.onload=function(){ 40 var video=document.querySelector('video') 41 var control=document.querySelector('#wrap>.control') 42 var inner=document.querySelector('#wrap>.control .inner') 43 var process=document.querySelector('#wrap>.control .process') 44 var process_down=document.querySelector('#wrap>.control .process_down') 45 var volume=document.querySelector('.volume') 46 var start=document.querySelector('.btns span:first-child') 47 var current=document.querySelector('.text') 48 var duration=document.querySelector('.duration') 49 var reset=document.querySelector('.reset') 50 var volume_up=document.querySelector('.volume_up') 51 var volume_inner=document.querySelector('.volume_inner') 52 var volume_down=document.querySelector('.volume_down') 53 var volumecontorl=document.querySelector('.volumecontorl') 54 var volume_wrap=document.querySelector('.volume_wrap') 55 var fullScreen=document.querySelector('.full') 56 window.onresize=function(){//点击全屏,改变高宽 57 video.width=document.documentElement.clientWidth 58 video.height=document.documentElement.clientHeight-control.offsetHeight 59 } 60 video.width=document.documentElement.clientWidth 61 video.height=document.documentElement.clientHeight-control.offsetHeight 62 setTimeout(function(){ 63 duration.innerText=getTime(video.duration) 64 },500) 65 video.volume=0.5//一开始声音置为0.5 66 play()//播放器功能 67 var timer=0 68 function play(){ 69 //点击开始暂停 70 var currTime 71 start.onclick=function(ev){ 72 ev=ev||event 73 clearInterval(currTime) 74 if(video.paused){//处于播放 75 start.classList.remove('start') 76 start.classList.add('pause') 77 video.play() 78 timer=setInterval(function(){ 79 process_down.style.width=video.currentTime/video.duration*process.offsetWidth+'px' 80 inner.style.left=video.currentTime/video.duration*process.offsetWidth+'px' 81 },100) 82 currTime=getCurrTime() 83 }else{ 84 start.classList.remove('pause') 85 start.classList.add('start') 86 video.pause() 87 clearInterval(timer) 88 } 89 } 90 //点击重置 91 reset.onclick=function(ev){//点击重置 92 ev=ev||event 93 start.classList.remove('pause') 94 start.classList.add('start') 95 video.pause() 96 clearInterval(timer) 97 clearInterval(currTime) 98 video.currentTime=0; 99 process_down.style.width='0px' 100 inner.style.left='0px' 101 current.innerText='00:00:00' 102 } 103 //点击视频进度条 104 process.onclick=function(ev){//点击视频进度条 105 ev=ev||event 106 clearInterval(timer) 107 clearInterval(currTime) 108 if(video.paused){//处于暂停 109 start.classList.remove('start') 110 start.classList.add('pause') 111 video.play() 112 } 113 inner.style.left=ev.clientX-process.offsetLeft-inner.clientWidth/2+'px' 114 video.currentTime=(ev.clientX-process.offsetLeft)/process.clientWidth*video.duration 115 process_down.style.width=ev.clientX-process.offsetLeft-inner.clientWidth/2+'px' 116 timer=setInterval(function(){ 117 process_down.style.width=video.currentTime/video.duration*process.offsetWidth+'px' 118 inner.style.left=video.currentTime/video.duration*process.offsetWidth+'px' 119 },100) 120 currTime=getCurrTime() 121 } 122 //点击音量进度条 123 volume_wrap.onclick=function(ev){//点击音量进度条 124 ev=ev||event 125 var L=ev.clientX-volume_up.offsetLeft-volume.offsetLeft-volume_inner.clientWidth/2 126 if(L<=0){ 127 L=0 128 muted() 129 }else if(L>volume_up.offsetWidth){ 130 L=volume_up.offsetWidth-volume_inner.clientWidth/2 131 removeMuted() 132 }else{ 133 removeMuted() 134 } 135 volume_inner.style.left=L+'px'//音量拖拽块跳到鼠标位置 136 video.volume=L/volume_up.offsetWidth 137 volume_down.style.width=L+'px'//音量进度条跳到鼠标位置 138 } 139 var volumeMove=1//记录静音前的位置,静音后返回这个位置 140 //点击静音按钮 141 volumecontorl.onclick=function(){ 142 if(video.muted){ 143 removeMuted() 144 volume_inner.style.left=volumeMove 145 volume_down.style.width=volumeMove 146 } 147 else{ 148 muted() 149 volumeMove=volume_inner.style.left 150 volume_inner.style.left=0+'px' 151 volume_down.style.width=0+'px' 152 } 153 } 154 var isFullScreen=false 155 //点击全屏 156 fullScreen.onclick=function(){ 157 if(isFullScreen){ 158 isFullScreen = false 159 if (document.exitFullscreen){ 160 document.exitFullscreen(); 161 } 162 else if (document.mozCancelFullScreen){ 163 document.mozCancelFullScreen(); 164 } 165 else if (document.webkitCancelFullScreen) { 166 document.webkitCancelFullScreen(); 167 } 168 else if (document.msExitFullscreen) { 169 document.msExitFullscreen(); 170 } 171 }else{ 172 isFullScreen = true 173 var docElm = document.documentElement; 174 //W3C 175 if (docElm.requestFullscreen){ 176 docElm.requestFullscreen(); 177 } 178 //FireFox 179 else if (docElm.mozRequestFullScreen) { 180 docElm.mozRequestFullScreen(); 181 } 182 //Chrome等 183 else if (docElm.webkitRequestFullScreen){ 184 docElm.webkitRequestFullScreen(); 185 } 186 //IE11 187 else if(doctlm.msRequestFullscreen) { 188 docElm.msReguestFullscreen() 189 } 190 191 } 192 } 193 194 } 195 //实现静音 196 function muted(){ 197 video.muted=true//静音 198 video.volume=0 199 volumecontorl.classList.add('volumecontorl2') 200 volumecontorl.classList.remove('volumecontorl') 201 } 202 //取消静音 203 function removeMuted(){ 204 video.muted=false 205 video.volume=1 206 volumecontorl.classList.remove('volumecontorl2') 207 volumecontorl.classList.add('volumecontorl') 208 } 209 //拖拉视频音量进度条 210 var callback={ 211 move:function(ev){ 212 process_down.style.width=this.offsetLeft+'px'//让进度条随着鼠标移动而移动,中间的差值需要理清楚 213 video.currentTime=(ev.clientX-process.offsetLeft)/process.clientWidth*video.duration 214 } 215 } 216 drag(inner,callback)//拖拉视频进度 217 var callback2={ 218 move:function(){ 219 volume_down.style.width=this.offsetLeft+'px' 220 video.volume=this.offsetLeft/volume_up.offsetWidth 221 } 222 } 223 224 drag(volume_inner,callback2)//音量 225 //时间格式转换 226 function getTime(time){ 227 var s,f,h 228 time=parseInt(time) 229 h=toZero(Math.floor(time/3600)) 230 f=toZero(Math.floor(time%3600/60)) 231 s=toZero(Math.floor(time%60)) 232 return h+':'+f+':'+s 233 } 234 //时间补0 235 function toZero(n){ 236 if(n<10) 237 n="0"+n 238 return n 239 } 240 //当前时间格式转换 241 function getCurrTime(){ 242 var currTime 243 currTime=setInterval(function(){ 244 var t=video.currentTime 245 current.innerText=getTime(t) 246 if(video.currentTime>=video.duration){ 247 start.classList.remove('pause') 248 start.classList.add('start') 249 video.pause() 250 clearInterval(timer)//播放结束,清除定时器 251 clearInterval(currTime) 252 } 253 },500) 254 return currTime 255 } 256 257 } 258 </script> 259 </html>

1 (function(w){ 2 w.drag=function(testnode,callback){ 3 var testNodeStart={x:0,y:0} 4 testnode.onmousedown=function(ev){ 5 ev=ev||event 6 testnodeStart.x=testnode.offsetLeft//按住滑动块时,获取他相对父元素的位置 7 if(testnode.setCapture){ 8 testnode.setCapture()//开启鼠标捕获,让IE8只能获取到鼠标点击的元素,间接达到效果 9 } 10 var mouseStartNode=ev.clientX//鼠标一开始的位置 11 document.onmousemove=function(ev){ 12 ev=ev||event 13 var nowNode=ev.clientX//鼠标开始移动的位置 14 var L=testnodeStart.x+nowNode-mouseStartNode//元素现在的位置 15 if(L<0)L=0//控制元素位置范围 16 else if(L>testnode.parentNode.clientWidth-testnode.clientWidth)L=testnode.parentNode.clientWidth-testnode.clientWidth 17 testnode.style.left=L+'px' 18 if(callback&&callback['move']&&typeof callback['move']=='function'){ 19 callback['move'].call(testnode,ev)//让回调函数的this指向元素,并把鼠标信息作为参数传递过去 20 } 21 } 22 document.onmouseup=function(){ 23 document.onmouseup=document.onmousemove=null 24 if(document.releaseCapture){ 25 document.releaseCapture()//释放鼠标捕获 26 } 27 } 28 return false//取消浏览器默认行为 29 } 30 } 31 })(window)

1 html,body{ 2 height: 100%; 3 overflow: hidden;//取消浏览器自带滚动条 4 } 5 #wrap{ 6 background-color: #383838; 7 } 8 #wrap>.control{ 9 position: relative; 10 height: 25px; 11 background-color: #2A2A2A; 12 } 13 #wrap>video{ 14 margin: auto; 15 } 16 #wrap>.control>.btns{ 17 position: absolute; 18 width: 55px; 19 height: 25px; 20 } 21 .start,.reset,.pause{ 22 width: 13px; 23 height: 13px; 24 position: absolute; 25 margin-top: 6px; 26 } 27 .start{ 28 background: url(img/开始.png); 29 background-size: 100% 100%; 30 margin-left: 10px; 31 } 32 .pause{ 33 background: url(img/暂停.png); 34 background-size: 100% 100%; 35 margin-left: 10px; 36 } 37 .reset{ 38 background: url(img/重置.png); 39 background-size: 100% 100%; 40 margin-left: 30px; 41 } 42 43 #wrap>.control>.process{ 44 position: relative; 45 width: auto; 46 height: 25px; 47 margin: 0 230px 0 55px; 48 } 49 .process>.process_up{ 50 position: absolute; 51 width: 100%;/*脱离文档流了*/ 52 height: 3px; 53 margin-top: 11px; 54 background-color: #737373; 55 } 56 .process>.process_up>.inner{ 57 position: absolute; 58 width: 9px; 59 height: 7px; 60 margin-top: -2px; 61 background-color: white; 62 border-radius: 50%; 63 } 64 .process>.process_down{ 65 position: absolute; 66 height: 3px; 67 width: 0px; 68 margin-top: 11px; 69 background-color: deeppink; 70 } 71 #wrap>.control>.volume{ 72 position: absolute; 73 width: 230px; 74 height: 25px; 75 right: 0; 76 top: 0; 77 color: white; 78 font-size: 12px; 79 } 80 .text{ 81 display: inline-block; 82 width:40px; 83 margin-left: 10px; 84 margin-top: 6px; 85 } 86 .volumecontorl,.volumecontorl2{ 87 position: absolute; 88 width: 20px; 89 height:20px; 90 } 91 .volumecontorl{ 92 background: url(img/音量.png); 93 background-repeat: no-repeat; 94 background-size: 50% 50%; 95 margin-top: 7px; 96 margin-left: 9px; 97 } 98 .volumecontorl2{ 99 background: url(img/静音.png); 100 background-repeat: no-repeat; 101 background-size: 60% 60%; 102 margin-top: 6px; 103 margin-left: 11px; 104 } 105 .volume_up{ 106 position: absolute; 107 width: 60px;/*脱离文档流了*/ 108 height: 5px; 109 margin: -8px 132px; 110 background-color: #737373; 111 } 112 .volume_inner{ 113 position: absolute; 114 width: 9px; 115 height: 7px; 116 background-color: white; 117 margin-top: -1px; 118 left: 51px; 119 border-radius: 50%; 120 } 121 .volume_down{ 122 position: absolute; 123 height: 5px; 124 width: 51px; 125 margin: -8px 132px; 126 background-color: deeppink; 127 } 128 .full{ 129 position: absolute; 130 width: 20px; 131 height:20px; 132 background: url(img/全屏.png); 133 background-repeat: no-repeat; 134 background-size: 50% 50%; 135 margin-top: -11px; 136 margin-left: 200px; 137 }