HTML5 媒体播放器 video、audio 自定义播放器进度条(上)

简介:当使用到 HTML5 媒体播放器(<video>、<audio>),往往有许多自定义的需求,其中自定义播放进度条就是其中一种常见的需求,因此,这里通过html、css 和 js 实现一简单的媒体播放器进度条,文中简单实现其主要功能,包括加载,点击,拖拽等,若有自定义需求,可在此基础上拓展。

1、绘制基本进度条

关于进度条的实现有很多种方式,也有很多种现成的组件可以使用,在实际项目开发中,可以根据需求选择。但这里还是选择自己来手动实现一简单的进度条,进度条的实现方式大同小异,自定义的进度条有很大的拓展性。

1.1、html 结构

  • 基本说明在代码中体现
    <div class="box">
        <!-- 媒体容器 -->
        <div class="media-box"></div>
        <!-- 进度条容器 -->
        <div id="slide-box">  
            <div id="slide">
                <div id="slide-inside"></div>
            </div>
        </div>
    </div>

1.2、css样式

  • 样式包括后面用到的元素,现在可只关注上面代码中用到的元素样式。
    <style>
        *{
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        .box{
            width: 800px;
            margin: 50px auto ;
        }
        .media-box{
            width: 800px;
            height: 400px;
            border: 1px solid #000;
        }
        #slide-box{
            margin-top: 20px;
            width: 700px;
            height: 26px;
            padding: 8px 0;
            cursor: pointer;
        }
        #slide{
            height: 10px;
            position: relative;
            background-color: #e4e7ed;
            border-radius: 8px;
        }
        #slide-progress, #slide-inside{
            position: absolute;
            top: 0;
            left: 0;
            height: 100%;
            border-radius: 8px;
        }
        #slide-progress{
            background-color: #c6c8c9;
            width: 50%;
            transition: all ease 2s;
        }
        #slide-inside{
            background-color: #f98e2d;
            z-index: 10;
            width: 30%;
            transition: all ease 0.5s;
        }
        #point-box{
            width: 24px;
            height: 24px;
            position: absolute;
            top: 50%;
            left: 30%;
            transform: translate(-50%,-50%);
            z-index: 11;
        }
        .point{
            position: absolute;
            border: 12px solid #fff;
            box-shadow: 1px 1px 2px #454343;
            border-radius: 50%;
        }
        .point:hover{
            transform: scale(1.2);
        }
    </style>

1.3、js代码

  • 让进度条自己简单动起来
        let slideInsideDom = document.getElementById('slide-inside')
        let step = 0
        let max = 100
        let si = setInterval(() => {
            step += 1
            step = step >= max ? max : step
            slideInsideDom.style.width = (step / max ) * 100 + '%'
            if(step >= max){
                clearInterval(si)
            }
        }, 100);

这样就实现了一个简单的可用于展示的进度条,长这样:

 现在离目标动能还缺少:

  • 需要有一个显示加载进度的背景
  • 需要有一个用于拖拽的元素
  • js添加拖拽功能

2、播放器进度条

2.1、html

在上面的基础上添加:

    <div class="box">
        <!-- 媒体容器 -->
        <div class="media-box"></div>
        <!-- 进度条容器 -->
        <div id="slide-box">  
            <div id="slide">
                <!-- 加载进度 -->
                <div id="slide-progress"></div>
                <!-- 主进度 -->
                <div id="slide-inside"></div>
                <!-- 拖拽元素 -->
                <div id="point-box">
                    <div class="point"></div>
                </div>
            </div>
        </div>
    </div>

样式看上面 1.2,上面是全部样式。

2.2 js实现拖拽功能

主要代码实现:

    <script>
        let slideDom = document.getElementById('slide-box')
        let slideInsideDom = document.getElementById('slide-inside')
        let pointBoxDom = document.getElementById('point-box')
        // 获取外层长度
        let extent =  slideDom.getBoundingClientRect().width

        slideDom.addEventListener('mousedown',mousedownFun)

        document.addEventListener('mouseup',mouseupFun)

        // 监听进度条鼠标按下
        function mousedownFun(e){
            setPosition(e)
            console.log('进度条鼠标按下',e.clientX,slideDom.offsetLeft);
            document.addEventListener('mousemove',mousemoveFun)
        }
        function mousemoveFun(e){
            e=e || window.event;
            pauseEvent(e);
            console.log('拖拽移动');
            setPosition(e)
        }
        function mouseupFun(e){
            console.log('鼠标抬起',e.clientX);
            document.removeEventListener('mousemove',mousemoveFun)
        }
        function setPosition(e){
            // 计算拖动长度
            let x = e.clientX - slideDom.offsetLeft
            x = x < 0 ? 0 : x
            x = x >= extent ? extent : x
            slideInsideDom.style.width = ( x / extent ) * 100 + '%'
            pointBoxDom.style.left = ( x / extent ) * 100 + '%'
        }

        //阻止事件冒泡
        //不仅仅要stopPropagation,还要preventDefault
        function pauseEvent(e){
            if(e.stopPropagation) e.stopPropagation();
            if(e.preventDefault) e.preventDefault();
            e.cancelBubble=true;
            e.returnValue=false;
            return false;
        }

    </script>
  • 计算 slide-box 盒子长度

  • 监听 slide-box 盒子 鼠标按下事件,setPosition 计算出鼠标当前横向位置与 slide-box 横向距离的差值,通过差值计算出 slide-inside 长度和 point-box 位置

  • css 文件中 transition 后面的时间需要去掉(添加时间是让 目录1 中效果更明显),

