效果图:
video.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>video</title> <style> *{margin:0;padding:0;list-style: none;} /*body{background:#d0d8e9;}*/ /*要么不加position,如果加了则必须同时设置body和height高度为100%*/ html,body{ background:#d0d8e9; position: relative; height:100%; } .box{width:540px;height:332px;box-shadow:0 0 4px #d0d8e9;position: absolute;left:50%;top:50%;margin:-166px 0 0 -270px;} .videoNode{width:540px;height:305px;/*float布局可以清除上下间的空隙*/float:left;background-color: #000;} .ctrNode{width:540px;height:27px;/*gif格式容量更小*/background:url(data/ctrl_bg.gif) repeat-x;float:left;} .playNode{float:left;width:13px;height:15px;margin:6px 0 0 14px;/*png更清晰*/background:url(data/playbtn.png) no-repeat;cursor:pointer;} .pauseNode{float:left;width:13px;height:15px;margin:6px 0 0 14px;/*png更清晰*/background:url(data/pause.png) no-repeat;cursor:pointer;} /*时间进度条部分*/ .processNode{width:260px;height:9px;background:url(data/ctrl_bg.gif) top repeat-x;margin:9px 0 0 14px;float:left;position: relative;} .processLeft{position: absolute;left:-2px;top:0;background:url(data/proleft.png) no-repeat;width:4px;height:9px;} .processRight{position: absolute;right:-2px;top:0;background:url(data/right_bg.png) no-repeat;width:4px;height:9px;} .processCircle{position: absolute;left:-8.5px;top:-3px;background:url(data/circle.png) no-repeat;width:17px;height:17px;cursor:pointer;z-index:5;} .lineNode{width:0%;height:100%;position: absolute;top:0;left:0;background:url(data/line_bg.png) repeat-x;} .lineRight{position: absolute;width:2px;height:7px;top:0;right:0;background:url(data/line_r_bg.png) no-repeat;} /*声音进度条部分*/ .timeNode{float:left;width:57px;height:10px;margin:9px 0 0 9px;} .timeNode span{float:left;line-height:10px;font-size:10px;color:#fff;} .volumeNode{width:19px;height:17px;float:left;margin:6px 10px 0 17px;background:url(data/volume.png) no-repeat;} .vProcessNode{width:61px;height:9px;/*background:url(data/probg.gif) top repeat-x;*/margin:9px 0 0 4px;float:left;position: relative;} .vLineNode{width:61px;height:100%;position: absolute;top:1px;left:0;background:url(data/line_bg.png) repeat-x;} .vLineRight{position: absolute;width:2px;height:7px;top:0;right:0;background:url(data/line_r_bg.png) no-repeat;} #vCircleNode{left:52px;} /*全屏部分*/ .fullNode{width:13px;height:15px;background:url(data/full.png) no-repeat;margin:6px 0 0 40px;float:left;cursor:pointer;} .fullNode:hover{transform:scale(1.1);/*transition:all .5s;*/} </style> </head> <body> <div class="box"> <video class="videoNode" src="data/imooc.mp4" poster="data/poster.jpg"></video> <div class="ctrNode"> <!-- 声音播放 --> <div class="playNode"></div> <!-- 时间调节 --> <div class="processNode"> <div class="processLeft"></div> <div class="processRight"></div> <div class="processCircle" id="circleNode"></div> <!-- 真正的进度条 --> <div class="lineNode"> <div class="lineRight"></div> </div> </div> <!-- 时间显示 --> <div class="timeNode"> <span class="now">00:00</span> <span>-</span> <span class="all">00:00</span> </div> <div class="volumeNode"></div> <!-- 音量调节 --> <div class="vProcessNode"> <div class="processLeft"></div> <div class="processRight"></div> <div class="processCircle" id="vCircleNode"></div> <!-- 真正的进度条 --> <div class="vLineNode"> <div class="vLineRight"></div> </div> </div> <!-- 全屏 --> <div class="fullNode"></div> </div> </div> <script> var playNode=document.getElementsByClassName("playNode")[0], videoNode=document.getElementsByClassName("videoNode")[0], fullNode=document.querySelector(".fullNode"), // 声音显示 nowNode=document.querySelector(".now"), allNode=document.querySelector(".all"), // 时间进度条 processNode=document.querySelector(".processNode"), lineNode=document.querySelector(".lineNode"), circleNode=document.querySelector("#circleNode"), processCircle=document.querySelector("#processCircle"), // 声音进度条 vProcessNode=document.querySelector(".vProcessNode"), vLineNode=document.querySelector(".vLineNode"), playState=true; // 播放暂停 playNode.onclick=function(){ //es6语法 //注意:要切换的样式一定要在初始样式的下面定义,否则无法进行覆盖 //this.classList.toggle("pauseNode"); //传统语法 playState=!playState; if(playState){ this.className="playNode"; videoNode.pause(); }else{ this.className="pauseNode"; videoNode.play(); } } //全屏 fullNode.onclick=function(){ if(videoNode.webkitRequestFullscreen){ videoNode.webkitRequestFullscreen(); }else if(videoNode.mozRequestFullScreen){ videoNode.mozRequestFullScreen(); }else{ videoNode.requestFullscreen(); } } //时间显示(解决时间初始的NaN问题) videoNode.addEventListener("canplay",function(){ var duration=videoNode.duration; var aMin=toDou(parseInt(duration/60)); var aSec=toDou(parseInt(duration%60)); allNode.innerHTML=aMin+":"+aSec; },false); //视频播放时,更新当前时间 videoNode.addEventListener("timeupdate",function(){ var curTime=videoNode.currentTime; var cMin=toDou(parseInt(curTime/60)); var cSec=toDou(parseInt(curTime%60)); nowNode.innerHTML=cMin+":"+cSec; //进度条运动 lineNode.style.width=(curTime/videoNode.duration*100)+"%"; circleNode.style.left=lineNode.offsetWidth-8.5+"px"; },false); //时间格式转换 function toDou(time){ return time<10?"0"+time:time; } //拖拽进度条 circleNode.onmousedown=function(e){ videoNode.pause(); var el=e||event;//有些IE版本无法获取事件对象e,只能通过window.event来获取 //offsetLeft是一个元素到父级左边的距离 //clientX返回当事件被触发时鼠标指针相对于浏览器页面(或客户区)的水平坐标 //l是还没运动时,circleNode中心点距离屏幕左边的距离 var l=el.clientX-this.offsetLeft; //将鼠标移动和抬起事件绑定在document上是为了防止鼠标拖动过快,超出拖动的元素,不能正常拖动和抬起无效,鼠标再次移入的时候会出现问题。 //如果绑定到crlNode,鼠标移动过快的时候,移出这个元素,就不能正常的拖动 document.onmousemove=function(e){ var el=e||event; //el.clientX是鼠标按下位置距离浏览器页面(或客户区)的水平位置 //needX是circleNode距离初始位置移动的距离 var needX=el.clientX-l; //控制左右边界 var maxX=processNode.offsetWidth-8.5; needX=needX<-8.5?-8.5:needX; needX=needX>maxX?maxX:needX; //offsetLeft是只读模式,改变位置要用style.left circleNode.style.left=needX+"px"; //进度跟着走 //+9是为了保证左右两端分别是0和1 lineNode.style.width=(circleNode.offsetLeft+9)/processNode.offsetWidth*100+"%"; } document.onmouseup=function(){ //鼠标松开时清除事件 document.onmousemove=document.onmouseup=null; videoNode.currentTime=videoNode.duration*(circleNode.offsetLeft+9)/processNode.offsetWidth; videoNode.play(); playState=false; if(playState){ playNode.className="playNode"; videoNode.pause(); }else{ playNode.className="pauseNode"; videoNode.play(); } } return false;//阻止默认事件 } //拖拽声音 vCircleNode.onmousedown=function(e){ var el=e||event; var l=el.clientX-this.offsetLeft; document.onmousemove=function(e){ var el=e||event; var needX=el.clientX-l; var maxX=vProcessNode.offsetWidth-9; needX=needX<-8.5?-8.5:needX; needX=needX>maxX?maxX:needX; vCircleNode.style.left=needX+"px"; vLineNode.style.width=(vCircleNode.offsetLeft+9)/vProcessNode.offsetWidth*100+"%"; var toVolume=(vCircleNode.offsetLeft+9)/vProcessNode.offsetWidth; toVolume=toVolume<0?0:toVolume; videoNode.volume=toVolume; } document.onmouseup=function(){ document.onmousemove=document.onmouseup=null; } return false; } </script> </body> </html>
知识点补充:
onmouseup事件与onmousemove事件并不冲突,即使鼠标已经松开,也可以执行onmousemove事件
offsetLeft是只读模式,改变要用style.left
在做拖动功能,但是遇到如下图所示问题:
在点击CrlNode然后把鼠标往下移的时候会出现一个禁止符号,然后再松开鼠标,onmousemove事件并没有置null
后面鼠标左右移动的时候我已经松开了鼠标,但是CrlNode还是会跟着两边跑
这是因为拖动的时候鼠标直接到了页面中,相当于把按钮拖拽到页面中,而元素默认是不允许被放置的,需要阻止默认事件