• HTML5 video自定义视频播放器


    效果图:

    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还是会跟着两边跑

     这是因为拖动的时候鼠标直接到了页面中,相当于把按钮拖拽到页面中,而元素默认是不允许被放置的,需要阻止默认事件

  • 相关阅读:
    常见的分布
    ubuntu16.04获取root权限并用root用户登录
    神经网络与深度学习邱锡鹏学习笔记16多项式回归
    什么是公版显卡,什么是非公版显卡
    高考电子监控揭秘
    买了个2手睡袋
    HTML
    又是一天
    我也想去看珠峰
    Qt 主界面菜单栏和状态栏实现
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12405147.html
Copyright © 2020-2023  润新知