注意:mouseup 事件可能某些情况乱下监听不到,需要拖拽时禁用默认行为并且阻止冒泡;

可参考 JS中mouseup事件丢失的原因与解决办法

以上就基本实现一个进度条的基本功能了,在鼠标按下、鼠标移动拖拽的回调函数中可以实现媒体元素的操作。

下一篇介绍与媒体播放器的交互:HTML5 媒体播放器 video、audio 自定义播放器进度条(下)

完整代码

可直接在网页运行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        .box{
            width: 800px;
            margin: 50px auto ;
        }
        .media-box{
            width: 800px;
            height: 400px;
            border: 1px solid #000;
        }
        #slide-box{
            margin-top: 20px;
            width: 700px;
            height: 26px;
            padding: 8px 0;
            cursor: pointer;
        }
        #slide{
            height: 10px;
            position: relative;
            background-color: #e4e7ed;
            border-radius: 8px;
        }
        #slide-progress, #slide-inside{
            position: absolute;
            top: 0;
            left: 0;
            height: 100%;
            border-radius: 8px;
        }
        #slide-progress{
            background-color: #c6c8c9;
            width: 50%;
            transition: all ease;
        }
        #slide-inside{
            background-color: #f98e2d;
            z-index: 10;
            width: 30%;
            transition: all ease;
        }
        #point-box{
            width: 24px;
            height: 24px;
            position: absolute;
            top: 50%;
            left: 30%;
            transform: translate(-50%,-50%);
            z-index: 11;
        }
        .point{
            position: absolute;
            border: 12px solid #fff;
            box-shadow: 1px 1px 2px #454343;
            border-radius: 50%;
        }
        .point:hover{
            transform: scale(1.2);
        }
    </style>
</head>
<body>
    <div class="box">
        <!-- 媒体容器 -->
        <div class="media-box"></div>
        <!-- 进度条容器 -->
        <div id="slide-box">  
            <div id="slide">
                <!-- 加载进度 -->
                <div id="slide-progress"></div>
                <!-- 主进度 -->
                <div id="slide-inside"></div>
                <!-- 拖拽元素 -->
                <div id="point-box">
                    <div class="point"></div>
                </div>
            </div>
        </div>
    </div>

    <script>
        let slideDom = document.getElementById('slide-box')
        let slideInsideDom = document.getElementById('slide-inside')
        let pointBoxDom = document.getElementById('point-box')
        // 获取外层长度
        let extent =  slideDom.getBoundingClientRect().width

        slideDom.addEventListener('mousedown',mousedownFun)

        document.addEventListener('mouseup',mouseupFun)

        // 监听进度条鼠标按下
        function mousedownFun(e){
            setPosition(e)
            console.log('进度条鼠标按下',e.clientX,slideDom.offsetLeft);
            document.addEventListener('mousemove',mousemoveFun)
        }
        function mousemoveFun(e){
            e=e || window.event;
            pauseEvent(e);
            console.log('拖拽移动');
            setPosition(e)
        }
        function mouseupFun(e){
            console.log('鼠标抬起',e.clientX);
            document.removeEventListener('mousemove',mousemoveFun)
        }
        function setPosition(e){
            // 计算拖动长度
            let x = e.clientX - slideDom.offsetLeft
            x = x < 0 ? 0 : x
            x = x >= extent ? extent : x
            slideInsideDom.style.width = ( x / extent ) * 100 + '%'
            pointBoxDom.style.left = ( x / extent ) * 100 + '%'
        }

        //阻止事件冒泡
        //不仅仅要stopPropagation,还要preventDefault
        function pauseEvent(e){
            if(e.stopPropagation) e.stopPropagation();
            if(e.preventDefault) e.preventDefault();
            e.cancelBubble=true;
            e.returnValue=false;
            return false;
        }

        // let step = 0
        // let max = 100
        // let si = setInterval(() => {
        //     step += 1
        //     step = step >= max ? max : step
        //     slideInsideDom.style.width = (step / max ) * 100 + '%'
        //     if(step >= max){
        //         clearInterval(si)
        //     }
        // }, 100);

    </script>
</body>
</html>

  • 15
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值