系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 网页制作 > HTML/Xhtml > 详细页面

HTML5 video自定义视频播放器

时间:2020-03-04来源:电脑系统城作者:电脑系统城

 

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

 

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

分享到:

相关信息

  • HTML静态页面获取url参数和UserAgent的实现

    本文主要介绍了HTML静态页面获取url参数和UserAgent的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值...

    2022-09-12

  • html网页引入svg图片的4种方式

    web应用开发使用svg图片,总结了下,可以有如下4种方式: 1. 直接插入页面。 2. img标签引入。 3. css引入。 4. object标签引入。...

    2022-09-12

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载