目录
视频播放器实例
状态标签
meter
progress
列表标签
datalist
details
summary
注释标签
ruby
标记标签
mark
新增表单控件
新增表单属性
表单验证
validity对象
视频播放器实例
html代码
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title></title><link rel="stylesheet" type="text/css" href="css/index.css"/></head><body><div id="wrap"><video src="giphy.mp4"></video><div class="control"><div class="btns"><span class="start"></span><span class="stop"></span></div><div class="progress"><div class="wrap"><div class="inner"></div></div><div class="skyblue"></div></div><div class="others"><div class="time"><span class="now">00:00:00</span>/<span class="all">00:00:00</span></div><div class="sound"><div class="switch"><span></span></div><div class="progress"><div class="wrap"><div class="inner"></div></div><div class="skyblue"></div></div></div><div class="full-screen"> <span></span></div></div></div></div></body><script src="js/drag.js"></script><script type="text/javascript">window.onload=function(){var video = document.querySelector("#wrap > video");var control = document.querySelector("#wrap > .control");var progress = document.querySelector("#wrap > .control > .progress ")var inner = document.querySelector("#wrap > .control > .progress > .wrap > .inner ");var skyblue = document.querySelector("#wrap > .control > .progress > .skyblue ");var start = document.querySelector("#wrap .btns .start");var stop = document.querySelector("#wrap .btns .stop");var allSpan = document.querySelector("#wrap > .control >.others .all");var nowSpan = document.querySelector("#wrap > .control >.others .now");var switchNode = document.querySelector("#wrap > .control >.others >.sound .switch");var switchSpan = document.querySelector("#wrap > .control >.others >.sound .switch > span");var progress2 = document.querySelector("#wrap > .control >.others .progress ")var inner2 = document.querySelector("#wrap > .control >.others .progress > .wrap > .inner ");var skyblue2 = document.querySelector("#wrap > .control >.others .progress > .skyblue ");var fullScreen = document.querySelector("#wrap > .control >.others .full-screen ");var fullScreenSpan = document.querySelector("#wrap > .control >.others .full-screen > span");video.width= document.documentElement.clientWidth;video.height=document.documentElement.clientHeight - control.offsetHeight;window.onresize=function(){if(document.documentElement.clientWidth>=600){video.width= document.documentElement.clientWidth;video.height=document.documentElement.clientHeight - control.offsetHeight;}}//功能var timer = 0;//同步音量var flag = 0;//全屏标志var isFullScreen = false;player();function player(){//双击视频事件var flag=0;video.ondblclick=function(){if(flag==0){addClass(start,"active");video.play();timer=setInterval(move,100)flag=1;}else{removeClass(start,"active");video.pause();clearInterval(timer);flag=0;}}//全屏fullScreen.onclick=function(){if(isFullScreen) {// 全屏 ---> 不是全屏 --> removeremoveClass(fullScreenSpan,"active")isFullScreen = falseif (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitCancelFullScreen) { document.webkitCancelFullScreen(); }else if (document.msExitFullscreen) {document.msExitFullscreen();}} else {addClass(fullScreenSpan,"active")isFullScreen = truevar docElm = document.documentElement;//W3C if (docElm.requestFullscreen) { docElm.requestFullscreen(); }//FireFox else if (docElm.mozRequestFullScreen) { docElm.mozRequestFullScreen(); }//Chrome等 else if (docElm.webkitRequestFullScreen) { docElm.webkitRequestFullScreen(); }//IE11else if (docElm.msRequestFullscreen) {docElm.msRequestFullscreen();}}}//音量的控制inner2.style.left = skyblue2.style.width = progress2.clientWidth - inner2.offsetWidth+"px";switchNode.onclick=function(){if(video.muted){//静音 ---> 不静音 ---> 没有x的那个video.muted=false;video.volume =1;removeClass(switchSpan,"active")flag = flag==0?1:flag;inner2.style.left = skyblue2.style.width = (progress2.clientWidth - inner2.offsetWidth)*flag+"px";}else{video.muted=true;video.volume =0;addClass(switchSpan,"active")inner2.style.left = skyblue2.style.width=0+"px";}} //时间显示video.addEventListener("loadeddata",function(){allSpan.innerHTML = changeTime(video.duration);})//进度条progress.onclick=function(ev){ev=ev||event;addClass(start,"active");video.play();timer=setInterval(move,100);video.currentTime = video.duration*((ev.clientX-this.offsetLeft)/(progress.clientWidth - inner.offsetWidth))}//按钮排stop.onclick=function(){removeClass(start,"active");video.pause();clearInterval(timer);inner.style.left = skyblue.style.width=0+"px";video.currentTime=0;}start.onclick=function(){if(video.paused){//暂停 ---> 播放 ---> 显示暂停按钮addClass(this,"active");video.play();timer=setInterval(move,100)}else{removeClass(this,"active");video.pause();clearInterval(timer);}}function move(){inner.style.left = skyblue.style.width =(video.currentTime/video.duration)*(progress.clientWidth - inner.offsetWidth)+"px";nowSpan.innerHTML=changeTime(video.currentTime);}}//进度条小滑块拖拽时的逻辑var callback={move:function(){skyblue.style.width = this.offsetLeft+"px";var scale = this.offsetLeft/(progress.clientWidth - inner.offsetWidth);video.currentTime = video.duration*scale;nowSpan.innerHTML=changeTime(video.currentTime);}}//音量条小滑块拖拽时的逻辑var callback2={move:function(){skyblue2.style.width = this.offsetLeft+"px";var scale = this.offsetLeft/(progress2.clientWidth - inner2.offsetWidth);flag = scale;video.volume = scale;if(video.volume == 0){video.muted=true;addClass(switchSpan,"active")}else{removeClass(switchSpan,"active")video.muted=false;}}}$.drag(inner,callback);$.drag(inner2,callback2);//工具类function changeTime(time){time = parseInt(time);var h = toZero(Math.floor(time/3600));var m = toZero(Math.floor(time%3600/60));var s = toZero(Math.round(time%3600));return h+":"+m+":"+s;}function toZero(num){var val="";if(num<10){val="0"+num;}else{val = val+num;}return val;}function addClass(node,className){var reg=new RegExp("\\b"+className+"\\b");if(!reg.test(node.className)){node.className +=(" "+className); }}function removeClass(node,className){if(node.className){var reg=new RegExp("\\b"+className+"\\b");var classes = node.className;node.className=classes.replace(reg,"");if(/^\s*$/g.test(node.className)){node.removeAttribute("class");}}else{node.removeAttribute("class");}}} </script>
</html>
less代码
@import "reset.less";.progress-mixin(){position: relative;&>.wrap{position: absolute;width: 100%;height: 3px;margin-top: 11px;background: #737373;.inner{position: absolute;width: 9px;height: 7px;background: white;border-radius:2px ;margin-top: -2px;}}&>.skyblue{position: absolute;left: 0;top: 0;width: 0;height: 3px;margin-top: 11px;background: skyblue;}
}#wrap{height: 100%;overflow-x: auto;overflow-y: hidden;background: #383838;font-size: 0;.control{min-width: 600px;position: relative;height: 25px;background: #2A2A2A;.btns{position: absolute;left: 0;top: 0;width: 55px;height: 25px;text-align: center;&>span{display: inline-block;width: 9px;height: 11px;background: url(../img/icon.png) no-repeat;margin-top:7px;&:nth-child(1){background-position: 0px -23px;margin-right: 10px;&.active{background-position: 0px -11px;}}&:nth-child(2){background-position: 0px 0px;}}};& >.progress{margin: 0 230px 0 55px;height: 25px;.progress-mixin()};.others{position: absolute;right: 0;bottom: 0;width: 230px;height: 25px;&>div{height: 25px;float: left;}.time{width: 120px;font-size: 12px;color: white;line-height: 25px;text-align: center;}.sound{width: 80px;&>div{height: 25px;float: left;}.switch{width: 20px;text-align: center;&>span{display: inline-block;margin: 7px auto;width: 12px;height: 12px;background: url(../img/icon.png) no-repeat;background-position:0 -34px;&.active{background-position:0 -46px;}}}.progress{width: 60px;.progress-mixin();}}.full-screen{width: 30px;height: 25px;text-align: center;&>span{display: inline-block;margin: 7px auto;width: 11px;height: 11px;background: url(../img/icon.png) no-repeat;background-position: 0 -58px;&.active{background-position: 0 -71px;}}}}}
}
该实例中我在原先的基础上添加了一个双击视频来暂停开始的功能。
这个实例对我来说工作量挺大的,还是基础不够扎实,在实现的过程中出现很多低级错误。
状态标签
meter
该标签用来显示已知范围的标量值或分数值
- value:当前的数值
- min:值域的最小边界值。如果设置了,它必须比最大值要小。如果没设置,默认为0
- max:值域的上限边界值。如果设置了,它必须比最小值要大。如果没设置,默认为1
- low:定义了低值区间的上限值,如果设置了,它必须比最小值属性大,并且不能超过high值和最大值。未设置活着比最小值还要小时,其值即为最小值
- high:定义了高值区间的下限值。如果设置了,它必须小于最大值,同时必须大于low值和最小值。如果没有设置,或者比最大值还大,其值即为最大值
- optimum:这个属性用来指示最优 / 最佳取值
progress
该标签用来显示一项任务的完成进度
- max:该属性描述了这个progress元素所表示的任务一共需要完成多少工作
- value:该属性用来指定该进度条已完成的工作量。如果没有value属性,则该进度条的进度为”不确定“,也就是说,进度条不会显示任何进度,无法估计当前的工作会在何时完成
列表标签
datalist
该标签会包含一组option元素,这些元素表示其表单控件的可选值。其id必须要和input中的list一致
details
一个ui小部件,用户可以从其中检索附加信息
open属性用来控制附加信息的默认显示与隐藏
summary
该标签用作一个<details>元素的一个内容摘要(标题)
注释标签
ruby
<rt></rt>:展示文字注音或字符注释
标记标签
mark
该标签表示为引用或符号目的而标记或突出显示的文本,这是由于标记的段落在封闭上下文中的相关性或重要性造成的
新增表单控件
- type:email:电子邮件地址类型。当格式不符合email格式时,提交是不会成功的,会出现提示;只有当格式正确时,提交才会通过。在移动端获焦时会切换到英文键盘
- type:tel:电话类型。在移动端获焦时会切换到数字键盘
- type:url:url类型。当格式不正确时,提交是不会成功的,会出现提示;只有当格式正确时,提交才会通过
- type:search:搜索类型。有清空文本的按钮
- type:range:特定范围内的数值选择器。属性有min、max、step
- type:number:只能包含数字的输入框
- type:color:颜色选择器
- type:datetime:显示完整日期(移动端浏览器支持)
- type:datetime-local:显示完整日期(不含时区)
- type:time:显示时间(不含时区)
- type:date:显示日期
- type:week:显示周
- type:month:显示月
新增表单属性
- placeholder:输入框提示信息。使用于form,以及type是text、search、url、tel、email、password类型的input
- autofocus:指定表单自动获取输入焦点
- required:此项必填,不能为空
- pattern:正则验证,例如:pattern="\d{1,5}"
- formaction:在submit里定义提交地址
- list和datalist:为输入框构造一个选择列表。list值为datalist标签的id
表单验证
validity对象
通过下面的valid可以查看验证是否通过,如果八种验证都通过则返回true,一种验证失败返回false
node.addEventListener("invalid",function(){},false);
- valueMissing:输入值为空时返回true
- typeMismatch:控件值与预期类型不匹配返回true
- patternMismatch:输入值不满足pattern正则返回true
- customError:不符合自定义验证返回true(setCustomValidity())