博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
创建简单的js原生组件之————创建一个好看的html5播放器
阅读量:5885 次
发布时间:2019-06-19

本文共 15249 字,大约阅读时间需要 50 分钟。

一、介绍

由于工作需求,原生的html5播放器虽然好用,但是ui不是太好看(个人觉得还可以)但是过不了设计的眼光,所以需要创建一个好看的播放器组件。一个组件的好处用面向对象的方式来讲就相当于一个类,你可以重复的去新建这个类,生成重复的组件对象。在这里,相当于你可以在同一个页面用new的方式,方便的创建多个自定义的播放器。

html5播放器原理:其实无非还是使用了html5的audio元素,然后基于audio的api自己去写播放器各个方法(播放、暂停、进度条、声音控制)等等,我看了下网易的云音乐的播放器,也是采用的audio的API来控制的。

原生audio控件:

图片描述

网易云音乐皮肤:

图片描述

笔者的audio皮肤(虽然挺一般的,但是跟公司的网站色系比较统一)

图片描述

二、创建简单js组件原理

首先一个js插件关键的要点就是 不依赖、不污染、独立,不依赖与其它的方法和元素,独立自成一体。

最多基于jquery的插件会依赖于jquery,我也写过一些jquery的插件,但是这次要写的是完全基于原生js的插件。

使用IIFE架构

IIFE:immediately invoked functional expression 就是我们平常所说的立即执行函数:

(function() {}());

然后我们需要一个构造函数来实现一个类,关于如何用js实现类可以参考一些js的书籍,这里我们使用构造函数的方式。在立即执行函数中的作用域是全局 window, 函数中的this 就代表的是 window ,如下先定义this.AudioPlayer 就等于window.AudioPlayer , 这样相当于AudioPlayer这个变量名称已经在全局作用域中使用了。

(function() {this.AudioPlayer = function AudioPlayer() {}}());

然后建立一个对象就简单了,直接 var _audioPlayer = new AudioPlayer()就创建了一个对象。

传入参数

一般来讲,一个对象总会有一些初始化参数,比如我们的播放器AudioPlayer就可以有 音乐的url参数,是否需要音量控制的参数等等。 我们在构造函数的内部需要创建一个缺省的参数对象defaults,然后还需要有一个传入的参数和缺省的参数相互匹配的一个方法。

