html5

时间:2024-04-15 08:14:02

语义化标签 input的新属性值 表单的验证 json的新方法 自定义属性 拖放 canvas 地理位置的获取 离线存储 本地存储 audio video

语义化标签

使用最多的id->当前的语义化标签
页面整体架构
header标签 页面头部或者板块的头部
footer标签 页面底部或者板块的底部
nav标签 页面的导航
hgroup 页面中的标题组合
内容部分
section 页面中用来划分区域的 划分出独立的区块
article 结构完整并且内容相对独立的一部分
aside 和主题相关的附属信息
相对独立的语义化的新标签
figure 媒体元素组合(图片+文字) img+figcaption
time 时间标签 标签有一个datatime属性
dataList 列表标签 input中可能会输入的值

<input type="text" list="list1" >
<datalist id="list1">
    <option value="js">sasa1</option>
    <option value="css">sasa2</option>
    <option value="html">sasa3</option>
</datalist>

details 标签 配合summary

<details>   //加上open属性  p的内容就会显示
    <summary>sasa</summary>   
    <p>sassasas</p>
</details>

实现了点击summary的时候会显示p中的内容
dialog 标签

<dialog open>
    <dt>老叟</dt>
    <dd>老叟</dd>
    <dt>老叟</dt>
    <dd>老叟</dd>
    <dt>老叟</dt>
    <dd>老叟</dd>
</dialog>

必须加上open属性 才能显示整个对话框
address 标签 页面上的地址 倾斜
mark 标签 标记一下 文字的背景变黄
功能性标签
progress 进度条

<progress value="50" max="100"></progress>

浏览器h5的兼容 页面开始的地方添加脚本

<script>
    document.createElement("header")
    document.createElement("nav")
    document.createElement("section")
    document.createElement("footer")
</script>

等一系列新的结构性的标签、兼容低版本浏览器的插件 html5.js

html5新增表单元素 input的属性值

email 输入的必须为email
tel 输入的必须为一个电话号
url 输入的必须为一个网址
search 搜索框 输入的过程中 输入框尾部总有一个X 一点击X输入的内容就没有了
range 数值选择器 step=2 min=0 max=10 value=当前的值
number 输入框的尾部 有向上和向下的箭头 会改变数值
color 颜色输入框
datetime 显示完整的日期
time 小时和分钟数的显示
week 周显示器 显示当前是这一年的第几周
month 月显示器 显示当前是这一年的第几月

html5新增表单属性值 input的属性值

placeholder 输入框内会默认显示的值
autocomplete 输入的过程中是否会自动提示 如果在公共电脑上不需要保存的话 autocomplete =“off”
autofocus 表单是否会自动获取焦点 直接使用没有值
input 的list属性指定这个输入框的datalist
required 在提交之前这个输入 这个字段是必填的
pattern 属性值为正则表达式 可以校验这个输入的字符串 在失去焦点的时候就会校验
formaction 这个输入框单独的提交地址 传统的都是整个表单会提交到一个地方 在opera可以

html5表单验证反馈 通过绑定invalid 得到validity

html

<form>
    <input type="text" required id="text"/>
    <input type="submit"/>
</form>

js

   var oText=document.getElementById("text");
     //只有再没有填写在这个字段 并且提交的时候才会触发这个事件
     oText.addEventListener("invalid",fn,false);
     //用户向输入框中输入文字的时候便会触发该事件
     oText.oninput=function () {
         console.log(112)
            //自定义验证
       if(this.value=="111"){
           this.setCustomValidity("这是铭感词")
       }else{
           this.setCustomValidity("这是铭感词")
       }
     }
     function  fn() {
         console.log(this.validity)  //整个验证信息都是保存在这个对象当中的
         console.log(this.validity.valid)  //布尔值  验证通过为true
         console.log(this.validity.valueMissing)  //布尔值  输入的字符串是否为空
         console.log(this.validity.typeMismatch)  //布尔值  输入的字符串是否和要求的类型不一致返回true
         console.log(this.validity.patternMismatch)  //布尔值  输入的字符串是否和pattern的属性值的正则是否不匹配   返回为true
         console.log(this.validity.tooLong)  //布尔值  输入的字符串的长度大于maxlength的属性值
     }

在设计 保存至草稿箱按钮的时候注意
1、关闭表单验证 为这个input 添加formnovalidate 关闭验证
2、使用formaction 提交到本地

HTML5中新增加的选择器

querySelector(id,class[只能选择到一组中的第一个元素],标签) 返回的都是一个元素

html

<div id="test2">sasa</div>

