系統城裝機大師 - 唯一官網:www.www.newsthatmovesu.com!

當前位置:首頁 > 網頁制作 > 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連載72-動畫效果及其他屬性

    一、動畫效果 1.過渡與動畫相類似,都需要三要素,那么他們的區別在哪里呢? ?答:過渡必須是人為的觸發才會執行動畫,動畫不需要人為的觸發就可以自動執行?動畫。 2.?相同點: (1)過度和動畫都是用來給元素添加動畫的;(2)過渡...

    2020-03-04

  • 徹底搞懂flex彈性盒模型布局

    為什么要用flex 基于css3簡單方便,更優雅的實現,瀏覽器兼容性好,傳統的css實現一個div居中布局要寫一堆代碼,而現在幾行代碼就搞定了,沒有理由不用flex。...

    2020-02-28

系統教程欄目

欄目熱門教程

人氣教程排行

站長推薦

熱門系統下載

24小时免费更新在线视频_丝袜放荡妩媚美腿娇妻_99re6这里有精品热视频_国色天香社区论坛