html5

作者: llpy | 来源:发表于2017-03-04 11:07 被阅读19次

    html5新特性

    新的选择器

    querySelector

    选择一个(如果多个匹配返回第一个)

    document.querySelector('#div');
    document.querySelector('.div');
    document.querySelector('div');
    

    querySelectorAll

    选择多个

    getElementsByClass

    JSON

    JSON.parse

    把json格式的字符串转化为js对象

    json格式

    {
        "key":"value",
        "key2": 1, 
    }
    

    注意: 键值必须加双引号, 如果值是字符串,也必须加双引号

    var str = '{"key": "value"}';
    var obj = JSON.parse(str);
    

    JSON.stringify

    把js对象转化为json格式的字符串

    使用JSON.parse和JSON.stringify做深拷贝

    function deepCopy(obj){
        var str = JSON.stringify(obj);
        return JSON.parse(str);
    }
    
    var obj = { a: 1 };
    
    var objClone = deepCopy(obj);
    
    objClone.a = 2;
    
    console.log(obj.a);//1
    

    data自定义数据

    在html元素上以data-开头的属性,可以在相应的DOM对象上的dataset属性上得到其属性值

    <div data-index="1" data-sub-title="hello"></div>
    
    var oDiv = document.querySelector('div');
    console.log( oDiv.dataset.index );//1
    console.log( oDiv.dataset.subTitle );//hello  sub-title这样的多个-分割的形式,对应的属性为驼峰命名
    

    js加载

    defer

    延迟加载

    <script src="a.js"></script>
    <script src="b.js"></script>
    <script src="c.js"></script>
    <img src="" alt="">
    

    默认js的加载是顺序执行的,先加载js才会加载图片

    <script src="a.js" defer="defer"></script>
    <script src="b.js"></script>
    <script src="c.js"></script>
    <img src="" alt="">
    

    如果script标签加上defer属性表示延迟加载(在onload之间加载),也就是说a.js会在图片加载之后加载

    没加defer的js依然顺序加载

    <script src="a.js" defer="defer"></script>
    <script src="b.js" defer="defer"></script>
    <script src="c.js" defer="defer"></script>
    <img src="" alt="">
    

    等价于

    <img src="" alt="">
    <script src="a.js"></script>
    <script src="b.js"></script>
    <script src="c.js"></script>
    

    async

    异步加载

    <script src="a.js" async="async"></script>
    <script src="b.js" async="async"></script>
    <script src="c.js" async="async"></script>
    <img src="" alt="">
    

    表示几个js文件和图片会同时加载

    问题: 不能确定那个js文件先加载完成(适合独立js的加载)

    历史管理 history

    触发历史管理:

    1. 跳转页面
    2. 改变hash
    3. pushState

    onhashchange事件

    当hash值发生改变时出发

    例子: 彩票选择

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <button>随机选择</button>
    <div></div> 
    <script>
    var oDiv = document.querySelector('div');
    var btn = document.querySelector('button');
    
    var json = {};
    
    btn.onclick = function(){
        var hash = Math.random();
        var arr = randomArr(35, 7);
        json[ hash ] = arr;
        oDiv.innerHTML = arr.join(',');
        window.location.hash = hash;
    }
    window.onhashchange = function(){
        var hash = window.location.hash.slice(1);
        oDiv.innerHTML = json[hash];
    }
    function randomArr(maxNum , length){
        var arr = [];
        for(var i=0;i<length;i++){
            arr.push( parseInt(Math.random()*maxNum) )
        }
        return arr;
    }
    </script>
    </body>
    </html>
    

    history.pushState 和 onpopstate事件

    history.pushState

    有三个参数:state对象,标题(现在是被忽略,未作处理),URL(可选)

    当history实体被改变时(后退或前进),popstate事件将会发生

    如果history实体是有pushState方法产生的,popstate事件的state属性会包含一份来自history实体的state对象的拷贝

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <button>随机选择</button>
    <div></div> 
    <script>
    var oDiv = document.querySelector('div');
    var btn = document.querySelector('button');
    
    var json = {};
    
    btn.onclick = function(){
        var arr = randomArr(35, 7);
        history.pushState(arr, '');
        oDiv.innerHTML = arr.join(',');
    }
    window.onpopstate = function(ev){
        oDiv.innerHTML = ev.state.join(',');
    }
    function randomArr(maxNum , length){
        var arr = [];
        for(var i=0;i<length;i++){
            arr.push( parseInt(Math.random()*maxNum) )
        }
        return arr;
    }
    </script>
    </body>
    

    拖放

    在html标签上设置draggable="true", 元素久可以拖拽了

    <div draggable="true"></div>
    

    但是拖拽有点奇怪, 元素本身不会移动, 感觉是影子在移动, 跟拖拽图片的效果很像

    拖拽元素事件
    • dragstart 拖拽前触发
    • drag 拖拽前、拖拽结束之间,连续触发
    • dragend 拖拽结束触发
    <style>
    .drag{
        width: 100px;
        height: 100px;
        background: red;
    }
    </style>
    <div class="drag" draggable="true"></div>
    <script>
        var oDrag = document.querySelector('.drag');
        oDrag.ondragstart = function(){
            this.style.background = 'green';
        }
    
        oDrag.ondragend = function(){
            this.style.background = 'red';
        }
        var i=0;
        oDrag.ondrag = function(){
            document.title = i++;
        }
    </script>
    
    目标元素事件
    • dragenter , 进入目标元素触发
    • dragover ,进入目标、离开目标之间,连续触发
    • dragleave , 离开目标元素触发
    • drop , 在目标元素上释放鼠标触发(需要在dragover事件中阻止默认行为才能生效)
    <style>
    div{
        width: 100px;
        height: 100px;
    }
    .drag{
        background: red;
    }
    .target{
        background: green;
    }
    </style>
    <div class="drag" draggable="true"></div>
    <div class="target"></div>
    <script>
    var oTarget = document.querySelector('.target');
    oTarget.ondragenter = function(){
        this.style.background = '#111';
    }
    var i=0;
    oTarget.ondragover = function(ev){
        ev.preventDefault();
        document.title = i++;
    }
    oTarget.ondragleave = function(){
        this.style.background = 'green';
    }
    oTarget.ondrop = function(){
        alert(1)
    }
    </script>
    
    事件的执行顺序

    drop不触发的时候:

    dragstart > drag > dragenter > dragover > dragleave > dragend

    drop触发的时候(dragover的时候阻止默认事件):

    dragstart > drag > dragenter > dragover > drop > dragend

    火狐下拖拽的问题

    只设置draggable属性,在火狐下还是不能拖拽

    还必须设置在dragstart事件中,设置dataTransfer对象上的setData方法才能拖拽除图片以外的其他元素

    <div class="drag" draggable="true"></div>
    <script>
    var oDrag = document.querySelector('.drag');
    oDrag.ondragstart = function(ev){
        ev.dataTransfer.setData('key', 'value');
    }
    </script>
    
    dataTransfer

    在拖拽事件中,是事件对象上的一个属性

    有两个方法:

    • setData(key, value) key,value必须都是字符串
    • getData(key)
    var oDrag = document.querySelector('.drag');
    oDrag.ondragstart = function(ev){
        ev.dataTransfer.setData('a', 'b');
        alert(ev.dataTransfer.getData('a'));//b
    }
    

    实例: 将li拖拽到div, 在ondrop是删除对应的li

    <style>
        div{
            width: 100px;
            height: 100px;
            background: red;
        }
        .drag{
            background: red;
        }
        .target{
            background: green;
        }
    
    
        li{
            display: inline-block;
            background: yellow;
        }
    </style>
    <ul>
        <li draggable="true">aa</li>
        <li draggable="true">bb</li>
        <li draggable="true">cc</li>
    </ul>
    
    <div>
        
    </div>
    <script>
    var aLi = document.querySelectorAll('li');
    var oDiv = document.querySelector('div');
    aLi.forEach(function(elem, i){
        elem.i = i;
        elem.ondragstart = function(ev){
            ev.dataTransfer.setData('index', this.i);
        }
    
    
    });
    oDiv.ondragover = function(ev){
        ev.preventDefault();
    }
    oDiv.ondrop = function(ev){
        var i = ev.dataTransfer.getData('index');
        aLi[i].remove();
    }
    </script>
    
    dataTransfer.effectAllowed

    移入目标元素时,鼠标的样式

    取值: none, copy, copyLink, copyMove,link,linkMove,move, all,uninitialized

    oDrag.ondragstart = function(ev){
        ev.dataTransfer.effectAllowed = 'link';
    }
    
    dataTransfer.setDragImage()

    三个参数: 指定的元素, 坐标x, 坐标y

    oDrag.ondragstart = function(ev){
        ev.dataTransfer.setDragImage(oDiv, 0, 0);
    }
    
    dataTransfer.files

    获取外部拖拽的文件, 返回一个filesList列表

    filesList下每个文件对象有个type属性, 返回文件的类型

    关于外部文件的拖拽, 这样我们就不需要操作拖拽元素了, 只需要操作目标元素

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    <style>
    div{
        width: 200px;
        height: 200px;
        background: red;
    }
    </style>
    </head>
    <body>
        <div>将文件拖放到此区域</div>
    <script>
    var oDiv = document.querySelector('div');
    oDiv.ondragenter = function(ev){
        this.innerHTML = '可以释放了';
        console.log(ev.dataTransfer.files[0].type);
    }
    oDiv.ondragover = function(ev){
        ev.preventDefault();
    };
    oDiv.ondragleave = function(){
        this.innerHTML = '将文件拖放到此区域';
    }
    oDiv.ondrop = function(ev){
        ev.preventDefault();//阻止浏览器的默认行为, 默认拖放文件到浏览器,会将文件在浏览器中打开
    };
    </script>
    </body>
    </html>
    
    FileReader

    使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容

    • fd.readAsDataURL(file);

    data: URL格式的字符串以表示所读取文件的内容
    参数为file对象,在拖拽中可以是ev.dataTransfer.files[0];

    • fd.onload

    读取文件成功的回调函数,

    成功获fd对象的result属性代表了获取的文件数据, 如果是图片,则返回base64格式的图片数据

    oDiv.ondrop = function(ev){
        ev.preventDefault();
        var fd = new FileReader();
        fd.readAsDataURL(ev.dataTransfer.files[0]);
        fd.onload=function(){
            console.log(this.result);
        }
    };
    
    

    或者在<input>

    <input id="fileItem" type="file">
    <script>
    var fileItem = document.getElementById('fileItem');
    fileItem.onchange = function(){
        var file = this.files[0];
        var fd = new FileReader();
        fd.readAsDataURL(file);
        fd.onload=function(){
            console.log(this.result);
        }
    }
    </script>
    

    实例: 图片预览

    <div>将文件拖放到此区域</div>
    <ul></ul>
    <script>
    var oDiv = document.querySelector('div');
    var oUl = document.querySelector('ul');
    oDiv.ondragenter = function(ev){
        this.innerHTML = '可以释放了';
    }
    oDiv.ondragover = function(ev){
        ev.preventDefault();
    };
    oDiv.ondragleave = function(){
        this.innerHTML = '将文件拖放到此区域';
    }
    oDiv.ondrop = function(ev){
        ev.preventDefault();
        var files = ev.dataTransfer.files;
        files = [].slice.call(files);
        files.forEach(function(file, i){
            if( file.type.indexOf('image')!=-1){
                var li = document.createElement('li');
                var img = document.createElement('img');
                li.appendChild(img);
    
                var fd = new FileReader();
                fd.readAsDataURL(file);
                fd.onload = function(){ 
                    img.src= this.result;
                    oUl.appendChild(li);
    
                }   
            }
            else{
                alert('请选择图片格式');
            }
            
        });
    
    
    };
    </script>
    

    实例: 拖拽购物车

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    <style>
    #cart{
        border: 1px solid  #111;
        min-height: 500px;
        min-width: 300px;
    }
    </style>
    </head>
    <body>
    
    <ul id="product-list">
    </ul>
    <ul id="cart"></ul> 
    <script>
    var products = [
        {
            img: 'http://g-search2.alicdn.com/img/bao/uploaded/i4/i2/TB1wSUANpXXXXXeXXXXXXXXXXXX_!!0-item_pic.jpg_80x80.jpg',
            title: 'i7 6850K/华硕X99/GTX1080 VR游戏',
            price: 10000
        },
        {
            img: 'http://g-search3.alicdn.com/img/bao/uploaded/i4/i2/TB1UdPeOFXXXXa_XFXXXXXXXXXX_!!0-item_pic.jpg_80x80.jpg',
            title: '松明微星宙斯盾Aegis B903-008CN i7/8G*2/GTX1070台式机',
            price: 9999
        },
        {
            img: 'http://g-search1.alicdn.com/img/bao/uploaded/i4/i1/TB1UOY_KpXXXXciXVXXXXXXXXXX_!!2-item_pic.png_80x80.jpg',
            title: '海盗船 梦幻电脑250D 6700K/1151 多屏炒股HTPC办公台式电脑主机',
            price: 8888
        }
    
    ]
    
    var cartData = {};
    
    var str = '';
    
    products.forEach(function(product, i){
        str += `
        <li draggable="true" data-index="${i}">
            ![](${product.img})
            <p>${product.title}</p>
            <p>¥${product.price}</p>
        </li>
    
        `
    });
    
    var oProduct = document.querySelector('#product-list');
    var oCart = document.querySelector('#cart');
    
    oProduct.innerHTML = str;
    
    var aProductItem = document.querySelectorAll('#product-list li');
    
    aProductItem.forEach(function(product, i){
        product.ondragstart = function(ev){
            ev.dataTransfer.setDragImage(this,0, 0);
            console.log(this.dataset.index);
            ev.dataTransfer.setData('index', this.dataset.index);
        }
    });
    
    oCart.ondragover = function(ev){
        ev.preventDefault();
    }
    
    oCart.ondrop = function(ev){
        ev.preventDefault();
        var index = ev.dataTransfer.getData('index');
        var product = products[index];
        var cartItem = null;
    
        if( !cartData[index] ){
            cartItem = {
                title: product.title,
                price: product.price,
                count: 1,
                li: document.createElement('li')
            }
            cartData[index] = cartItem;
            oCart.appendChild(cartItem.li);           
        }
        else{
            cartItem = cartData[index];
            cartItem.count++;
            
        }
    
        cartItem.li.innerHTML = `
            <span class="count">${cartItem.count}</span>
            <span class="title">${cartItem.title}</span>
            <span class="total">¥${cartItem.price*cartItem.count}</span>
        `;
    
    }
    </script>
    </body>
    </html>
    

    canvas

    基本使用

    <!--不要使用css给canvas设置宽高-->
    <canvas id="canvas" width="500" height="300">
            你的浏览器不支持canvas
    </canvas>
    

    绘图环境

    var canvas = document.querySelector('#canvas');
    var context = canvas.getContext('2d');
    

    目前只支持2d,不支持3d,如果要使用3d, 可以使用webgl(不过兼容性也不是很好)

    绘制方块

    context.fillRect

    context.fillRect(left,top, width, height)

    context.fillRect(50,50, 100, 200);
    

    默认颜色是黑色

    context.strokRect

    strokeRect(left, top, width, height)

    context.strokeRect(50,50, 100, 200);
    

    默认是1像素黑色边框

    但是显示出在ps中测量为2像素的边框,把画布看成一个坐标轴,正方形的顶点坐标为(50px, 50px)

    正方形的边框为1像素宽,我们以左边框为例, 它是以50px为中心点,向右延伸0.5像素(49.5px),
    向左延伸0.5像素(50.5px); 所以做边框为(49.5px~50.5px)

    但是,用canvas绘图跟我们的ps一样, 最小的但是就是1px,没有0.5px, 所以就将出现了2px的边框

    我们可以这样写

    context.strokeRect(50.5,50.5, 100, 200);
    

    这样边框的中心点在1px的一半,刚刚就可以是1px

    设置绘图

    fillStyle 填充颜色

    strokeStyle 边框颜色

    lineWidth 线宽

    context.fillStyle = 'red';
    context.strokeStyle = 'blue';
    context.lineWidth = 10;
    
    
    //注意: 顺序不同,效果不同
    context.fillRect(50,50,100,50);
    context.strokeRect(50,50,100,50);
    

    边界绘制

    lineJoin 边界连接点样式

    miter(默认)(斜接) round(圆角) bevel(斜角)

    lineCap 端点样式

    butt(默认) round(圆角) square()

    绘制路径

    beginPath

    closePath

    moveTo

    lineTo

    stroke

    fill

    rect

    clearRect

    save

    restore

    实例: 鼠标画线

    var canvas = document.querySelector('#canvas');
    var context = canvas.getContext('2d');
    canvas.onmousedown = function(ev){
        context.moveTo(ev.clientX - canvas.offsetLeft, ev.clientY-canvas.offsetTop)
        canvas.onmousemove = function(ev){
            context.lineTo(ev.clientX - canvas.offsetLeft, ev.clientY-canvas.offsetTop);
            context.stroke();
        }
        canvas.onmouseup = function(){
            this.onmousemove = null;
            this.onmouseup = null;
        }
    }
    

    实例: 方块移动

    var canvas = document.querySelector('#canvas');
    var context = canvas.getContext('2d');
    var iNow = 0;
    setInterval(function(){
        iNow++;
        context.clearRect(0, 0, 500, 300);
        context.fillRect(iNow, iNow, 100, 100);
    
    }, 50);
    

    绘制圆

    arx(x, y, 半径, 起始弧度, 终止弧度, 旋转方向)

    • 弧度与角度的关系: 弧度=角度*Math.PI/180
    • 旋转方向: 顺时针false(默认), 逆时针true

    实例: 时钟

    var canvas = document.querySelector('#canvas');
    var context = canvas.getContext('2d');
    
    var r = 100;
    var x = 150;
    var y = 150;
    function drawClock(){
        context.clearRect(0, 0, 500, 300);
        var now = new Date();
        var hour = now.getHours();
        var min = now.getMinutes();
        var sec = now.getSeconds();
    
        console.log(hour, min, sec);
    
        var hourAngle = hour*30 + min*(30/60) - 90;
        var minAngle = min*6+sec*(6/60) - 90;
        var secAngle = sec*6 -90;
    
        //分钟刻度
        for(var i=0;i<60;i++){
            context.beginPath();
            context.moveTo(x,y);
            context.arc(x,y,r, 6*i*Math.PI/180, 6*(i+1)*Math.PI/180);
            context.stroke();
            context.closePath();
        }
    
        context.beginPath();
        context.fillStyle ='white';
        context.arc(x,y,r*(19/20), 0, 360*Math.PI/180);
        context.fill();
        context.closePath();
    
        // 时钟刻度
        for(var i=0;i<12;i++){
            context.beginPath();
            context.lineWidth = 3;
            context.moveTo(x,y);
            context.arc(x,y,r, 30*i*Math.PI/180, 30*(i+1)*Math.PI/180);
            context.stroke();
            context.closePath();
        }
    
        context.beginPath();
        context.fillStyle ='white';
        context.arc(x,y,r*(17/20), 0, 360*Math.PI/180);
        context.fill();
        context.closePath();
    
    
        // 时钟指针
        context.beginPath();
        context.moveTo(x,y);
        context.arc(x,y,r*(12/20), hourAngle*Math.PI/180, hourAngle*Math.PI/180);
        context.stroke();
        context.closePath();
    
        // 分钟刻度
        context.beginPath();
        context.moveTo(x,y);
        context.arc(x,y,r*(14/20), minAngle*Math.PI/180, minAngle*Math.PI/180);
        context.lineWidth = 2;
        context.stroke();
        context.closePath(); 
    
        // 秒钟刻度
        context.beginPath();
        context.moveTo(x,y);
        context.arc(x,y,r*(17/20), secAngle*Math.PI/180, secAngle*Math.PI/180);
        context.lineWidth = 1;
        context.stroke();
        context.closePath();    
    }
    
    drawClock();
    
    
    setInterval(function(){
        drawClock();
    }, 1000);
    

    相关文章

      网友评论

        本文标题:html5

        本文链接:https://www.haomeiwen.com/subject/oqipvttx.html