(function(){    this.AudioPlayer = function AudioPlayer() {        var config;                //定义缺省参数        var defaults = {            audiodom:'',            audiosrc:'',            showVolume:true        }        //传入的参数于缺省参数的对应        if (arguments[0] && typeof arguments[0] === "object") {            config = extendDefaults(defaults, arguments[0]);        }    }                function extendDefaults(source, properties) {        var property;        for(property in properties) {            if (properties.hasOwnProperty(property)) {                source[property] = properties[property];            }        }        return source;    }})();

使用prototype创建公有方法

公有方法的作用很明显,可以创建这个对象的一些在外部需要调用的功能,如: 我在这里简单的写了一个当播放器切换音乐来源url的时候的一个公有方法,因为当需要换音乐url的时候,不需要再去重新创建一个播放器对象了。

AudioPlayer.prototype.setAudioSrc = function (src) {        this.audioPlayer.setAttribute('src',src);    }

整合在一起写就是这样:

(function(){    this.AudioPlayer = function AudioPlayer() {        var config;                //定义缺省参数        var defaults = {            audiodom:'',            audiosrc:'',            showVolume:true        }        //传入的参数于缺省参数的对应        if (arguments[0] && typeof arguments[0] === "object") {            config = extendDefaults(defaults, arguments[0]);        }    }           //公有方法    AudioPlayer.prototype.setAudioSrc = function (src) {        this.audioPlayer.setAttribute('src',src);    }         function extendDefaults(source, properties) {        var property;        for(property in properties) {            if (properties.hasOwnProperty(property)) {                source[property] = properties[property];            }        }        return source;    }})();

总结:这样基本上写一个简单js组件的框架就搭建起来了,在里面不断的加入方法和功能就可以了。

三、编写一个html5播放器

以下就是一个播放器的js代码,css部分我就不贴出代码来了,附上github 的地址:

(function () {    this.AudioPlayer = function AudioPlayer() {        var config;        // Define option defaults        var defaults = {            audiodom:'',            audiosrc:'',            showVolume:true        }        // Create options by extending defaults with the passed in arugments        if (arguments[0] && typeof arguments[0] === "object") {            config = extendDefaults(defaults, arguments[0]);        }        var duration;        var myAudioPlayer = document.createElement("div");        var audioPlayer = document.createElement("audio");        var playButton = document.createElement("button");        var timeLine = document.createElement("div");        var timeProgressBar = document.createElement("span");        var playhead = document.createElement("div");        var currentTime = document.createElement("div");        var volumeLine = document.createElement("div");        var volumeLineBar = document.createElement("span");        var volumeLineHead = document.createElement("div");        var volumeHorn = document.createElement('span');        var playheadSpan = document.createElement('span');        var timelineWidth = 230;        var volumelinewidth = 50;        var onplayhead = false;        var volumeStatus = [];        this.myAudioPlayer = myAudioPlayer;        this.playhead = playhead;        this.timeProgressBar = timeProgressBar;        this.timelineWidth = timelineWidth;        this.playButton = playButton;        this.currentTime = currentTime;        this.transTime = transTime;        this.intialStatus = intialStatus;        this.playStatus = playStatus;        this.volumeHorn = volumeHorn;        this.audioPlayer = audioPlayer;        myAudioPlayer.className = "audioplayer";        playButton.className = "playbutton play";        timeLine.className = "timeline";        timeProgressBar.className = "time-progress-bar";        playhead.className = "playhead intial";        playheadSpan.className = 'round';        currentTime.className = "current-time";        audioPlayer.setAttribute('controls', 'controls');        audioPlayer.style.display = "none";        volumeLine.className = "audio-line";        volumeLineHead.className = "audio-line-head";        volumeLineBar.className = "audio-line-bar";        volumeHorn.className = 'horn full';        if(config.audiodom === ''){            document.body.appendChild(myAudioPlayer);        }else{            document.getElementById(config.audiodom).appendChild(myAudioPlayer);        }        myAudioPlayer.appendChild(playButton);        playhead.appendChild(playheadSpan);        timeLine.appendChild(timeProgressBar);        timeLine.appendChild(playhead);        myAudioPlayer.appendChild(timeLine);        myAudioPlayer.appendChild(currentTime);        myAudioPlayer.appendChild(audioPlayer);        volumeLine.appendChild(volumeLineBar);        volumeLine.appendChild(volumeLineHead);        myAudioPlayer.appendChild(volumeHorn);        myAudioPlayer.appendChild(volumeLine);        if (config.hasOwnProperty("audiosrc")) {            audioPlayer.setAttribute('src', config.audiosrc);        }        else{            playButton.setAttribute("disabled", "disabled");            timeLine.setAttribute("disabled", "disabled");            volumeLine.setAttribute("disabled", "disabled");            playhead.setAttribute("disabled", "disabled");            volumeLineHead.setAttribute("disabled", "disabled");            volumeHorn.setAttribute("disabled", "disabled");        }        if(config.hasOwnProperty("showVolume")){            if(!config.showVolume){                volumeLine.style.display='block';                volumeLineHead.style.display='block';                volumeLineBar.style.display='block';                myAudioPlayer.style.width ='430px';            }        }        audioPlayer.addEventListener('loadedmetadata',function(){            currentTime.innerHTML = transTime(parseInt(audioPlayer.duration));        },false);        playButton.addEventListener('click', play, false);        audioPlayer.addEventListener('timeupdate', timeUpdate, false);        audioPlayer.addEventListener('canplaythrough', function () {            duration = audioPlayer.duration;        }, false);        timeLine.addEventListener('click', function (event) {            moveplayhead(event);            audioPlayer.currentTime = duration * clickPercent(event);        }, false);        playhead.addEventListener('mousedown', mouseDown, false);        window.addEventListener('mouseup', mouseUp, false);        volumeLine.addEventListener('click', function (event) {            movevolumehead(event);            audioPlayer.volume = volumeClickPercent(event);            if (audioPlayer.volume == 0) {                volumeHorn.className = 'horn';            }else if(audioPlayer.volume>=0.8){                volumeHorn.className = 'horn full';            }else if(audioPlayer.volume>=0.5){                volumeHorn.className = 'horn two';            }else if(audioPlayer.volume>0){                volumeHorn.className = 'horn one';            }        }, false);        //volumeLineHead.addEventListener('mousedown', volumeMouseDown, false);        //window.addEventListener('mouseup', volumeMouseUp, false);        //声音按钮控制        volumeHorn.addEventListener('click',function(event){            if (audioPlayer.volume > 0) {                volumeStatus[0] = audioPlayer.volume;                volumeStatus[1] = volumeHorn.className;                volumeStatus[2] = volumeLineBar.style.width;                volumeStatus[3] = volumeLineHead.style.marginLeft;                volumeHorn.className = 'horn';                movevolumehead(event);                audioPlayer.volume = volumeClickPercent(event);            }else{                audioPlayer.volume = volumeStatus[0];                volumeHorn.className = volumeStatus[1];                volumeLineBar.style.width = volumeStatus[2];                volumeLineHead.style.marginLeft = volumeStatus[3];            }        },false);        //样式调整        //设置成初始状态        function intialStatus(){            playhead.className = 'playhead intial';        }        //设置成播放状态        function playStatus(){            playhead.className = 'playhead';        }        function mouseDown() {            //样式调整            playStatus();            onplayhead = true;            window.addEventListener('mousemove', moveplayhead, true);            audioPlayer.removeEventListener('timeupdate', timeUpdate, false);        }        function mouseUp(e) {            //样式调整            if (parseInt(playhead.style.marginLeft) <= 0) {                intialStatus();            }            if (onplayhead == true) {                moveplayhead(e);                window.removeEventListener('mousemove', moveplayhead, true);                // change current time                audioPlayer.currentTime = duration * clickPercent(e);                audioPlayer.addEventListener('timeupdate', timeUpdate, false);            }            onplayhead = false;        }        function clickPercent(e) {            var timelineleft = getOffsetLeft(timeLine);            return (e.pageX - timelineleft) / timelineWidth;        }        function volumeClickPercent(e) {            var volume = 0;            var volumeLineLeft = getOffsetLeft(volumeLine);            if ((e.pageX - volumeLineLeft) / volumelinewidth < 0)volume = 0;            if ((e.pageX - volumeLineLeft) / volumelinewidth > 1)volume = 1;            if ((e.pageX - volumeLineLeft) / volumelinewidth >= 0 && (e.pageX - volumeLineLeft) / volumelinewidth <= 1)volume = (e.pageX - volumeLineLeft) / volumelinewidth;            return volume;        }        function moveplayhead(e) {            var timelineleft = getOffsetLeft(timeLine);            var newMargLeft = e.pageX - timelineleft;            if (newMargLeft >= 0 && newMargLeft <= timelineWidth) {                playhead.style.marginLeft = newMargLeft + "px";                timeProgressBar.style.width = newMargLeft * 100 / timelineWidth + "%";            }            if (newMargLeft < 0) {                playhead.style.marginLeft = "0px";                timeProgressBar.style.width = "0%";            }            if (newMargLeft > timelineWidth) {                playhead.style.marginLeft = timelineWidth + "px";                timeProgressBar.style.width = "100%";            }        }        function movevolumehead(e) {            var volumeLineLeft = getOffsetLeft(volumeLine);            var newMargLeft = e.pageX - volumeLineLeft;            if (newMargLeft >= 0 && newMargLeft <= volumelinewidth) {                volumeLineHead.style.marginLeft = newMargLeft-10 + "px";                volumeLineBar.style.width = newMargLeft * 100 / volumelinewidth + "%";            }            if (newMargLeft < 0) {                volumeLineHead.style.marginLeft = "-10px";                volumeLineBar.style.width = "0%";            }            if (newMargLeft > timelineWidth) {                volumeLineHead.style.marginLeft = volumelinewidth-10 + "px";                volumeLineBar.style.width = "100%";            }        }        function play() {            //样式控制            playStatus();            // start music            if (audioPlayer.paused) {                audioPlayer.play();                // remove play, add pause                playButton.className = "";                playButton.className = "playbutton pause";            } else { // pause music                audioPlayer.pause();                // remove pause, add play                playButton.className = "";                playButton.className = "playbutton play";            }        }        function timeUpdate() {            var playPercent = audioPlayer.currentTime / duration;            var playPercentWidth = timelineWidth * playPercent;            var playTime = transTime(parseInt(audioPlayer.currentTime));            currentTime.innerHTML = playTime;            playhead.style.marginLeft = playPercentWidth + "px";            timeProgressBar.style.width = playPercent * 100 + "%";            if (audioPlayer.currentTime == duration) {                playButton.className = "";                playButton.className = "playbutton play";            }        }        function transTime(time){            if (time<10) {                return('00:0'+time);            }else if(time<60){                return('00:'+time);            }else if(time<600){                var i = parseInt(time/60);                var j = parseInt(time%60);                if (j<10) {                    return('0'+i+':0'+j);                }else{                    return('0'+i+':'+j);                }            }else if(time<6000){                var i = parseInt(time/60);                var j = parseInt(time%60);                if (j<10) {                    return(i+':0'+j);                }else{                    return(i+':'+j);                }            }else{                return time;            }        }        function volumeMouseDown() {            onplayhead = true;            window.addEventListener('mousemove', movevolumehead, true);            //audioPlayer.removeEventListener('timeupdate', timeUpdate, false);        }        function volumeMouseUp(e) {            if (onplayhead == true) {                movevolumehead(e);                window.removeEventListener('mousemove', movevolumehead, true);                audioPlayer.volume = volumeClickPercent(e);            }            onplayhead = false;        }        function getOffsetLeft( elem )        {            var offsetLeft = 0;            do {                if ( !isNaN( elem.offsetLeft ) )                {                    offsetLeft += elem.offsetLeft;                }            } while( elem = elem.offsetParent );            return offsetLeft;        }    }    AudioPlayer.prototype.getAudioPlayer = function () {        return this.myAudioPlayer;    };    AudioPlayer.prototype.setAudioSrc = function (src) {        this.audioPlayer.setAttribute('src',src);    }        // Utility method to extend defaults with user options    function extendDefaults(source, properties) {        var property;        for (property in properties) {            if (properties.hasOwnProperty(property)) {                source[property] = properties[property];            }        }        return source;    }})();

在html中调用js播放器组件

在html调用就比较简单了,只需要一点点的代码,甚至不需要了解audio标签,就可以生成两个互不冲突的音乐播放器。

结果如下:

图片描述

转载地址:http://hzmix.baihongyu.com/

你可能感兴趣的文章
nodejs
查看>>
Android ViewPager多页面滑动切换以及动画效果
查看>>
redis错误总结
查看>>
ecshop 批量删除购物车商品
查看>>
Hunting for Sensitive Data with the Veil-Framework
查看>>
mysql中now,curdate,curtime,sysdate区别
查看>>
初始化一个list集合
查看>>
js如何获取当前时间并对时间进行比较?
查看>>
MySql远程访问及防火墙设置
查看>>
XCode 已有项目添加 Git
查看>>
windows安装解压版mysql5.6以上
查看>>
位域,链接指示
查看>>
exchange 2013 相关日志查询
查看>>
Centos7-修复心脏滴血漏洞
查看>>
WINDOWS 2008 R2增量备份
查看>>
Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead.
查看>>
shell 中利用getopts
查看>>
我的友情链接
查看>>
PowerShell 基本概念
查看>>
block,inline和inline-block概念和区别
查看>>