HTML5详解

01-HTML5新增语义化标签

<body

<header></header><!--页眉。主要用于页面头部的信息介绍,也可用于板块头部-->
<footer></footer><!--页脚。用在页面的底部或者板块的底部-->
<hgroup>
    <h1>妙味课堂</h1>
    <h2>极富有人情味的学习网站</h2>
</hgroup><!--页面上一个标题组合。一个标题和一个子标题,或者标语的组合-->
<nav></nav><!--用来表示导航。内容比较宽松-->

<section></section><!--代表一个页面上的区块或者板块,主要作用是用来划分页面上的不同区域-->

<article></article><!--代表页面上一个独立完整的内容部分-->

<aside></aside><!--和主体相关的附属信息-->

<figure></figure><!--媒体元素信息组合-->

<time></time><!--时间标签-->

<p>我在 <time datetime="2019-20-2">情人节</time>有个约会</p><!--方便查找-->


<input type="text" list="valueList">
<datalist id="valueList">
    <option value="java">java</option>
    <option value="html">html</option>
    <option value="css">css</option>
</datalist>


<details open><!--代表一个缩略信息,一般配合summary来使用.想默认展开,添加open属性-->
    <summary>课堂</summary>
    <p>国内知名的IT培训机构</p>
</details>

<dialog  ><!--定义一段对话-->
    <dt>老师:</dt>
    <dd>一加一等于几</dd>
    <dt>学生</dt>
    <dd>四</dd>
</dialog>

<address>by 痞子坦</address><!--定义文章或者页面作者的详细联系信息-->

<mark>这是一个mark,作用是标记</mark>

<!--还有一个公钥标签-->


<progress max="100" value="86"><!--max总值,value表示当前值-->
    <span>76</span>%<!--为了向下兼容-->
</progress>

</body>

HTML5语义化标签的兼容

    <style>
        *{
            margin: 0px;
            padding: 0px;
        }
        header{
            height: 100px;
            background-color: red;
        }
        article{
            padding: 10px;
            background-color: green;
            overflow: hidden;
            zoom: 1;
        }
        aside{
            width: 100px;
            height: 300px;
            background-color: gray;
            float: left;
        }
        section{
            margin-left: 210px;
            background-color: floralwhite;
            height: 300px;
        }
        footer{
            background-color: rebeccapurple;
        }
    </style>
</head>
<body>

<header>头部</header><!--页面头部-->

<article><!--主体部分-->
    <aside>侧边栏</aside><!--侧边栏-->
    <section>内容区域</section><!--右侧-->
</article>

<footer>底部</footer><!--底部-->


<!--
IE6的标签兼容方式是通过JS的创建元素

并且设置为block
-->
</body>

HTML5新增表单控件和表单属性

<!--HTML5表单新增控件-->

<form action="">
    <input type="text" value="1"name="a1">
    <input type="text" value="2"name="b1">
    <input type="submit">
    <input type="email" name="emall"><!--是emall.在移动端也会切换键盘-->
    <input type="tel"><!--在移动端会有一个切换数字键盘-->
    <input type="url"><!--输入网址-->
    <input type="search"><!--后面会多了一个取消-->
    <input type="range" step="1" min="2" max="8" value="2"><!--数值选择器-->
</form>


<form action="">
    <input type="number"><!--数值-->
    <input type="color"><!--颜色选择器-->
    <input type="datetime"><!--用来显示一个完整的日期-->
    <input type="datetime-local"><!--包含完整日期-->
    <input type="time"><!--包含完整日期-->
    <input type="date"><!--显示年月日-->
    <input type="week"><!--显示周-->
    <input type="month"><!--显示当前的月-->
</form>


<form action="http://www.baidu.com">
    <input type="text" placeholder="请输入4-16个字符" name="user"><!--默认提示,输入之后会消失-->
    <input type="text" name="usrname" autocomplete="off"><!--是指是否保存历史输入值-->

    <input type="password"autofocus="autofocus"><!--设置焦点属性-->

    <input type="text" required><!--此项为必填项-->
    <input type="text"pattern="\d{1,5}"><!--正则-->
    <!--上面这两个属性,在PC端通过修改,可以直接破解掉的-->


    <input type="submit"formaction="http://www.qq.com"value="保存到草稿箱"><!--保存到草稿箱,走的是两套不同的逻辑-->
    <input type="submit">
</form>

HTML5表单验证反馈

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

<script>
    var oText = document.getElementById('text');

    oText.addEventListener('invalid',function(){//验证是否为空
        alert(this.validity.valid);
    },false);//为true时候,不会弹出提示
</script>
捕获
//自定义验证
<script>
    var oText = document.getElementById('text');

    oText.addEventListener('invalid',function(){//验证是否为空
//        alert(this.validity.valid);
        alert(this.validity.customError);//符合自定义验证返回true

    },false);

    oText.oninput = function(){

    oText.oninput = function(){

        if(this.value == '敏感词'){
            this.setCustomValidity('请不要输入敏感词');
        }else{//这一段代码要注意
            this.setCustomValidity('');
        }
    }
    }
</script>

incalid事件:验证反馈

ev.preventDefault()//组织默认事件

formnovalidate//关闭验证
<input type="text"required id="text" formnovalidate>

新的选择器

<div id="div1" class="box1 box2 box3">

</div>


<script>
/*    document.querySelector();
    document.querySelectorAll();
    document.getElementsByClassName();*/

    var div1 = document.getElementById('div1');
    console.log( div1.classList);//获得CSS列表 类型是object[类数组],也可以得到长度
    div1.classList.add('cls');//添加
    div1.classList.remove('box2');//删除
    div1.classList.toggle('cls');//切换类[如果存在,就会删除。如果不存在,就会添加]
</script>

JSON的新方法

<script>
    //转换成JS
    var str = 'function show(){alert(1)};'
    eval(str);
    show();