js

 window.onload=function () {
        var oDIv=document.querySelector(\'#test2\')
        oDIv.style.background="red"
    }

querySelectorAll(id,class[选择到一组元素],标签)
html5增加了对元素类的操作

 var oDIv=document.querySelector(\'#test2\')
         console.log(oDIv.classList)
        oDIv.classList.add("box4")  //为元素增加了类  box4
        oDIv.classList.remove("box2")  //为元素删除了类  box4
        oDIv.classList.toggle("box2")  //如果元素有box2就删除box2 如果没有box2增加box2

html5的JSON的新方法

JSON.parse("json类型的字符串") 只能解析json类型的字符串转化为对象 json必须是一个严格的json
严格的json 属性和属性值都带着“”
eval("任何字符串") 将任意类型的字符串转化为js

       var sss=JSON.parse(\'{"name":"huangxiaojian","age":"23"}\')
        console.log(typeof sss)  //object

将js转化为字符串
JSON.strify(对象) 返回的是严格的json字符串

 var sss=JSON.parse(\'{"name":"huangxiaojian","age":"23"}\')
        console.log(typeof sss)  //object
        var sss1=JSON.stringify(sss);
        console.log(typeof sss1)   //string

对象之间的赋值会出现引用

   var a={name:"sasa"};
        var b=a;
        b.name="sa11";
        console.log(a.name)  //sa11

但是使用for循环对对象的赋值只能是浅拷贝。
实现深拷贝的最简单的方法。

 var a={name:"11"};
        var str=JSON.stringify(a);
        var b=JSON.parse(str);
        b.name="sasa";
        console.log(a.name)  //依然为11

先转化为字符串 再将字符串转化为对象 实现了深拷贝

html5中的自定义属性

html

<div id="test2" class="box1 box2 box3">sasa</div>
<div id="miaowei" data-maiaov="妙味" data-maiaov-all="妙味课堂"></div>

js

  var maiowei=document.querySelector("#miaowei")
        console.log(maiowei.dataset.maiaov)  //妙味
        console.log(maiowei.dataset.maiaovAll)  //妙味课堂  使用驼峰式来访问

在使用自定义的属性的时候注意:
1、html中属性值都是 data-name-value=""
2、js中访问这个值得时候都是 存放在这个元素上的dataset上边 比如说dataset.nameValue

html5中为js延迟加载的新的属性 defer

defer="defer" 延迟加载js这个属性

<script defer="defer" src="a.js"></script>
<script>
     console.log(333)
</script>

会先输出333载执行a.js文件

html5为js异步加载的属性 async

异步加载js 加载完就会某个事件
async="async"
异步加载的执行顺序是不定的
一般用来加载 和页面加载和显示无关的js

html5中的历史管理history

改变历史管理
1、跳转页面
2、增加哈希值 http://localhost:63342/study_... onhashchange
3、pushstate()
onhashchange()改变hash值来管理

 var oInput=document.getElementById("input1")
    var div1=document.getElementById("div1");
    var json={};
    window.onload=function () {
        oInput.onclick=function () {
            var number=Math.random();
            var arr=randomNum(35,7)
            json[number]=arr;
            div1.innerHTML=arr;
            window.location.hash=number
        }
        function randomNum(iAll,isNow) {
            var arr=[];
            var newArr=[];
            for(var i=1;i<=iAll;i++){
                arr.push(i)
            }
            for(var i=0;i<isNow;i++){
                newArr.push(arr.splice(Math.ceil(Math.random()*arr.length),1))
            }
            return newArr;
        }
    }
    window.onhashchange=function () {
        div1.innerHTML=json[window.location.hash.substring(1)];
    }

当url部分的哈希值发生变化的时候 div中的值也会发生改变

使用history.push(三个参数) 数据、标题、地址

  var oInput=document.getElementById("input1")
    var div1=document.getElementById("div1");
    var json={};
    window.onload=function () {
        oInput.onclick=function () {
            var arr=randomNum(35,7)
            history.pushState(arr,\'\',arr)
            div1.innerHTML=arr;
        }
        window.onpopstate=function (ev) {
            div1.innerHTML=ev.state
        }
        function randomNum(iAll,isNow) {
            var arr=[];
            var newArr=[];
            for(var i=1;i<=iAll;i++){
                arr.push(i)
            }
            for(var i=0;i<isNow;i++){
                newArr.push(arr.splice(Math.ceil(Math.random()*arr.length),1))
            }
            return newArr;
        }
    }

html5的拖放事件

draggable=true
拖拽元素事件
ondragstart 开始拖拽的时候(而不是鼠标按下)会响应
ondrag 拖拽前和拖拽结束的中间会连续触发
ondragend 拖拽结束的时候触发的事件(也就是释放鼠标的时候)
目标元素(拖拽到的地方)事件
ondragenter 拖拽的元素进入目标区域的时候会响应事件
ondragover 进入目标区域之后离开目标区域之前会一直响应
ondragleave 拖拽的元素离开目标区域的时候会响应事件
ondrop 在目标元素上释放被拖拽元素的时候会触发(要想触发drop事件,就必须触发在ondragover中阻止默认事件)
html

<ul>
    <li draggable="true">1</li>
    <li draggable="true">1</li>
    <li draggable="true">1</li>
</ul>
<div id="div1"></div>

js

   var lis=document.getElementsByTagName("li");
   var i=0;
   for(var i=0;i<lis.length;i++){
       lis[i].ondragstart=function () {
           this.style.background="red"
       }
       lis[i].ondrag=function () {
           //即使鼠标停下来也会触发
           //console.log(i++)
       }
       lis[i].ondragend=function () {
           this.style.background="green"
       }
   }
   var div1=document.getElementById("div1");
    div1.ondragenter=function () {
        console.log(11)
    }
    div1.ondragover=function (e) {
        //只有在这阻止了默认事件才会在目标区域释放的时候  才会触发
        e.preventDefault();
        console.log(i++)
    }
    div1.ondragleave=function () {
        console.log(22)
    }
    div1.ondrop=function () {
        console.log("end")
    }

刚被拖拽的元素没有触发drop时
依次触发的事件为:ondragstart ondrag ondragenter ondragover ondragleave ondragend
刚被拖拽的元素会触发drop时
依次触发的事件为:ondragstart ondrag ondragenter ondragover ondrop ondragend
解决火狐下元素的拖放
兼容火狐浏览器,并且利用dataTransfer来传递数据
html

<ul>
    <li draggable="true">1</li>
    <li draggable="true">2</li>
    <li draggable="true">3</li>
</ul>
<div id="div1"></div>
   var ul=document.getElementsByTagName("ul")[0];
   var lis=ul.getElementsByTagName("li");
   var i=0;
    var div1=document.getElementById("div1");
   for(var i=0;i<lis.length;i++){
       lis[i].index=i;
       lis[i].ondragstart=function (ev) {
           //针对火狐浏览器实现拖放  并且使用dataTransfer传递拖放过程中的样式
           var ev=ev||window.event;
           ev.dataTransfer.setData("name",this.index)
           //改变被拖拽元素被拖到拖拽区域的样式
           ev.dataTransfer.effectAllowed=\'copy\'  //进入拖拽区有一个小+
           ev.dataTransfer.effectAllowed=\'link\'  //进入拖拽区有一个小箭头
           //设置拖拽的样式   一个DOM元素(包括display:none的元素)也可以是img,坐标
           ev.dataTransfer.setDragImage(div1,0,0)   //拖拽出来的时候影子就会变为div1的样式
           this.style.background="red"
       }
       lis[i].ondrag=function () {
           //即使鼠标停下来也会触发
           //console.log(i++)
       }
       lis[i].ondragend=function () {
           this.style.background="green"
       }
   }

    div1.ondragenter=function () {
        console.log(11)
    }
    div1.ondragover=function (e) {
        //只有在这阻止了默认事件才会在目标区域释放的时候  才会触发
        e.preventDefault();
        console.log(i++)
    }
    div1.ondragleave=function () {
        console.log(22)
    }
    div1.ondrop=function (ev) {
        var ss=ul.removeChild(lis[ev.dataTransfer.getData("name")])
        div1.appendChild(ss);
        for(var i=0;i<lis.length;i++){
            lis[i].index=i;
        }
    }

html5中的canvas应用

canvas的默认大小 宽300高150
绘图的前提
1、得到画笔
var oc=document.getElementById("c1");

var oGC=oc.getContext("2d");

2、绘制方块
oGC.fillRect(50,50,50,50) //L T W H
3、绘制只有边框的方块

oGC.strokeRect(50,50,50,50)  //L T  W H

4、设置绘图的属性

 oGC.fillStyle="red";  //设置填充的颜色
   oGC.strokeStyle="blue"  //设置边框的颜色
   oGC.lineWidth=10  //设置边框的颜色
   oGC.lineJoin="round"   //矩形四周圆角连接
   oGC.lineJoin="bevel"   //矩形四周斜角连接 
   oGC.lineCap=\'squre\'   //方形的头

5、绘制直线 绘制路径
oGC.beginPath();

   oGC.moveTo(100,100);
   oGC.lineTo(200,200);
   oGC.lineTo(300,200);
   oGC.closePath()  //起点和终点进行连接
   oGC.stroke();  //画线的功能 

6、绘制其他的路径
oGC.stroke() 画线
oGC.fill() 填充
oGC.rect() 填充 默认是黑色
oGC.clearRect(L T W H) 清除画布的大小
oGC.save() 保存当前的画笔 在设置画笔前进行
oGC.restore() 恢复画笔

 window.onload=function () {
       var oc=document.getElementById("c1");
       //得到绘制环境
       var oGC=oc.getContext("2d");
       //先将画笔保存起来
       oGC.save();
       oGC.fillStyle="red"
       oGC.beginPath();
       oGC.moveTo(50,50);
       oGC.lineTo(100,50);
       oGC.lineTo(100,100);
       oGC.closePath()
       oGC.fill();
       //再恢复画笔
       oGC.restore();
       oGC.beginPath();
       oGC.moveTo(100,100);
       oGC.lineTo(200,200);
       oGC.lineTo(200,300);
       oGC.closePath();
       oGC.fill();
   }

canvas画曲线
画弧线
oGC.moveTo(100,200)

   oGC.arcTo(100,100,200,100,50)   //两组xy  半径
   oGC.stroke()

画贝塞尔曲线 方法一
oGC.moveTo(100,200)

   oGC.quadraticCurveTo(100,100,200,100)  //控制点坐标  结束点坐标
   oGC.stroke()

画贝塞尔曲线 方法二
oGC.moveTo(100,200)

   oGC.bezierCurveTo(100,100,200,200,200,100)  //第一组控制点  第二组控制点   结束点
   oGC.stroke()

canvas的变换
translate 画布原点的位移 (x,y)
rotate 旋转的角度(deg) 矩形以左上角的点 旋转
scale 缩放 (x,y) x和y缩放的比例
在canvas上边加载图片
画笔.drawImage(image,x,y) 参考旋转图片的额例子
将图片平铺画布
画笔.createPattern(obj,"平铺的方式repeat")

window.onload=function () {
       var oc=document.getElementById("c1");
       //得到绘制环境  画笔
       var oGC=oc.getContext("2d");
       var yImg=new Image();
       yImg.src="111.jpg"
       yImg.onload=function () {
            draw();
       }
       function draw() {
           var bg=oGC.createPattern(yImg,\'repeat\');//得到的是一个填充的样式
           oGC.fillStyle=bg;
           oGC.fillRect(0,0,300,300)
       }
   }

canvas渐变
线性渐变

var oc=document.getElementById("c1");
       //得到绘制环境  画笔
       var oGC=oc.getContext("2d");
       //渐变的起始点的坐标  渐变的终点的坐标
       var obj=oGC.createLinearGradient(150,100,250,200);
       obj.addColorStop(0,\'red\')
       obj.addColorStop(0.5,\'green\')
       obj.addColorStop(1,\'blue\')
       oGC.fillStyle=obj;
       oGC.fillRect(150,100,100,100)

放射性渐变
canvas的文本
设置文字的样式

oGC.font=\'20px impact\' //文字的大小  文字的样式

设置文字的基线

oGC.textBaseline=\'top\';    bottom

在画布上写字

   oGC.fillText(str,200,200)  //   内容和文字
       oGC.strokeText(str,200,200)  //内容和文字

设置文字的坐标

oGC.textAlign="left"         //设置文字的左右基线
       oGC.textBaseline=\'top\';   //设置文字的上下基线
       oGC.strokeText(str,0,0)  //

得到文字的宽度

oGC.measureText(str).width

为文字添加阴影

 var oc=document.getElementById("c1");
       //得到绘制环境  画笔
       var oGC=oc.getContext("2d");
       oGC.font=\'60px impact\' //文字的大小  文字的样式
       var str="sasa"
       oGC.textAlign="left"
       oGC.textBaseline=\'top\';
       oGC.shadowOffsetX=10;  //x轴便宜
       oGC.shadowOffsetY=10;   //Y轴便宜
       oGC.shadowBlur=3   //设置高斯模糊
       oGC.shadowColor="red"  //设置影音必须的一步   因为默认的阴影颜色是黑色透明
       oGC.fillText(str,0,0)

canvas中的像素操作
得到像素点 画笔.getImageData(x,y,width,heigth)
为画布设置像素点 画笔.putImageData(像素对象,x,y)

  var oc=document.getElementById("c1");
       //得到绘制环境  画笔
       var oGC=oc.getContext("2d");
       oGC.fillRect(0,0,100,100);
       var oImg=oGC.getImageData(0,0,100,100);   //获取到黑色方块的所有的像素
        //oImg为一个对象  包括
       console.log(oImg.width) //宽的像素
       console.log(oImg.height)  //高的像素
       console.log(oImg.data[0])  //40000 整体像素的数组集合
       //一个像素点使用四个值表示  rgba
       for(var i=0;i<oImg.width*oImg.height;i++){
           oImg.data[4*i]=255;
           oImg.data[4*i+1]=0;
           oImg.data[4*i+2]=0;
           oImg.data[4*i+3]=100;
       }
       //设置新的图像数据
       oGC.putImageData(oImg,100,100)  //将oImg添加到100 100的位置

创建新的像素 oGC.createImageData(x,y,w,h)
通过 坐标得到像素点 通过坐标设置像素点

 //设置像素点
   function setXY(obj,x,y,color) {
       var w=obj.width;
       var h=obj.height;
       var d=obj.data;
       for(var i=0;i<d.length;i++)
       {
           d[4*(y*w+x)]=color[0]
           d[4*(y*w+x)+1]=color[1]
           d[4*(y*w+x)+2]=color[2]
           d[4*(y*w+x)+3]=color[3]
       }

   }
   //传递imgData  x  y
    function getXY(img,x,y) {
         var color=[];
         var w=img.width;
         var h=img.height;
         var d=img.data;
         for(var i=0;i<d.length;i++)
         {
             color[0]=d[4*(y*w+x)]
             color[1]=d[4*(y*w+x)+1]
             color[2]=d[4*(y*w+x)+2]
             color[3]=d[4*(y*w+x)+3]
         }
         return color
    }

设置画笔透明

       context.globalAlpha=0.5;

改变合成部分元素的叠加顺序 默认的是后画的会覆盖之前画的
源 即将绘制的图形 目标已经绘制过的图形

  context.gloalCompositionOperation=\'destination-over\'  //默认的值

将canvas导出为图片

   var ii=oc.toDataURL();  //画布的方法
       img.src=ii;

canvas的事件操作
isPointInPath(x,y) 判断点击的点是否在路径内 但是这个方法只会针对最后一个画的图形
context.isPointInPath(x,y)
为每一个绘制在每一个画布上的圆添加点击事件

    var oc=document.getElementById("c1");
       var img=document.getElementsByTagName("img")[0];
       //得到绘制环境  画笔
       var context=oc.getContext("2d");
       var c1=new shape(100,100,50)
       var c2=new shape(200,200,50)
       oc.onmousedown=function (ev) {
           var e=window.event||ev
           var point={
               x:ev.clientX-oc.offsetLeft,
               y:ev.clientY-oc.offsetTop
           }
           c1.repaint(point);
           c2.repaint(point);
       }
       c1.click=function () {
           console.log(111)
       }
       c2.click=function () {
           console.log(222)
       }
       function shape(x,y,r) {
           this.x=x;
           this.y=y;
           this.r=r;
           context.beginPath();
           context.arc(this.x,this.y,this.r,0,360*Math.PI/180);
           context.closePath();
           context.fill();
       }
       shape.prototype.repaint=function (point) {
           context.beginPath();
           context.arc(this.x,this.y,this.r,0,360*Math.PI/180);
           context.closePath();
           context.fill();
           if(context.isPointInPath(point.x,point.y)){
                this.click();
           }
       }

http://jcscript.com/ 一个专注于操作canvas的库

html5的跨文档通信

同域的不同窗口(iframe)之间的通信、window.open()新打开窗口之间的通信
1、 iframe 这个页面就会有两个窗口

   <iframe src="small.html" id="iframe1"></iframe>

找到子窗口

    //指向了子窗口的window
        var smallwindow=iframe1.contentWindow
        smallwindow.document.body.style.background="red"

2、通过window.open()方法打开的窗口
跨域下会报错

    <input type="button" value="点击我改变新窗口的窗体颜色" id="btn1">
    <iframe src="http://localhost:8888/" id="iframe1"></iframe>

js

   var btn1=document.getElementById("btn1");
    var   iframe1=document.getElementById("iframe1");
    btn1.onclick=function () {
        var window=iframe1.contentWindow
        console.log(window)
        window.document.body.style.background="red"; //这就会因为跨域下的限制报错
    }

跨域的方法


1、通过postMeassage window对象的方法
用于这个对象下的方法 给另外的一个窗口发送信息
postMeassage(发送的数据,接收数据的协议+域名) 发送端
window.onMessage(function(){}) 接收端
当接收窗口接受到postmessag方法 发送给过来的消息 就会触发这个事件
使用postMessage发送的消息

<body>
    <input type="button" value="点击我通过postMessage来发送消息" id="btn1">
    <iframe src="http://localhost:8888/" id="iframe1"></iframe>
</body>
<script>
    var btn1=document.getElementById("btn1");
    var   iframe1=document.getElementById("iframe1");
    btn1.onclick=function () {
        var window=iframe1.contentWindow
        window.postMessage(\'ddasavxv\',"http://localhost:8888/")
    }
</script>

服务器端

var http = require(\'http\');//引入http模块

//开启服务,监听8888端口
//端口号最好为6000以上

var server = http.createServer(function(req,res){
    res.writeHeader(200,{
        \'content-type\' : \'text/html;charset="utf-8"\'
    });
    var data;
   //ev.origin    判断发送消息的域
    res.write(\'<div>sasa</div><script>window.onmessage=function (ev) {data=ev.data  }</script>\');//显示给客户端
    res.end();

}).listen(8888);

console.log(\'服务器开启成功\');

关于parent
当页面没有被其他页面包括 这个页面的额parent就是window
当页面是<iframe>引入到其他页面的时候 此时的parent的时候 就是父页面的window
top
*窗口
2、新版的ajax
html5中的ajax支持跨域
服务器端

 app.get("/",function (req,res) {
        //设置指定的域才可以跨域访问这个服务器
          res.header("Access-Control-Allow-Origin", "http://localhost:63342");
          res.write("sasasasq21sa");
          res.end();
      })

前端

 var btn1=document.getElementById("btn1");
    var   iframe1=document.getElementById("iframe1");
    btn1.onclick=function () {
        var xhr=new XMLHttpRequest();
        xhr.onreadystatechange=function () {
            if(xhr.readyState==4){
                if(xhr.status==200){
                    console.log(xhr.responseText)
                }
            }
        }
        xhr.open(\'get\',\'http://localhost:3000/\',true)
        xhr.send();
    }

点击btn就会在控制台输出跨域的服务器输出的数据

WebSocket

1、为什么需要websocket的存在
因为 HTTP 协议有一个缺陷:通信只能由客户端发起。这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。websocket主要特点就是服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
2、websocket协议(http协议在同一水平)的特点
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
使用node搭建websocket
服务器端

var io=require("socket.io");
var socket=io.listen(server);
socket.sockets.on(\'connection\',function (socket) {
    console.log("有人通过socket进来了")
    //服务器端向客户端发送事件  hello  信息为11112121
    socket.emit(\'hello\',"欢迎你进来")
    //服务器接受客户端发送过来的事件hello11  并发生响应
   /* socket.on(\'hello11\',function (data) {
        console.log(data)
    })*/
   //实现广播事件   除了他自己收不到其余的人都能收到
   socket.broadcast.emit(\'a\',\'有新人进来了\')
})

每一个socket连接都有一个socket实例
客户端

 <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
</head>
<body>
   <div>sasasa</div>
<button typeof="button" value="post" id="btn">sasasa</button>
<script>
 window.onload=function () {
        var oBtn=document.getElementById("btn");
        var socket=null;
        oBtn.onclick=function () {
            //连接器起来的一个socket 实例
            var socket=io.connect(\'http://localhost:8888\')
            //客户端收到服务器发送的事件hello  做出的响应
            socket.on(\'hello\',function (data) {
                alert(data)
                //客户端向服务器发送事件hello11  传送的数据为ssjasasjia
                this.emit(\'hello11\',"ssjasasjia")

            })
            socket.on(\'a\',function (data) {
                alert(data)
            })
        }
    }
</script>

客户端就实现了 每次一点击按钮就会在你服务器输出有一个人进来了 进了服务器人,每有一个新人进来就会弹出有新人进来 新人第一次进来的时候只会弹出欢迎你进来


使用node搭建websocket服务器
客户端

  var ws = new WebSocket("ws://localhost:8181");
    ws.onopen = function(evt) {
        console.log("Connection open ...");
        ws.send("Hello WebSockets!");
    };
    ws.onmessage = function(evt) {
        console.log( "Received Message: " + evt.data);
        ws.close();
    };
    ws.onclose = function(evt) {
        console.log("Connection closed.");
    };

服务器端

var WebSocketServer = require(\'ws\').Server,
    wss = new WebSocketServer({ port: 8181 });
wss.on(\'connection\', function (ws) {
    console.log(\'client connected\');
    ws.on(\'message\', function (message) {
        console.log(message);
    });
    ws.send("sss",function () {
        console.log(111)
    })
});

其中新建的wss的属性有四个值
CONNECTING:值为0,表示正在连接。
OPEN:值为1,表示连接成功,可以通信了。
CLOSING:值为2,表示连接正在关闭。
CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
四种状态的使用如下

   var ws = new WebSocket("ws://localhost:8181");
    console.log(ws.readyState)  //0  CONNECTING:值为0,表示正在连接
    ws.onopen = function(evt) {
        console.log("Connection open ...");
        console.log(ws.readyState)  //1  OPEN:值为1,表示连接成功,可以通信了。
        ws.send("Hello WebSockets!");
    };
    ws.onmessage = function(evt) {
        console.log( "Received Message: " + evt.data);
        ws.close();
        console.log(ws.readyState)  //2  CLOSING:值为2,表示连接正在关闭。
    };
    ws.onclose = function(evt) {
        console.log(ws.readyState) //3  CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
        console.log("Connection closed.");
    };

如上websocket的实例对象还有如下的方法
webSocket.onopen 用于指定连接成功后的回调函数。
webSocket.onclose 用于指定连接关闭后的回调函数。
webSocket.onmessage 用于指定收到服务器数据后的回调函数。
webSocket.send 用于向服务器发送数据。

html5离线存储

离线存储的好处
没有网络的时候可以正常访问
快速构建相应页面 不必再使用http占用资源带宽
缓存的可以是任何文件
搭建离线应用
1、服务器端设置头信息
2、html标签加上 manifest="demo.manifest"
3、写demo.manifest清单
CACHE MANIFEST
../22.jpg
/logo.gif
/main.js

web Worker

js的单线程变为多线程 使用new Worker(test.js) 在test.js文件里边处理数据处理完之后 再返回
在test.js文件里边的运行环境和普通的环境不一样 有如下的规定
1、navgator :appName、appVersion、userAgent、platform
2、location 所有属性都是只读的
3、self 指向全局的worker对象
4、所有的ECMA 对象Object Array Date等
5、XMLHttpRequest构造器
6、setTimeout和setInterval方法
7、close()方法 立刻停止worker运行 已经使用完webworks
8、importScripts方法 引入在这个运行环境里边需要的其他js文件
所以这个运行环境只允许 对通过pastMessage传递过来的数据 做处理 处理完以后再通过postmessage传回来计算后的数据

使用方法
主线程

<script>
    var ss=new Worker("test.js");
    ss.postMessage(12)
    ss.onmessage=function (p1) { console.log(p1.data) }   //13
</script>

后台线程

var dd;
self.onmessage=function (p1) {
    dd=p1.data;
    self.postMessage(++dd)
}

html5的其他功能

实现任何内容都可以编辑 增加属性 contenteditable="true"

    <div contenteditable="true">sasa</div>

双击就可以编辑
实现语音输入

  <input type="text" x-webkit-speech lang="zh-CN"/>

桌面提醒 网页版微信提醒

html5获取地理位置

navigator.geolocation得到地理信息的坐标
第一个方法一次请求

window.onload=function () {
    var text=document.getElementById("text");
    var btn=document.getElementById("btn");
    btn.onclick=function () {
        navigator.geolocation.getCurrentPosition(function (position) {
            console.log(position)
            text.value+=\'经度\'+position.coords.longitude+\'\n\'  //得到经度
            text.value+=\'纬度\'+position.coords.latitude+\'\n\'  //得到经度
            text.value+=\'准确度\'+position.coords.accuracy+\'\n\'  //得到经度
            text.value+=\'海拔\'+position.coords.altitude+\'\n\'  //得到经度
            text.value+=\'海拔准确度\'+position.coords.altitudeAccuracy+\'\n\'  //得到经度
            text.value+=\'进行方向\'+position.coords.heading+\'\n\'  //得到经度
            text.value+=\'地面速度\'+position.coords.speed+\'\n\'  //得到经度
            text.value+=\'事件戳\'+position.coords.timeStamp+\'\n\'  //得到经度
        },function (error) {
            //地理位置获取失败
            
        },{
          //配置的选项
          enableHighAcuracy:true,  //高准确的
            timeout:5000  //请求限制的事件
        })
    }
}
   <input type="button" id="btn" value="点击">
    <br>
    <textarea style="width: 300px;height:300px;" id="text"></textarea>

实现了点击一次就可以 获取一次当前的地理位置
第二个方法 连续请求位置信息 适合移动设备 动的时候会自动触发

window.onload=function () {
    var text=document.getElementById("text");
    var btn=document.getElementById("btn");
    btn.onclick=function () {
       var timer= navigator.geolocation.watchPosition(function (position) {
            console.log(position)
            text.value+=\'经度\'+position.coords.longitude+\'\n\'  //得到经度
            text.value+=\'纬度\'+position.coords.latitude+\'\n\'  //得到经度
            text.value+=\'准确度\'+position.coords.accuracy+\'\n\'  //得到经度
            text.value+=\'海拔\'+position.coords.altitude+\'\n\'  //得到经度
            text.value+=\'海拔准确度\'+position.coords.altitudeAccuracy+\'\n\'  //得到经度
            text.value+=\'进行方向\'+position.coords.heading+\'\n\'  //得到经度
            text.value+=\'地面速度\'+position.coords.speed+\'\n\'  //得到经度
            text.value+=\'事件戳\'+position.coords.timeStamp+\'\n\'  //得到经度
        },function (error) {
            //地理位置获取失败
            //清除定时器
           navigator.geolocation.clearWatch(time)
        },{
            enableHighAcuracy:true,  //高准确的
            timeout:5000  //请求限制的事件
            可以配置更新的频率
        })
    }
}

本地存储

cookie存储特点
1、存储限制
2、客户端 服务器端 都会请求服务器
3、页面之间cookie是共享的
storage存储的特点
sessionstorage 临时会话页面打开到关闭的时间段 页面之间是不会共享的哪怕是在一个域名下
LocalStorage 永久存储 必须手动删除 页面之间是可以共享的
存储5M
客户端完成,不会请求服务器处理
sessionStorage数据是在页面之间是不共享的、localStorage页面之间可以共享数据 即使浏览器关闭数据也还在 除非用主动删除数据
本地存储的方法
sessionStorage.setItem(key,value) 设置key和value sessionStorage.getItem(key) 得到value
sessionStorage.removeItem(key)删除key对应的值 sessionStorage.clear() 删除全部的数据
本地存储的事件
window.addEventListener(\'storage\',function(){})

但是这个事件不会在对数据进行改变的窗口上触发 在本页面上触发不了 但是在其他的共享页面上可以触发

   window.addEventListener(\'storage\',function ( ev) {
            console.log(ev.key)
            console.log(ev.newValue)
            console.log(ev.oldValue)
            console.log(ev.storageArea)
            console.log(ev.url)
        },false)

实例同步购物车

    window.onload=function () {
        var aInput=document.getElementsByTagName(\'input\');
        for(var i=0;i<aInput.length;i++){
            aInput[i].onclick=function () {
                if(this.value){
                    window.localStorage.setItem(\'sel\',this.value);
                }else{
                    window.localStorage.setItem(\'onsel\',this.value);
                }
            }
        }
        window.addEventListener(\'storage\',function (ev) {
            console.log(ev.key)
            for(var i=0;i<aInput.length;i++){
                if(ev.key==\'sel\'){
                    for(var i=0;i<aInput.length;i++){
                            if(ev.newValue==aInput[i].value){
                                aInput[i].checked=true;
                            }
                    }
                }else if(ev.key==\'onsel\'){
                    for(var i=0;i<aInput.length;i++){
                        if(ev.newValue==aInput[i].value){
                            aInput[i].checked=false;
                        }
                    }
                }
            }

        },false)
    }

用户在选择完商品的时候 共享的页面也会同步的更新

音频和视频

audio video
两个标签的
src属性执行播放源
controls属性显示
autoplay属性控制自动播放
loop媒体是否循环播放
currenTime从开始到播放现在所用的时间 不仅可以读取 还可以设置
duration 媒体的总时间 是可读的
volume 0.0-1.0 音量的相对值
muted 是否是静音的状态
autobuffer 开始的时候 是否缓存加载
媒体元素的只读属性
paused 媒体是否正在暂停
ended 媒体是否播放结束
媒体元素的方法
play() 让媒体元素开始播放
pause() 让媒体元素暂停播放
load() 重新加载媒体 当媒体的源改变的额时候 必须使用这个方法才能在媒体元素上生效
媒体元素的事件
loadstart 开始加载的时候会触发
end 播放结束的时候会触发

video独有的属性
poster 视频播放的预览图片
width 视频播放界面的宽度 height 可以设置可以读取
videoWidth 视频实际的宽
利用 source标签 实现各个浏览器的播放兼容 这个标签是audio或者video的子标签