Namespace.register("U.MD.UI.video"); //注册命名空间 /** * 创建视频 * @param src 资源地址 * @param width 视频宽度 * @param height 视频高度 * @param autoplay 是否自动播放 * @param parent 生成在哪个元素 */ U.MD.UI.video = function (src, width, height, autoplay, parent) { var _autoplay = autoplay || false; //检测自动播放 var _intervalTemp = null; //用于记录interval的值 var _volumeTemp = null; //用于记录临时音量(静音与取消静音用) var _moving = false; //记录是否有移动 var _tempHeight = ""; //全屏恢复的临时高度 var _tempWidth = ""; //全屏恢复的临时宽度 var _fullscreen = false; //记录是否处于全屏状态 /*生成元素*/ var _els = U.MD.UI.video.appendEle(src, width, height, _autoplay, parent); /*添加事件*/ U.MD.UI.video.addEvent(_els, _intervalTemp, _volumeTemp, _moving, height, width, _fullscreen); return _els; }; /** * 生成元素 * @param src 视频资源地址 * @param width 视频宽度 * @param height 视频高度 * @param autoplay 是否自动播放 * @param parent 父元素 */ U.MD.UI.video.appendEle = function (src, width, height, autoplay, parent) { var els = {}; //包括视频和控制器的大div els.videoDiv = $$("div", { "className": "U_MD_UI_video_VideoDiv", "style": { "width": width + "px", "height": height + "px"} }, parent); //视频主体 els.video = $$("video", { "src": src, //视频资源地址 "className": "U_MD_UI_video_VideoMain", //视频class "autoplay": autoplay, //是否自动播放 "preload": "auto"//是否预加载(默认自动) }, els.videoDiv); //控制器主体 els.controls = $$("div", { "className": "U_MD_UI_video_VideoControls" }, els.videoDiv); //暂停/播放按钮 els.playPauseBtn = $$("div", { "className": "U_MD_UI_video_PlayPauseButton U_MD_UI_video_PlayIcon" }, els.controls); //显示当前时间的div els.currentTimeDiv = $$("div", { "className": "U_MD_UI_video_Time", "innerHTML": "00:00" }, els.controls); //进度条 els.progress = $$("div", { "className": "U_MD_UI_video_Progress" }, els.controls); //进度条实际进度 els.progressCurrentTime = $$("div", { "className": "U_MD_UI_video_ProgressCurrentTime" }, els.progress); //进度条上的圆点 els.progressCircle = $$("div", { "className": "U_MD_UI_video_ProgressCircle" }, els.progressCurrentTime); //显示实际时间的div els.DurationDiv = $$("div", { "className": "U_MD_UI_video_Time", //设置class "innerHTML": "00:00", //设置默认值 "onselectstart": "return false;"//禁止选择 }, els.controls); //音量按钮 els.soundControls = $$("div", { "className": "U_MD_UI_video_SoundControls" }, els.controls); //音量 els.soundProgress = $$("div", { "className": "U_MD_UI_video_SoundProgress" }, els.controls); //真实音量 els.soundProgressCurrent = $$("div", { "className": "U_MD_UI_video_SoundProgressCurrent", "style": { "width": "100%"} }, els.soundProgress); //设置class //全屏按钮 els.fullScreenBtn = $$("div", { "className": "U_MD_UI_video_FullScreen" }, els.controls); return els; }; /** * 给元素添加事件 * @param els 传入所有元素 * @param intervalTemp 传入intervalTemp * @param volumeTemp 传入volumeTemp * @param moving 传入moving * @param tempHeight 传入tempHeight * @param tempWidth 传入tempWidth * @param fullscreen 传入fullscreen */ U.MD.UI.video.addEvent = function (els, intervalTemp, volumeTemp, moving, tempHeight, tempWidth, fullscreen) { //给暂停/播放按钮添加事件 els.playPauseBtn.onclick = function (event) { U.MD.UI.playPauseBtnClick(event, els); }; if (els.videoDiv.onwebkitfullscreenchange !== undefined) {//设置全屏状态事件(webkit) els.videoDiv.onwebkitfullscreenchange = function () { var rtn = U.MD.UI.video.fullscreenChange(fullscreen, tempHeight, tempWidth, els); fullscreen = rtn[0]; tempHeight = rtn[1]; tempWidth = rtn[2]; } } else if (els.videoDiv.onfullscreenchange !== undefined) {//设置全屏状态事件(w3) els.videoDiv.onfullscreenchange = function () { var rtn = U.MD.UI.video.fullscreenChange(fullscreen, tempHeight, tempWidth, els); //设置全屏状态事件(w3) fullscreen = rtn[0]; tempHeight = rtn[1]; tempWidth = rtn[2]; } } else if (els.videoDiv.onmozfullscreenchange !== undefined) {//设置全屏状态事件(moz) els.videoDiv.onmozfullscreenchange = function () { var rtn = U.MD.UI.video.fullscreenChange(fullscreen, tempHeight, tempWidth, els); fullscreen = rtn[0]; tempHeight = rtn[1]; tempWidth = rtn[2]; } } /** * 全屏按钮单击事件 */ els.fullScreenBtn.onclick = function () { U.MD.UI.video.fullscreenClick(fullscreen, els); }; /** * 进度条圆点按下事件 * @param event 按下事件 */ els.progressCircle.onmousedown = function (event) { U.MD.UI.video.circleMove(event, moving, els); }; /** * 音量条鼠标按下事件 * @param event 事件 */ els.soundProgress.onmousedown = function (event) { U.MD.UI.video.soundProgressMove(event, els, moving); //执行soundProgressMove函数 }; /** * 进度条鼠标按下事件 * @param event 事件 */ els.progress.onmousedown = function (event) { U.MD.UI.video.progressMove(event, els, moving); //进度条按下移动函数(点击进度条除圆点以外的地方) }; /** * 视频暂停事件,用于设置暂停按钮与停止刷新 */ els.video.onpause = function () { els.playPauseBtn.className = "U_MD_UI_video_PlayPauseButton U_MD_UI_video_PlayIcon"; //设置暂停按钮的icon(修改class) clearInterval(intervalTemp); //清除刷新的interval }; /** * 视频播放事件,用于设置播放按钮与启动刷新 */ els.video.onplay = function () { els.playPauseBtn.className = "U_MD_UI_video_PlayPauseButton U_MD_UI_video_PauseIcon"; //设置开始按钮的icon(修改class) intervalTemp = U.MD.UI.video.setInterval(moving, els); //启动刷新 }; /** * 视频可以播放,刷新数据 */ els.video.oncanplay = function () { U.MD.UI.video.flushInfo(moving, els.currentTimeDiv, els.DurationDiv, els.progressCurrentTime, els.soundProgressCurrent, els.video); //刷新信息 }; /** * 静音按钮事件函数 */ els.soundControls.onclick = function () { volumeTemp = U.MD.UI.video.muteClick(els, volumeTemp, moving); }; /** * 控制栏显示/隐藏控制 */ els.videoDiv.onclick = function () { //U.MD.UI.video.displayControls(event, els); }; }; /** * 让控制栏可以隐藏 * @param event 视频点击事件 * @param els 元素集合 */ U.MD.UI.video.displayControls = function (event, els) { var _target = event.target; //获取目标 if (_target === els.video || _target === els.videoDiv) {//判断目标点击后是否可以隐藏/显示 if (els.controls.style.display === "none") {//如果已设置隐藏状态则显示 els.controls.style.display = "block"; } else {//否则隐藏控制栏 els.controls.style.display = "none"; } } }; U.MD.UI.playPauseBtnClick = function (event, els) { var _el = event.target; //获取到按钮本身 if (_el.className === "U_MD_UI_video_PlayPauseButton U_MD_UI_video_PlayIcon") {//暂停状态 els.video.play(); //开始播放 } else {//播放状态 els.video.pause(); //暂停播放 } }; /** * 静音按钮 * @param els 元素集合 * @param volumeTemp 临时记录音量 * @param moving 记录是否正在移动(刷新数据用) * @returns {*} 返回volumeTemp */ U.MD.UI.video.muteClick = function (els, volumeTemp, moving) { if (els.video.volume !== 0) {//音量非零,静音 volumeTemp = els.video.volume; //记录当前音量 els.video.volume = 0; //静音 U.MD.UI.video.flushInfo(moving, els.currentTimeDiv, els.DurationDiv, els.progressCurrentTime, els.soundProgressCurrent, els.video); //刷新信息 } else if (els.video.volume === 0 && volumeTemp !== null) {//如果音量等于0(即静音),且用户没有按过静音键 els.video.volume = volumeTemp; //设置音量 volumeTemp = null; //将变量值重置 U.MD.UI.video.flushInfo(moving, els.currentTimeDiv, els.DurationDiv, els.progressCurrentTime, els.soundProgressCurrent, els.video); //刷新信息 } return volumeTemp; //返回volumeTemp }; /** * 全屏按钮点击事件 * @param fullscreen 是否全屏 * @param els 元素集合 */ U.MD.UI.video.fullscreenClick = function (fullscreen, els) { if (!fullscreen) {//如果没全屏 if (els.videoDiv.requestFullScreen) {//请求全屏(w3) els.videoDiv.requestFullScreen(); //请求全屏(w3) } else if (els.videoDiv.webkitRequestFullScreen) {//请求全屏(webkit) els.videoDiv.webkitRequestFullScreen(); //请求全屏(webkit) } else if (els.videoDiv.mozRequestFullScreen) {//请求全屏(moz) els.videoDiv.mozRequestFullScreen(); //请求全屏(moz) } } else {//如果已全屏 if (document.exitFullScreen) {//取消全屏(w3) document.exitFullScreen(); //取消全屏(w3) } else if (document.webkitCancelFullScreen) {//取消全屏(webkit) document.webkitCancelFullScreen(); //取消全屏(webkit) } else if (document.webkitExitFullscreen) {//取消全屏(webkit) document.webkitExitFullscreen(); //取消全屏(webkit) } else if (document.mozExitFullScreen) {//取消全屏(moz) document.mozExitFullScreen(); //取消全屏(moz) } } }; /** * 全屏状态改变事件 * @param fullscreen 记录是否全屏 * @param tempHeight 临时高度 * @param tempWidth 临时宽度 * @param els 元素集合 * @returns {*[]} 返回部分改变后的变量 */ U.MD.UI.video.fullscreenChange = function (fullscreen, tempHeight, tempWidth, els) { if (!fullscreen) {//如果没全屏,则进行全屏准备操作 //tempHeight = els.videoDiv.offsetHeight + "px";//备份视频div高度 //tempWidth = els.videoDiv.offsetWidth + "px";//备份视频div宽度 els.videoDiv.style.height = "100vh"; //100vh为覆盖整个页面 els.videoDiv.style.width = "100vw"; //100vw为覆盖整个页面 els.videoDiv.style.position = "absolute"; //将视频设置绝对定位 els.videoDiv.style.top = "0"; //移动到最上 els.videoDiv.style.left = "0"; //移动到最左 els.videoDiv.style.zIndex = "999"; //设置zIndex最高 } else {//退出全屏 els.videoDiv.style.height = tempHeight + "px"; //恢复高度 els.videoDiv.style.width = tempWidth + "px"; //恢复宽度 els.videoDiv.style.position = ""; //清除绝对定位 els.videoDiv.style.top = ""; //清除top属性 els.videoDiv.style.left = ""; //清除left属性 els.videoDiv.style.zIndex = ""; //清除zIndex属性 } fullscreen = !fullscreen; //设置全屏状态 return [fullscreen, tempHeight, tempWidth]; }; /** * 时间格式化(数字秒转换成00:00的格式) * @param time 待转换的时间(秒) 例:30 * @returns {string} 返回的时间 例:00:30 */ U.MD.UI.video.timeFormat = function (time) { var _sec = parseInt(time % 60); //计算秒 var _min = parseInt(parseInt(time) / 60); //计算分钟 (_sec < 10) ? _sec = "0" + _sec : _sec; //秒补零 (_min < 10) ? _min = "0" + _min : _min; //分钟补零 return _min + ":" + _sec; //返回生成的时间 }; /** * 刷新数据 * @param moving 是否正在移动(用于判断要不要刷新) * @param currentTimeDiv 当前时间元素 * @param DurationDiv 视频总长度元素 * @param progressCurrentTime 进度条当前长度 * @param soundProgressCurrent 音量当前长度 * @param video 视频元素 */ U.MD.UI.video.flushInfo = function (moving, currentTimeDiv, DurationDiv, progressCurrentTime, soundProgressCurrent, video) { if (moving) return; //如果在拖动则不刷新 currentTimeDiv.innerHTML = U.MD.UI.video.timeFormat(video.currentTime); //当前时间刷新 DurationDiv.innerHTML = U.MD.UI.video.timeFormat(video.duration); //视频总长度刷新 progressCurrentTime.style.width = video.currentTime / video.duration * 100 + "%"; //进度条刷新 soundProgressCurrent.style.width = video.volume * 100 + "%"; //音量刷新 }; /** * 获取当前元素左边到屏幕最左边的距离 * @param el 元素 * @returns {number} 返回距离(不包括单位) */ U.MD.UI.video.getScreenLeft = function (el) { var _rtnLeft = el.offsetLeft; //定义一个左边长度 var _parent = el.offsetParent; //定义这个元素的父元素 while (_parent != null) {//如果父元素不为空,则进入循环 _rtnLeft += _parent.offsetLeft; //记录左边距离 _parent = _parent.offsetParent; //重新定义父元素 } return _rtnLeft; //返回距离 }; /** * 循环刷新信息 * @param _moving 是否正在移动 * @param _els 元素 * @returns {number} interval */ U.MD.UI.video.setInterval = function (_moving, _els) { return setInterval(function () {//设置定时器 U.MD.UI.video.flushInfo(_moving, _els.currentTimeDiv, _els.DurationDiv, _els.progressCurrentTime, _els.soundProgressCurrent, _els.video); //刷新信息 }, 500); //每半秒刷新一次 }; /** * 进度条(圆点)移动事件函数 * @param event 鼠标按下事件 * @param moving 是否正在移动 * @param els 元素 */ U.MD.UI.video.circleMove = function (event, moving, els) {//进度条移动函数(圆点) moving = true; //设置移动状态 var _e = event; //读取event var _content = event.currentTarget; //获取目标 var _startX = _e.pageX; //设置一个开始的x点 var _currentProgress = _content.parentElement; //获取当前进度条元素 var _progress = _currentProgress.parentElement; //获取进度条元素 els.videoDiv.onmousemove = function (e) { if (e.pageX - U.MD.UI.video.getScreenLeft(_progress) < 0 || e.pageX - U.MD.UI.video.getScreenLeft(_progress) > _progress.offsetWidth) {//如果鼠标位置不在有效范围内则不继续 return; } var _iL = e.pageX - _startX; //移动的距离 //根据实际进度与进度条长度对比进行判断 if (!(_currentProgress.offsetWidth + _iL > _progress.offsetWidth || _currentProgress.offsetWidth + _iL < 0) && (e.currentTarget.children[0].offsetWidth <= e.currentTarget.children[0].offsetWidth)) { //设置进度条位置 _currentProgress.style.width = (_currentProgress.offsetWidth + _iL) / _progress.offsetWidth * 100 + "%"; //设置视频位置 els.video.currentTime = (_currentProgress.offsetWidth + _iL) / _progress.offsetWidth * els.video.duration; } _startX = e.pageX; //重置开始的x点 }; els.videoDiv.onmouseup = function () {//清除事件 moving = false; //恢复移动状态 els.videoDiv.onmousemove = function () {//清除移动事件 }; els.videoDiv.onmouseup = function () {//清除mouseup事件 }; }; }; /** * 声音进度条拖动函数 * @param event 事件 * @param els 元素集合 * @param moving 是否正在移动 */ U.MD.UI.video.soundProgressMove = function (event, els, moving) {//注释见move函数 event.preventDefault(); //取消事件的默认动作 var _e = event; //声明event var _content = event.currentTarget; //获取soundprogress var _startX = _e.pageX; //设置一个开始的x点 var _currentSound = els.soundProgressCurrent; //当前的音量条元素 var _x = event.offsetX; //获取现在鼠标相对于音量条的x点 var _length = _content.offsetWidth; //获取音量条的长度 els.video.volume = _x / _length; //设置视频音量 U.MD.UI.video.flushInfo(moving, els.currentTimeDiv, els.DurationDiv, els.progressCurrentTime, els.soundProgressCurrent, els.video); //刷新信息 /** * mousemove函数 * @param e 事件 */ els.videoDiv.onmousemove = function (e) { if (e.pageX - U.MD.UI.video.getScreenLeft(els.soundProgress) < 0 || e.pageX - U.MD.UI.video.getScreenLeft(els.soundProgress) > els.soundProgress.offsetWidth) {//如果鼠标位置不在有效范围内则不继续 return; //返回 } var _iL = e.pageX - _startX; //移动的长度 if (!(_currentSound.offsetWidth + _iL > _content.offsetWidth || _currentSound.offsetWidth + _iL < 0)) {//判断是否应该移动 _currentSound.style.width = (_currentSound.offsetWidth + _iL) / _content.offsetWidth * 100 + "%"; //设置样式(进度条长度) els.video.volume = _currentSound.offsetWidth / _content.offsetWidth; //设置音量 } _startX = e.pageX; //重置开始的x点 }; els.videoDiv.onmouseup = function (e) { els.videoDiv.onmousemove = function () {//清除mousemove事件 }; els.videoDiv.onmouseup = function () {//清除mouseup事件 }; }; }; /** * 进度条拖动函数 * @param event 事件 * @param els 元素集合 * @param moving 是否正在移动 */ U.MD.UI.video.progressMove = function (event, els, moving) {//部分注释见move函数 event.preventDefault(); //清除默认事件 if (event.target.className === "U_MD_UI_video_ProgressCircle") {//如果class是圆点的话返回 return; } var _e = event; //记录event var _content = U.selectEl(".U_MD_UI_video_Progress")[0]//event.currentTarget; //获取进度条元素 var _startX = _e.pageX; //定义起点 var _currentProgress = els.progressCurrentTime; //定义进度条(当前)元素 var _x = event.layerX || event.offsetX; //鼠标点击的点 var _length = _content.offsetWidth; //进度条长度 els.video.currentTime = els.video.duration * (_x / _length); //计算出百分比并设置时间 U.MD.UI.video.flushInfo(moving, els.currentTimeDiv, els.DurationDiv, els.progressCurrentTime, els.soundProgressCurrent, els.video); //刷新信息 /*els.videoDiv.onmousemove = function (e) {//鼠标移动事件 if (e.pageX - U.MD.UI.video.getScreenLeft(els.progress) < 0 || e.pageX - U.MD.UI.video.getScreenLeft(els.progress) > els.progress.offsetWidth) {//鼠标不在范围内则不继续 return; } moving = true; //设置移动状态 var _iL = e.pageX - _startX; //移动的长度 if (!(_currentProgress.offsetWidth + _iL > els.progress.offsetWidth || _currentProgress.offsetWidth + _iL < 0)) {//判断加上移动距离后是否合理 _currentProgress.style.width = (_currentProgress.offsetWidth + _iL) / els.progress.offsetWidth * 100 + "%"; //设置当前进度条的样式(宽度) els.video.currentTime = (_currentProgress.offsetWidth + _iL) / els.progress.offsetWidth * els.video.duration; //设置视频现在播放时间 } _startX = e.pageX; //重新设置开始的点 };*/ els.videoDiv.onmouseup = function () {//鼠标点击事件 moving = false; //设置移动状态 U.MD.UI.video.flushInfo(moving, els.currentTimeDiv, els.DurationDiv, els.progressCurrentTime, els.soundProgressCurrent, els.video); //刷新信息 els.videoDiv.onmousemove = function () {//清除事件 }; els.videoDiv.onmouseup = function () {//清除事件 }; }; };