</script>
    /*
    * eval可以解析任何字符串变成JS
    * parse()只能解析JSON形式的字符串编程JS.安全性会高一些
    * */

    var str = '{"name":"hello"}';//一定是严格形式JSON模式

    var json = JSON.parse(str);
    console.log(json.name);
//JSON转换为字符串
    var json = {name:'hellow'};

    var str = JSON.stringify(json);
    console.log(str);
//深层拷贝。IE低版本存在兼容性问题

    var a = {
        name:'hello'
    }

    var str = JSON.stringify(a);
    var b = JSON.parse(str);

    b.name = '小明';
    console.log(a.name);
    console.log(b.name);

自定义数据与JS加载

<script>

    /*
    * 一些框架就是使用的自定义属性
    * */
    var getDiv1 = document.getElementById('div1');

    console.log(getDiv1.dataset.miaov);
    console.log(getDiv1.dataset.ketang);
</script>
 <script src="a.js" defer="defer"></script><!--延迟执行。只能加在外联。在onload之前执行-->
    <script src="a.js" async="async"></script><!--异步执行加载,齐头并进,顺序很难保证-->

专门做异步加载的库:labjs库

历史管理器history

<script>
/*
*
* 触发历史管理
*   - 切换Hash也会改变历史管理
*   - 跳转页面
*   - pushState
* */
    var oInput  = document.getElementById('input1');
    var oDiv = document.getElementById('div1');

    var json = {};

    oInput.onclick = function(){

        var num = Math.random();
        var arr = randomNum(35,7);
        json[num] = arr;
        oDiv.innerHTML = arr;

        window.location.hash = num;

        //console.log(json);
    }

    /*随机生成函数*/
    function randomNum(iAll,iNow){
        var arr = [];
        var newArr = [];
        for(var i =1;i<=iAll;i++){
            arr.push(i);
        }

        for(var i=0;i<iNow;i++){
            newArr.push(arr.splice(Math.floor(Math.random()*arr.length),1));
        }
        return newArr;
    }

    /*哈希值的改变,事件就会触发*/
    window.onhashchange = function(){
        console.log(window.location.hash.substring(1));/*得到的是一个带#号的*/

        oDiv.innerHTML = json[window.location.hash.substring(1)];
    }
</script>
<script>
    /*
     *//必须是在服务器环境下
     * 触发历史管理
     *   - 切换Hash也会改变历史管理
     *   - 跳转页面
     *   - pushState
     * */
    var oInput  = document.getElementById('input1');
    var oDiv = document.getElementById('div1');


    //pushState改变历史管理,在不刷新页面,没有hash值的情况下。但是不能够刷新!
    oInput.onclick = function(){

        var arr = randomNum(35,7)
        history.pushState(arr,'',arr);/*[存数数据,title 地址(可选)]*/
        oDiv.innerHTML = arr;
    }

    window.onpopstate = function(ev){

        oDiv.innerHTML=ev.state;//作用就是取出对应历史管理的值
    }
    /*随机生成函数*/
    function randomNum(iAll,iNow){
        var arr = [];
        var newArr = [];
        for(var i =1;i<=iAll;i++){
            arr.push(i);
        }

        for(var i=0;i<iNow;i++){
            newArr.push(arr.splice(Math.floor(Math.random()*arr.length),1));
        }
        return newArr;
    }
</script>

拖放操作一

    var div1 =document.getElementById('div1');
    var getLi =document.getElementsByTagName('li');
    var i =0;
    var t =0;

    for(var i =0;i<getLi.length;i++){

        getLi[i].ondragstart = function(){/*拖拽的一瞬间出发*/
            this.style.background = 'pink';
        }
        getLi[i].ondragend = function(){/*拖拽的一瞬间出发*/
            this.innerHTML = '拖拽结束';
            this.style.background = 'red';

        }
        getLi[i].ondrag = function(){/*元素移动的时候触发,即使不动也会触发*/
            document.title = i++;
        }

        /*目标事件*/

        div1.ondragenter = function(){
            this.style.background = 'yellow';
        }

        div1.ondragover = function(ev){//与ondrag类似
            document.title = t--;
            ev.preventDefault();
        }
        div1.ondragleave = function(){
            this.innerHTML = '主动元素离开';
            this.style.background = 'green';
        }

        div1.ondrop = function(){//释放的时候触发。要想触发此事件,必须阻止ondragover的默认时间
            alert(1);
        }

捕获

拖放操作二

解决火狐下不能够拖拽的问题

    /*
    * 火狐的兼容解决
    * 必须设置dataTransfer对象的setData方法才可以拖拽除图片外的其他标签
    * */

    /*
    * dataTransfer是出现在event对象下的
    *
    * setData():设置数据key和value(必须是字符串)
    * getData():获取数据,根据key值,获取对应的value
    * */
    var div1 =document.getElementById('div1');
    var getLi =document.getElementsByTagName('li');
    var ul = document.getElementById('ul1');
    var i =0;
    var t =0;

    for(var i =0;i<getLi.length;i++){

        getLi[i].index = i;
        getLi[i].ondragstart = function(ev){/*拖拽的一瞬间出发*/
            var ev = ev||event;

            ev.dataTransfer.setData('name',this.index);/*设置好这个数据之后,就可以拖拽,释放了[必须是字符串]*/


            this.style.background = 'pink';
        }
        getLi[i].ondragend = function(){/*拖拽的一瞬间出发*/
            this.innerHTML = '拖拽结束';
            this.style.background = 'red';

        }
        getLi[i].ondrag = function(){/*元素移动的时候触发,即使不动也会触发*/
            document.title = i++;
        }

        /*目标事件*/

        div1.ondragenter = function(){
            this.style.background = 'yellow';
        }

        div1.ondragover = function(ev){//与ondrag类似
            document.title = t--;
            ev.preventDefault();
        }
        div1.ondragleave = function(){
            this.innerHTML = '主动元素离开';
            this.style.background = 'green';
        }

        div1.ondrop = function(ev){//释放的时候触发。要想触发此事件,必须阻止ondragover的默认时间
//            alert(ev.dataTransfer.getData('name'));
            ul.removeChild(getLi[ev.dataTransfer.getData('name')]);

            for(var i =0;i<getLi.length;i++){

                getLi[i].index = i;
            }
        }

    }

<script>
    var div1 =document.getElementById('div1');
    var getLi =document.getElementsByTagName('li');
    var ul = document.getElementById('ul1');
    var i =0;
    var t =0;

    for(var i =0;i<getLi.length;i++){

        getLi[i].index = i;
        getLi[i].ondragstart = function(ev){/*拖拽的一瞬间出发*/

            var ev = ev||event;
            ev.dataTransfer.setData('name','hello');

            ev.dataTransfer.effectAllowed = 'link';/*设置移动鼠标样式 copy*/
            ev.dataTransfer.setDragImage(div1,100,100)/*设置当前拖拽样式.阴影可以变成我们指定样式,指定是必须的*/

        }
        getLi[i].ondragend = function(){/*拖拽的一瞬间出发*/
            this.innerHTML = '拖拽结束';
            this.style.background = 'red';

        }
        getLi[i].ondrag = function(){/*元素移动的时候触发,即使不动也会触发*/
            document.title = i++;
        }

        /*目标事件*/

        div1.ondragenter = function(){
            this.style.background = 'yellow';
        }

        div1.ondragover = function(ev){//与ondrag类似
            document.title = t--;
            ev.preventDefault();
        }
        div1.ondragleave = function(){
            this.innerHTML = '主动元素离开';
            this.style.background = 'green';
        }

        div1.ondrop = function(ev){

        }

    }
</script>

拖放操作三

<script>

    /*
    * 将图片拖拽到区域的话,就会执行浏览器默认行为,打开图片
    *
    * */
    var getDiv = document.getElementById('div1');

    getDiv.ondragenter = function(){
        this.style.backgroundColor = 'red';
        this.innerHTML = '可以释放';
    }
    getDiv.ondragover = function(ev){
        var ev = ev||event;
        this.style.backgroundColor = 'pink';
        ev.preventDefault();
    }
    getDiv.ondragleave = function(){
        this.innerHTML = '将文件拖拽到此区域';
    }

    /*
    *dataTransfer对象
    *   - files属性:
    *       - 获取外部拖拽的文件,返回一个filesList列表
    *       - filesList下有个type属性,返回文件的类型
    *       - .length 返回文件的个数
    * */

    /*
    * FileReader(读取文件信息的对象)
    *   - readAsDataURL
    *       - 参数为要读取的文件对象,将文件读取为DataUrl[文件信息]
    *
    *   - onload
    *       - 当读取文件成功完成的时候触发此事件
    *       - this.result,来获取读取的文件数据,如果是图片,将返回base64格式的图片数据
    *
    * */


    getDiv.ondrop = function(ev){

        var ev = ev||event;
        ev.preventDefault();
        this.innerHTML = '释放';

        var fs = ev.dataTransfer.files;
        console.log(fs[0].type);
        console.log(fs.length);

        var fd = new FileReader();
        fd.readAsDataURL(fs[0]);//读取文件
        fd.onload = function(){//如果读取成功就会触发onload事件
            alert(this.result);//获取文件的信息
        }

    }
</script>
<script>

    /*
     * 将图片拖拽到区域的话,就会执行浏览器默认行为,打开图片
     *
     * */
    var getDiv = document.getElementById('div1');
    var oUl = document.getElementById('ul1');

    getDiv.ondragenter = function(){
        this.style.backgroundColor = 'red';
        this.innerHTML = '可以释放';
    }
    getDiv.ondragover = function(ev){
        var ev = ev||event;
        this.style.backgroundColor = 'pink';
        ev.preventDefault();
    }
    getDiv.ondragleave = function(){
        this.innerHTML = '将文件拖拽到此区域';
    }



    getDiv.ondrop = function(ev){

        var ev = ev||event;
        ev.preventDefault();
        this.innerHTML = '释放';

        var fs = ev.dataTransfer.files;
        console.log(fs[0].type);
        console.log(fs.length);


        //读取多张文件
        for(var i=0;i<fs.length;i++){
            if(fs[i].type.indexOf('image')!=-1){
                    var fd = new FileReader();
                    fd.readAsDataURL(fs[i]);//读取文件
                    fd.onload = function(){//如果读取成功就会触发onload事件
                    var oLi = document.createElement('li');
                    var oImg = document.createElement('img');
                     oImg.src = this.result;
                    oLi.appendChild(oImg);
                     oUl.appendChild(oLi);
                    console.log(this.result);//获取文件的信息
            }
        }else{
            alert('请上传图片');
        }
        }
    }
</script>

拖放实例

一个简单的拖拽购物车

<script>
    /*
    * 拖拽购物车
    * */
    var aLi = document.getElementsByTagName('li');
    var oDiv = document.getElementById('buyCar');
    var obj = {};
    var iNum = 0;
    var allMoney = null;
    console.log(aLi.length);

    for(var i=0;i<aLi.length;i++){
        aLi[i].ondragstart = function(ev){

            console.log(this);
            var ev = ev||event;
            var aP = this.getElementsByTagName('p');
            ev.dataTransfer.setData('title',aP[0].innerHTML);
            ev.dataTransfer.setData('money',aP[1].innerHTML);
            ev.dataTransfer.setDragImage(this,0,0);

        }
        oDiv.ondragover = function(ev){
            ev.preventDefault();
        }

        oDiv.ondrop = function(ev){
            var ev = ev||event;

            ev.preventDefault();//默认行为是图片被打开
            var sTitle = ev.dataTransfer.getData('title');
            var sMoney = ev.dataTransfer.getData('money');

            if(!obj[sTitle]){
            var oP = document.createElement('p');
            var oSpan = document.createElement('span');
            oSpan.className = 'box1';
            oSpan.innerHTML = 1;
            oP.appendChild(oSpan);

            var oSpan = document.createElement('span');
            oSpan.className = 'box2';
            oSpan.innerHTML = sTitle;
            oP.appendChild(oSpan);

            var oSpan = document.createElement('span');
            oSpan.className = 'box3';
            oSpan.className = sMoney;
            oSpan.innerHTML = sMoney;
            oP.appendChild(oSpan);

            oDiv.appendChild(oP);
                obj[sTitle] = 1;
            }else{
                var box1 = document.getElementsByClassName('box1');
                var box2 = document.getElementsByClassName('box2');

                for(var i=0;i<box1.length;i++){

                    if(box2[i].innerHTML == sTitle){
                        box1[i].innerHTML = parseInt(box1[i].innerHTML)+1;
                    }
                }
            }

            if(!allMoney){

                allMoney = document.createElement('div');
                allMoney.id = 'allMoney';
            }
            iNum += parseInt(sMoney);
            allMoney.innerHTML = iNum+'¥';
            oDiv.appendChild(allMoney);

        }
    }

</script>

canvas基础

<canvas id="c1" width="400px" height="400px"><!--一般是这样设置宽高-->
    <!--canvas在不支持canvas的浏览器下可以看到内容-->
    <!--默认大小宽300px,高150px-->
</canvas>


<script>
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');//创建绘图环境。目前只支持2d

    oGC.fillStyle = 'red';//修改北京颜色
    oGC.strokeStyle = 'blue';//修改边框颜色
    oGC.lineWidth = '2';//修改边框大小


    // L T W H
    oGC.fillRect(50,50,100,100);/*绘制填充方块*/
    oGC.strokeRect(80,80,100,100)/*绘制边框方块。默认大小是1px ,其实是2px,左右移动0.5半个像素。设置.5可以避免*/
</script>
<script>
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');//创建绘图环境。目前只支持2d

    /*
    * 边界绘制
    *   linejon:边界连接点样式
    *       - miter[默认],round[圆角],bevel[斜角]
    *   lineCap:端点样式
    *       - butt[默认] round[圆角] square[高度多出为宽一般的值]
    *
    * 绘图路径
    *   - beginpath:开始绘制路径
    *   - closepath:结束绘制路径||起终点进行连接
    *   - moveTo:移动到绘制的新目标点
    *   - lineTo:新的目标点
    *
    *   - stroke:画线,默认黑色
    *   fill:填充,默认黑色
    *   rect:矩形区域
    *   clearRect:删除一个画布的矩形区域
    *   save:保存路径
    *   restore:恢复路径
    * */

    oGC.lineJoin = 'round';
    oGC.lineWidth = '5';
    // L T W H
    oGC.fillRect(50,50,100,100);
    oGC.strokeRect(80,80,100,100);


    oGC.beginPath();
    oGC.moveTo(100,100);
    oGC.lineTo(200,200);
    oGC.lineTo(300,200);
    oGC.closePath();
    oGC.stroke();
</script>
      oGC.clearRect(0,0,oC.width,oC.height);//清空画布。[X,Y,W,H]
    oGC.save();  
    //封闭路径。比如说中间是一个设置背景颜色的是全局通用。如果加在这个里面就是局部
    oGC.restore();

使用style修改的宽高是进行缩放的,会带来像素扭曲

canvas基础二

    // 弧度=角度*Math.PI/180

    oGC.moveTo(200,200);

    oGC.arc(200,200,150,0,90*Math.PI/180,false);//false是顺时针,true是逆时针
    //[X,Y,半径,起始弧度,结束弧度,旋转方向]//X Y 表示中心
    oGC.stroke();//画线
    oGC.beginPath();
    oGC.moveTo(100,200);
    oGC.arcTo(100,100,200,100,50);//绘制曲线[起点X,起点Y,终点X,终点Y,半径]
    oGC.stroke();//画线
    oGC.closePath();
    oGC.quadraticCurveTo(100,100,200,100);//贝塞尔曲线[X,Y,C1,C2] //贝塞尔曲线。控制点1,控制点2,结束坐标1,结束坐标2

     oGC.bezierCurveTo(100,100,200,200,200,100);//两个点贝塞尔曲线[X1,Y1,X2,Y2,C1,C2] //控制点1,控制点2,结束坐标1,结束坐标2.
    /*
    * translate
    *   - 偏移
    * rotate
    *   - 旋转:参数为弧度
    * scale
    *   - 缩放
    * */

    oGC.translate(100,100);//移动[X,Y]
    oGC.rotate(45*Math.PI/180);
    oGC.scale(0.5,0.5);
    oGC.fillRect(0,0,100,100);

    oGC.translate(100,100);//移动[X,Y]
    setInterval(function(){
        num++;

        oGC.save();//封闭
        oGC.clearRect(0,0,oC.width,oC.height);
        oGC.rotate(num*Math.PI/180);
        oGC.translate(-50,-50);
        oGC.fillRect(0,0,100,100);
        oGC.restore();//封闭
    },30)

canvas基础

  /*
    * - 插入图片,等图片加载完在执行canvas方法
    *   - 图片预加载:在onload中调用方法
    * - drawlmage(oimg,x,y,w,h)
    *   - oimg:当前图片 x,y:坐标 w h:宽高
    *   - 例子:微博的图片旋转效果
    *oGC.drawImage(obj,0,0,400,400)//[图片对象,X轴坐标,Y轴坐标,宽度,高度].如果两个   *宽高参数不写会自适应宽高
    *
    *
    *createPattem(oimg,平铺方式)
    *- 2参为:repeat,repeat-x,repeat-y,no-repeat
    *
    */
        var bg = oGC.createPattern(obj,'repeat');/*设置背景:[img,平铺方式*/

        oGC.fillStyle = bg;/*填充背景*/
        oGC.fillRect(0,0,300,300);
//线性渐变
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');

    
    var obj = oGC.createLinearGradient(150,100,150,200);/*线性渐变。[起点X,起点Y,终点X,终点Y]*/

    obj.addColorStop(0,'red');//起点
    obj.addColorStop(0.5,'pink');//中间可以添加多个点
    obj.addColorStop(1,'blue');//终点

    oGC.fillStyle = obj;
    oGC.fillRect(150,100,100,100);
    //放射性渐变
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');


    var obj =oGC.createRadialGradient(200,200,100,200,200,150);//放射性渐变[X1,Y1,R1,X2,Y2,R2]

    obj.addColorStop(0,'green');//起点
    obj.addColorStop(0.5,'yellow');//中间可以添加多个点
    obj.addColorStop(1,'blue');//终点

    oGC.fillStyle = obj;
    oGC.fillRect(0,0,oC.width,oC.height);
<script>
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');

    oGC.font = '60px impact';//文字大小和文字样式[文字默认不是在左上角居中的]
    oGC.textBaseline='top';// middle bottom
    oGC.fillText('妙味课堂',0,0);
    oGC.strokeText('课堂',0,200) //这个表示的是画线
    /*
    * strokeText(文字,x,y)
    *   - 文字边框
    * fillText(文字,x,y)
    *   - 文字填充
    *
    * font
    *   - 文字大小:'60PX impact'
    * textAlign //表示基准点
    *   - 默认是start跟left一样的效果 end right center
    *
    *  textBaseline //表示基准点
    *    - 文字上下的位置的方式默认:alphabetic
    * */


</script>

<script>
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');

    oGC.font = '60px impact';//文字大小和文字样式
    oGC.textBaseline='top';// middle bottom

    /*
    * measureText()
    *   - measureText(str).width 只有宽度,没有高度
    *
    * 阴影:
    * shadowOffsetX shadowOffsetY
    *   - X轴偏移,Y轴偏移
    * shadowBlur
    *   - 高斯模糊值
    * shadowColor
    *   - 阴影颜色
    * */

    var w = oGC.measureText('妙味课堂').width;
    console.log(w);
    oGC.fillText('妙味课堂',(oC.width-w)/2,(oC.height-60)/2);
</script>
<script>
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');

    oGC.font = '60px impact';//文字大小和文字样式
    oGC.textBaseline='top';// middle bottom

    oGC.shadowOffsetX = 20;//阴影偏移量.但是必须要设置颜色才能显示
    oGC.shadowOffsetY = 20;//阴影偏移量.但是必须要设置颜色才能显示
    oGC.shadowBlur = 5;//高斯模糊值
    oGC.shadowColor = 'yellow';//阴影颜色。默认颜色是黑色透明

    var w = oGC.measureText('妙味课堂').width;
    console.log(w);
    oGC.fillText('妙味课堂',(oC.width-w)/2,(oC.height-60)/2);
</script>

canvas基础


<!--
像素:
    getimageData(x,y,w,h)
        - 获取图像数据
    putimageData(获取图像,x,y)
        - 设置新的图像数据

    属性:
        - width:一行的像素个数
        - Height:一列的像素个数
        - data:一个数组。包含每个像素的rgba四个值,注意每个值都在0~255之间的整数[100*100存在40000个像素]
-->
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');

    oGC.fillRect(0,0,100,100);

    /*
    * 获取像素点*/
    var pixel =  oGC.getImageData(0,0,100,100);
    console.log(pixel.width);
    console.log(pixel.height);
    console.log(pixel.data);//整体像素的数组集合

    for(var i =0;i<pixel.width*pixel.height;i++){

        pixel.data[4*i] = 255;
        pixel.data[4*i+1] = 0;
        pixel.data[4*i+2] = 0;
        pixel.data[4*i+3] = 255;//表示透明度,范围是从0-255
    }
    oGC.putImageData(pixel,100,100);

    /*
    * createImageData(w,h)
    *   - 生成新的像素矩阵,初始值是全透明的黑色,即是(0,0,0,0)
    *   -像素显字
    *
    * */

canvas基础教程五

在canvas中,画布画的每个图形都是由像素组成的

   /*
    * 源:新的图形
    * 目标:已经绘制过的图形
    * - oGC.globalCompositeOperation
    *   - sourec-over默认属性/*+--
    *   - destination-over 目标属性会覆盖
    *   
    *
    *
    * */

    oGC.globalCompositeOperation = 'destination-over';
    oGC.fillRect(50,50,100,100);

oGC.globalAlpha = 0.5;/*设置全局透明度*/

属性

    /*
    * 将画布导出为图像
    *   - toDataURL
    *       - 而火狐右键可以直接导出成图片
    * 事件操作
    *   - isPointlnPath
    *       - 是否在点击范围内
    * */
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');
    var img1 = document.getElementById('img1');
    oGC.fillStyle = 'green';
    oGC.fillRect(10,10,100,100);


    oGC.globalCompositeOperation = 'source-over';
    oGC.fillStyle = 'red';
    oGC.fillRect(50,50,100,100);
    img1.src = oC.toDataURL();//图片默认是透明的
   // alert(oC.toDataURL());//是一个64位的图片地址信息
//事件操作

<script>
    var oC = document.getElementById('c1');
    var oGC = oC.getContext('2d');
    var img1 = document.getElementById('img1');

/*    //第一个事件
    oGC.beginPath();
    oGC.arc(100,100,50,0,360*Math.PI/180,false);
    oGC.closePath();
    oGC.fill();

    //第二个事件
    oGC.beginPath();
    oGC.arc(200,200,50,0,360*Math.PI/180,false);
    oGC.closePath();
    oGC.fill();*/

    /*    /!*
     * 事件只会在第二个事件上生效
     * *!/
     oC.onmousedown = function(ev){
     var ev = ev||event;
     var x = ev.clientX - oC.offsetLeft;
     var y = ev.clientY - oC.offsetTop;

     if(oGC.isPointInPath(x,y)){
     alert(1);
     }
     }*/

    var c1 = new Shape(100,100,50);//生成图形
    var c2 = new Shape(200,200,50);//生成图形
    
    oC.onmousedown = function(ev){
        var ev = ev||event;
        var point = {
            x:ev.clientX - oC.offsetLeft,
            y:ev.clientY - oC.offsetTop,

        }
        c1.reDraw(point);
        c2.reDraw(point);
    }

    c1.click = function(){
        alert(1233);
    }
    
    c2.click = function(){
        alert(456);
    }


    function Shape(x,y,r){
        this.x = x;
        this.y = y;
        this.r = r;

        oGC.beginPath();
        oGC.arc(this.x,this.y,this.r,0,360*Math.PI/180,false);
        oGC.closePath();
        oGC.fill();
    }
    Shape.prototype.reDraw = function(point){

        oGC.beginPath();
        oGC.arc(this.x,this.y,this.r,0,360*Math.PI/180,false);
        oGC.closePath();
        oGC.fill();

        if(oGC.isPointInPath(point.x,point.y)){
            this.click();
        }
    }

</script>
//是采用重新绘制来解决问题

jCanvaScript(canvas中的jquery)

canvas 元素用于在网页上绘制图形。

01

  • canvas设置宽高. 默认宽300,高150

  • fillRect(x,y,w,h) //默认绘制已填黑色的矩形

  • strokeRect(x,y,w,h) //绘制无填充的边框矩形

  • fillStyle = ; //定义填充颜色

  • strokeStyle = ; //修改边框颜色

  • lineWidth = ; //borderer宽度

  • lineJoin= ; //修改矩形边角样式[默认尖角]

  • beginPath() // 在画布中开始子路径的一个新的集合

  • moveTo(x,y) //起始点的位置

  • lineTo(x,y) //到达一个点

  • closeePath //结束绘制路径||创建一个从当前点到起始点的路径

  • stroke() //实际绘出线

  • fill() //填充当前图像

  • rece(x,y,w,h) //绘制矩形

  • clearRect(x,y,w,h) //清除画布

  • save() //保存路径

  • restore() //恢复路径 [他们两个就像是局部函数,对外不造成影响]

  • lineCap = ; //设置线条末端的线帽的样式

02

[弧度= 角度*Math.PI/180]

  • arc(x,y,r,起始弧度,结束弧度,时针); //绘制一个圆形

  • arcTo(x1,y1,x2,y2,r); //绘制一个弧形

  • quadraticCurveTo(); //二次贝塞尔曲线

  • bezierCurveTo(); // 三次贝塞尔曲线

  • translate(x,y); //偏移[移动到Xpx与Ypx]

  • rotate(弧度); //旋转

  • scale(x,y) //缩放

03

  • drawImage(img,x,y) //在画布上绘制图片[加载完图片之后执行]

  • createPattern(img,repleat); //设置要重复的方式

  • createLinearGradient(); //渐变

  • addColorStop(); //添加渐变

  • createRadialGradient() //渐变圆

  • font //设置字体大小及字体

  • fillText //生成字体[填充]

  • strokeText //生成字体[线条]

  • textBaseline //设置文本基线[类似于拼音格]

  • strokeStyle //设置线条颜色

  • fillStyle //设置填充颜色

  • measureText('检查的字体').width //在画布上输出文本之前,检查文本的宽度

  • shadowOffsetX; //阴影X偏移量
  • shadowOffsetY; //阴影Y偏移量
  • shadowBlur; //阴影模糊度
  • shadowColor; //阴影颜色

04

  • getImageData(x,y,w,h) // 返回canvas的像素数据

  • .width

  • .height

  • .data.length //整体像素的数组集合[100*100的区域有4W个数组]

  • putImageData(); //把像素数据放回到画布中

  • createImageData(w,h); //Create ImageData Object

05

  • globalAlpha; //设置全局透明度
  • globalCompositeOperation //设置叠加方式
  • toDataURL(); // canvas图片信息
  • isPointInPath(x,y) //事件。如果在绘制图内点击就会触发

祖玛

//在canvas中,让动画动起来,其实都是重新绘制

准备工作和同域下的窗口通信

<input type="button" value="changeIframeBG" id="input1">
<iframe id="myframe" src="02_ifarm.html"></iframe>

<script>
    var getInput = document.getElementById('input1');
    var getiframe = document.getElementById('myframe');

    /*
    * iframee中的contentWindow就相当于 window对象
    *
    * */
    getInput.onclick = function(){
        getiframe.contentWindow.document.body.style.backgroundColor = 'yellow';
    }
</script>
//这是window的open对对象
    var btn = document.getElementById('btn');
    var btn1 = document.getElementById('btn1');
    var newWindow = null;
    btn.onclick = function(){

        //返回打开窗口的window对象
        newWindow = window.open('04_window.open.html','_blank');
    }
    btn1.onclick = function(){
        newWindow.document.body.style.backgroundColor = 'pink';
    }

窗口跨域操作问题和postMessage的使用

    /*
     * 跨域 操作是禁止的
     *  本页面和包含页面不在同一个域名下的时候,这样操作就会有跨域安全限制问题
     *
     *  postMessage:可以通过这个对象下的方法给另外一个窗口发送信息。[方法是全局的].只能够发送数据,不能够操作DOM
     *
     *  接收消息的窗口的window对象.postMessage(发送的数据,接收的域);
     *
         * */
    getInput.onclick = function(){
        //getiframe.contentWindow.document.body.style.backgroundColor = 'yellow';
        getiframe.contentWindow.postMessage('ac','http://www.bb.com');
    }
<script>
    /*
    * message[事件];当窗口接收到通过postMessage发送过来的数据的时候触发
    * */

    /*
    * iframe 父页面:contentWindow 子页面 window.top
    * */
    window.addEventListener('message',function(ev){
        //message事件的对象保存了发送过来的内容
        //ev.data:发送过来的数据
        // ev.origin 发送消息的域
        var ev = ev||event;
        alert('接收到内容了'+',内容是:'+ev.data);
        alert(ev.origin);
    },false);
</script>
在同域下面
    /*
    * window //当前窗口
    * parent //父级窗口
    * window.top //指的是顶层
    * */
        window.top.document.body.style.background = 'green';

//window.opener[作用范围是在同域下]

    sonBtn.onclick = function(){
        window.opener.document.body.style.backgroundColor = 'gold';
    }
/*
    * parent->window  如果当前页面是顶级,没有被其他页面所包含,那么parent就是当前页面的window对象。如果包含了,则parent就是包含当前页面的父级页面的window对象
    * */center
/*
    * parent->window  如果当前页面是顶级,没有被其他页面所包含,那么parent就是当前页面的window对象。如果包含了,则parent就是包含当前页面的父级页面的window对象
    *
    * window对象
    * parent对象
    *
    * */

ajax跨域的问题和处理

<script>

    var btn = document.getElementById('btn');

    btn.onclick = function(){

                /*
                 *
                 * 在标准浏览器下,XMLHttpRequest对象已经是升级版本,支持更多特性,可以跨域请求。但是如果想实现跨域请求,还需要后端的相关配合
                 * */

                /*
                 *
                 * 添加
                 *
                 * 文件:
                 *    <?php
                 *header('Access-Control-Allow-Origin:*');
                 *echo 'hello';
                 * */
                var xhr = new XMLHttpRequest();

                xhr.open('get','http://www.bb.com/readAjax.php',true);
                xhr.send();

                xhr.onreadystatechange = function(){

                    if(xhr.readyState == 4){
                        if(xhr.status == 200){
                            alert(xhr.responseText);
                        }
                    }
                }
            }
</script>
    btn.onclick = function(){

                /*
                 *
                 * 在标准浏览器下,XMLHttpRequest对象已经是升级版本,支持更多特性,可以跨域请求。但是如果想实现跨域请求,还需要后端的相关配合
                 * */

                /*
                 *
                 * 添加
                 *
                 * 文件:
                 *    <?php
                 *header('Access-Control-Allow-Origin:*');
                 *echo 'hello';
                 * */

                /*
                *
                *  XDomainRequest: IE如果想实现跨域请求,则需要另外的对象去实现.IE10-不支持
                *
                * */
                var xhr = new XMLHttpRequest();

                xhr.open('get','http://www.bb.com/readAjax.php',true);
                xhr.send();

                xhr.onreadystatechange = function(){

                    if(xhr.readyState == 4){
                        if(xhr.status == 200){
                            alert(xhr.responseText);
                        }
                    }
                }
            }
IE 下 [IE10-,eage支持标准方法]

    var btn = document.getElementById('btn');

    btn.onclick = function(){

                var xdr = new XDomainRequest();
                xdr.open('get','http://www.bb.com/readAjax.php',true);
                xdr.send();

                xdr.onload = function(){
                    alert(xdr.responseText);
                }

            }

XMLHttpRequest增加了很多功能,不推荐使用onreadystatechange来监听,推荐使用onload

ajax无刷新上传

<body>

<input type="file" id="myF" >
<input type="button" id="btn" value="上传">

<div id="div1">
    <div id="div2"></div>
    <div id="div3">0%</div>
</div>
<script>
    var btn = document.getElementById('btn');
    var myF = document.getElementById('myF');

    var div1 = document.getElementById('div1');
    var div2 = document.getElementById('div2');
    var div3 = document.getElementById('div3');

    btn.onclick = function(){

        //alert(myF.value);//获取到的是file空间的value值,这个内容是显示给你看的文字,不是我们选择的文件。
       // console.log(myF.files);//这个里面保存了选择的内容

        // 我们通过ajax把myF.files[0] 发送给后端

        /*for(var attr in myF.files[0]){

            console.log(myF.files[0][attr]);
        }*/
        var xhr = new XMLHttpRequest();

        xhr.onload = function(){//发送成功,后端返回之后进行执行
           // var d = JSON.parse(this.responseText);

            alert('上传成功');
            //alert(d.msg+':'+ d.url);
        }

        var oUPload = xhr.upload;//表示上传进度对象
        oUPload.onprogress = function(ev){
            console.log('要发送的数据:'+ev.total);
            console.log('已经发送的数据:'+ev.loaded);

            var iScale = ev.loaded/ev.total;

            div2.style.width = 300*iScale+'px';
            div3.innerHTML = iScale*100+'%';
        }

        xhr.open('post','post_file.php',true);
        xhr.setRequestHeader('X-Request-With', 'XMLHttpRequest');

        var oFormData = new FormData();//通过ForeData来提交数据
        oFormData.append('file',myF.files[0]);
        xhr.send(oFormData);
    }
</script>

nodejs的安装搭建和一个简单http服务器的实现

websocket协议
TCP/IP协议

  • 定义了电子设备如何连入因特网,以及数据在它们之间传输数据的标准(如何传输)
  • 传输数据[协议]类型:Email,www,FTP等
    HTTP协议
  • 浏览器和万维网服务器之间通信的规则

HTTP协议特点

  • 功能强大
  • 采用请求,响应模式,单向通信
  • 短连接,响应完成链接就断开
    实时web交互
  • 股票,网游
  • 实现服务器主动推送
websocket

搭建HTTP服务器

var http = require('http');//加载模块

var serv = http.createServer(function(req,res){//一个是请求,一个是响应
    console.log('有人进来了');//执行回调函数

    res.writeHeader(404,{
        'content-type' : 'text/html;charset="utf-8"'
    });

    console.log(req);//请求者的用户信息
    res.write('欢迎访问');
    res.end();

}).listen(8888);//创建一个服务器并监听8888端口

console.log('服务器开启成功');
var http = require('http');
var fs = require('fs');//FS模块[文件系统模块],使用这一个去读取文件

var documentRoot = 'D:/learntest/websocket/www';//文件存储路径

var httpServer = http.createServer(function(req,res){//创建一个服务器

    var url = req.url;//获得用户请求的url
    console.log(url);

    var file = documentRoot+url;
    console.log(file);

    fs.readFile(file,function(err,data){//去读取文件 参数[代表失败参数,读取来的文件内容]
        if(err){
            res.writeHeader(404,{
                'content-type' : 'text/html;charset="utf-8"'
            });
            res.write('<h1 style="text-align: center;color: red">404</h1>');
            res.end();
        }else{
            res.writeHeader(200,{
                'content-type' : 'text/html;charset="utf-8"'
            });
            res.write(data);//读取获得来的数据
            res.end();
        }
    });
}).listen(8888);

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

nodejs-websocker服务器的创建和应用

  • node.js步骤
    • 安装node.js
    • 转到安装目录
    • 运行 node scriptname.js
    • http 服务区的创建
    • 安装websocket模块[npm install socket.io]后面可以带参数,全局模式
    • websocket服务的创建
      实际创建中是失败,失败原因是由于版本的问题
      实际文档查看 :socket.io

HTML5之离线存储

应用于与服务器没有交互的展示场景

<!doctype html>
<html lang="en" manifest="cache.manifest">
<head>
    <meta charset="UTF-8">
    <title>cache</title>
</head>
<body>

<img src="picture.jpg" alt="">


<!--
做到离线步骤
    - 服务器设置头信息
        - AddType text/cache-manifest .manifest->**前面是要存在一个空格**

        ~在apache中不加空格,服务器无法打开~
        wamp地址:apache->httpd-conf ->添加以上代码


    - html标签添加
        - manifest = "xxxxx.manifest" **添加在html标签上面**

    - 写manifst文件:离线的清单列表
        - 先写: CACHE MANIFEST
        - FALLBACK:第一个网络没有获取到,就走第二个缓存的
        - NETWORK:无论缓存中存在与否,均从网络获取

[离线存储可以存储字符串,图片,CSS,JS]

没有网络的时候就会去找清单。
-->
</body>
</html>
与html标签中的名字相同

需要缓存的文件

HTML5之workers

  • 什么是worker
    • JS的单线程[方式UI队列的个数,利用定时器解决]
    • 可以让web应用程序具备后台处理能力,对多线程的支持非常好
  • worker API
    • new Worker('后台处理的JS地址');
    • 利用postMessage传输数据
    • importScripts('导入其他JS文件');
可以使用的

HTML5之一些小功能

<div contenteditable="true" id="getDiv">我是一个可以编辑的属性</div>//内容编辑

地理信息与本地存储

    /*
     * - 位置从哪里获取
     *   IP地址
     *   GPS
     *   WIFI
     *   基站
     *
     **/

    oInput.onclick = function(){
        
        navigator.geolocation.getCurrentPosition(function(position){
            
            oT.value += '经度:' + position.coords.longitude+'\n';
            oT.value += '纬度 :' + position.coords.latitude+'\n';
            oT.value += '准确度 :' + position.coords.accuracy+'\n';
            oT.value += '海拔 :' + position.coords.altitude+'\n';
            oT.value += '海拔准确度 :' + position.coords.altitudeAcuracy+'\n';
            oT.value += '行进方向 :' + position.coords.heading+'\n';
            oT.value += '地面速度 :' + position.coords.speed+'\n';
            oT.value += '时间戳:' + new Date(position.timestamp)+'\n';
                
            
        },function(err){
            
            //err.code // 失败所对应的编号
            
            alert( err.code );
            
        },{
            enableHighAcuracy : true,
            timeout : 5000,//设置超时时间
            maximumAge : 5000
        });
        
    };//[请求成功回调,请求失败回调,收集方式]
     
};
位置请求

位置请求
位置请求
位置请求

navigator.geolocation.clearWatch(timer);//关闭请求, 与clearInterval();类似
frequency:5000//设置更新时间,在移动设备上有效

了解地图接口

地理信息与本地存储2

  • cookie每次运行都会请求服务器

storage

  • sessionStorage[数据不共享]
  • localStorage[数据共享]
stroage

地理信息与本地存储3

getInput[0].onclick = function(){
        window.sessionStorage.setItem('name',getInput[3].value);
    }

地理信息与本地存储4

  • 当数据有修改或删除的情况下,就会触发storage事件。[是与之共享的页面会触发.]
    实测在chrome中不支持事件
    StorageAPI

    有一个应用场景是一个同步购物车,估计到不经常使用网络的人群

地理信息与本地存储5

*ERR:浏览器位置不能获取位置

音频与视频 webWorkers 移动端HTML5

audio
video
source//兼容

HTML5打造自定义播放器

//时间是通过JS来进行控制的
setInterval(function(){
        console.log(a1.currentTime);
    },1000);
mediaElem
mediaElem2
媒体事件
  • video的额外特性
    • poster:视频播放前的预览图片
    • width,height:设置视频的尺寸
    • viderWidth,videoHeight:视频的原始尺寸[readOnly]

打造自定义播放器

自定义播放器

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容

  • 格式后期处理。 Jeremy Keith在 Fronteers 2010 上的主题演讲 今天我想跟大家谈一谈HTM...
    LordZhou阅读 1,116评论 0 17
  • HTML5 第一章 HTML5概述 H5是下一代的web开发的基础. 1.1 web技术发展时间线 1991 HT...
    whitsats阅读 1,017评论 0 0
  • 1. 浏览器页面有哪三层构成,分别是什么,作用是什么? 构成:结构层、表示层、行为层分别是:HTML、CSS、Ja...
    程序猿人王小贱阅读 1,863评论 1 11
  • HTML5< !--...--> 标签 comment 注释标签用于在源文档中插入注释。注释内容不会被浏览器显示。...
    野小宝阅读 1,308评论 0 10
  • HTML5 标签comment 注释标签用于在源文档中插入注释。注释内容不会被浏览器显示。为代码编写注释的好处是...
    才気莮孒阅读 4,023评论 1 25