HTML5——新增的API


本文的API有:可點擊到達

  requestAnimationFrame

    客戶端存儲

    歷史記錄

    worker

    file Reader

    websocoket

一、requestAnimationFrame (請求動畫關鍵幀)

1.1  requestAnimationFrame怎么使用?

鋪墊:

  先看一下,我們平時在JS中是怎么讓一個元素產生動畫效果的。

我們平時都是用定時器來設置多長時間后發生什么動畫,或者位移

    <style>
    .demo{
        width: 100px;
        height:100px;
        background-color: red;
        position:absolute;
        left: 0;
    }
    </style>
</head>
<body>
    <div class="demo"></div>
    <script>
    var dom = document.getElementsByClassName('demo')[0];
    items = setInterval(function(e){
        dom.style.left = dom.offsetLeft + 50 +'px';
        if(dom.offsetLeft == 500){
            clearInterval(items);
        }
    },10);
    </script>

我們可以看到,用JS定時器就可以實現動畫效果

但是,JS定時器會有一個缺點

瀏覽器的重繪是每1s  ——》 60次,所以大約為16ms重繪一次 

 如果我們像上面執行的一樣,每隔10ms就增加 left50px 。頁面就會造成關鍵幀丟失

requestAnimationFrame:(優化后)

    <style>
        .demo {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            left: 0;
        }
    </style>
</head>

<body>
    <div class="demo"></div>
    <script>
        var dom = document.getElementsByClassName('demo')[0];
        function move() {
            dom.style.left = dom.offsetLeft + 50 + 'px';
            var items = requestAnimationFrame(move);
            if(dom.offsetLeft == 500){
                cancelAnimationFrame(items);
            }
        }
        move();
    </script>

1.2  requestAnimationFrame與setTImeout的區別?

setTimeout 是以 n 毫秒后執行回調函數,回調函數中可以遞歸 調用 setTimeout 來實現動畫。

        .demo {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            left: 0;
        }
    </style>
</head>

<body>
    <div class="demo"></div>
    <script>
        var dom = document.getElementsByClassName('demo')[0];
        function move() {
            var items = setTimeout(function () {
                dom.style.left = dom.offsetLeft + 50 + 'px';
                if (dom.offsetLeft == 500) {
                    clearTimeout(items);
                } else {
                    move();
                }
            }, 10)
        }
        move();
    </script>

使用 requestAnimationFrame 執行動畫,最大優勢是能保證回調函數在屏幕每一次刷 新間隔中只被執行一次,這樣就不會引起丟幀,動畫也就不會卡頓。

        .demo {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            left: 0;
        }
    </style>
</head>

<body>
    <div class="demo"></div>
    <script>
        var dom = document.getElementsByClassName('demo')[0];
        function move() {
            var items = requestAnimationFrame(function () {
                dom.style.left = dom.offsetLeft + 50 + 'px';
                if (dom.offsetLeft == 500) {
                    cancelAnimationFrame(items);
                } else {
                    move();
                }
            })
        }
        move();
    </script>

1.3  requestAnimationFrame的優勢

 

 

二、客戶端存儲

2.1  Storage: 不會傳到服務器

2.1.1 Storage 如何使用  掌握方法

    

存儲對象:

   

   

取出對象:

  

儲存數組:

   

 

   

 

取出數組:

    

API    localstorage sessionStorage  共同適用  

   

設置,獲得

   

移除屬性(指定個別屬性)

   

清除所有已設置的屬性

   

2.1.2  localstorage sessionStorage cookie區別

 localstorage:

  存儲信息到用戶的設備上,一般為5MB

  永久存儲,除非手動清除

  會存儲到同域下

sessionStorage:  

  存儲信息到用戶的設備上,一般為5MB

  臨時存儲,頁面關閉就會清除

  不會存儲到同域下

cookie:

  存儲信息到用戶的設備上,數據量較小  4k

  navigator.cookieEnabled  檢查是否啟用了cookie

     

三、歷史記錄

 BOM中的 History對象方法

現在已知我有三個標簽頁(從紅色小方塊開始)

3.1history.length   長度

通過調用這個方法就可以知道,當前歷史記錄里面有幾條數據(幾個網頁)

3.1history.back()   回退

 當前位置在第三頁(淘寶頁面),回退一頁就會跳轉到第二頁(百度頁面)

3.2 history.forward()   前進

 當前在紅色小方塊當前頁,前進一頁就會跳轉至第二頁(百度頁面)

3.3 history.go(n)     跳轉至指定頁

當前在紅色小方塊頁面即為第0頁,go(2)就會跳轉至第三頁(淘寶頁面)

 

當前在淘寶頁面即為第三頁,go(-2)就會跳轉至第一頁(紅色方塊頁面)

HTML5中新增的方法   此方法受同源策略限制,需要在服務器下操作

 

1、pushState   添加一條歷史記錄

 

 2、replaceState   替換當前的歷史記錄

 

 

1.  popstate 監聽頁面歷史記錄一旦發生改變時觸發

        history.pushState(null, null, '#a');
        window.addEventListener('popstate', function(e){  //監聽 popstate事件 有沒有發生改變 
            console.log("歷史記錄發生改變,我觸發了");
        }, false)

 應用場景

多應用於搜索,后台管理系統,或者父子頁面之間的切換(開發一個頁面就夠了)

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>

    </style>
</head>

<body>
    <input type="text" id="inp">
    <button id="btn">搜索</button>
    <ul id="wrapper"></ul>
    <script>
        var wrapper = document.getElementById('wrapper');
        var inp = document.getElementById('inp');
        var btn = document.getElementById('btn');
        var data = [{
            name: '科比'
        }, {
            name: '杜蘭特'
        }, {
            name: '庫里'
        }, {
            name: '哈登'
        }, {
            name: '詹姆斯'
        }, {
            name: '字母哥'
        }, {
            name: '杜蘭特'
        }, {
            name: '科比'
        }, {
            name: '科比'
        }];
        function radeDom(data) {  
            var str = " ";
            for (var i = 0; i < data.length; i++) {
                str += "<li>" + data[i].name + "</li>";
            }
            wrapper.innerHTML = str;
        }
        radeDom(data);

        btn.onclick = function () {
            var key = inp.value;
            var dataList = data.filter(function (item, index) {
                return item.name.indexOf(key) > -1;
            })
            radeDom(dataList);
            history.pushState({   //點擊后添加歷史記錄,key為當前的key
                key: key
            }, null, '#a');
        }
        
        window.addEventListener('popstate', function (e) {  //當歷史記錄事件改變時
            var key = e.state ? e.state.key : '';           //判斷當前頁的key是否等於當前頁的key
            var dataList = data.filter(function (item, index) {
                return item.name.indexOf(key) > -1;
            });
            inp.value = key;  //讓輸入框的value等於當前頁的key
            radeDom(dataList);
        }, false)
    </script>
</body>
</html>

 2.  hashchange 

用於監聽hash值的改變觸發事件,就是鏈接 # 這個東西的改變而觸發

跟popstate的用法大同小異,都差不多。用途也都是一樣的。所以大家可以自己試試

四、worker  (受同源策略限制,需要在服務器下運行)

4.1 了解worker 

worker字面意思是工人、雇佣員工的意思。

 worker是一種異步執行JS的方式。

4.2 worker應用

   var worker = new worker('worker.js');    
   // worker文件必須和主文件滿足同源策略    

 就是在執行代碼前雇佣一名工人(一個JS文件),把數據交給他讓他異步執行,執行完了給主人返回回來。

主人可以在執行完代碼后,調用解雇工人的方法,就不能繼續傳數據,

工人可以在執行完代碼后,調用辭職方法,就不能繼續傳數據。

 

傳輸數據

postMessage 、onmessage

返回數據

 

4.3 結束worlker

 

4.4woker的缺點

(1)同源限制

分配給 Worker 線程運行的腳本文件,必須與主線程的腳本文件同源。

(2)DOM 限制

Worker 線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網頁的 DOM 對象,也無法使用documentwindowparent這些對象。但是,Worker 線程可以navigator對象和location對象。

(3)通信聯系

Worker 線程和主線程不在同一個上下文環境,它們不能直接通信,必須通過消息完成。

(4)腳本限制

Worker 線程不能執行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 對象發出 AJAX 請求。

(5)文件限制

Worker 線程無法讀取本地文件,即不能打開本機的文件系統(file://),它所加載的腳本,必須來自網絡。

 4.5 其他特性

4.6主要應用場景

 Ajax輪詢可以使用,每隔一段時間獲取一下數據(用一個定時期每隔一段時間,向后端發送一次請求)

五、fileReader(上傳文件,讀取中的詳細信息)

 5.1 fileReader的使用方法 

var reader = new FileReader();

 

  按照不同項目的需求使用不同的方法,在這里我們就用這里面的readAsDataURL( )這個方法

  我們先來看怎么讀取文件,我們需要先把文件發送至服務器,等他給我返回文件的URL地址,然后我拿着URL地址來渲染我的頁面

  

既然我們可以接收到返回的地址,那我們就可以把圖片渲染到頁面了

    <style>
    .img{
        height: 300px;
    }
    </style>
</head>
<body>
    <input type="file">
    <img src="" alt="" class="img">
    <script>
    var reader = new FileReader();   //創建FileReader(讀文件對象)
    var inp = document.getElementsByTagName('input')[0];
    var img = document.getElementsByClassName('img')[0];
    inp.onchange = function(){       //onchange是當用戶改變input輸入框內容時執行一段JS代碼時觸發
        console.log(inp.files);      //flies 是你上傳什么文件,他就會給你返回一個文件信息的偽數組
        reader.readAsDataURL(inp.files[0]);//讀取文件,偽數組中的第0項
    }
    reader.onloadstart = function(e){
        console.log('讀取開始時觸發', e);
    }
    reader.onprogress = function(e){
        console.log('讀取中', e);
    }
    reader.onloadend = function(e){
        console.log('讀取完成', e);
    }
    reader.onload = function(e){
        console.log('文件讀取成功', e);
    }
    reader.onabort = function(e){
        console.log('中斷時觸發', e);
    }
    reader.onerror = function(e){
        console.log('出錯時觸發', e);
    }
    </script>

    <style>
    .img{
        height: 300px;
    }

    </style>
</head>
<body>
    <input type="file">
    <img src="" alt="" class="img">
    <script>
    var reader = new FileReader();   //創建FileReader(讀文件對象)
    var inp = document.getElementsByTagName('input')[0];
    var img = document.getElementsByClassName('img')[0];
    inp.onchange = function(){       //onchange是當用戶改變input輸入框內容時執行一段JS代碼時觸發
        console.log(inp.files);      //flies 是你上傳什么文件,他就會給你返回一個文件信息的偽數組
        reader.readAsDataURL(inp.files[0]);//讀取文件,偽數組中的第0項
    }
    reader.onloadstart = function(e){
        console.log('讀取開始時觸發', e);
    }
    reader.onprogress = function(e){
        console.log('讀取中', e);
    }
    reader.onloadend = function(e){
        console.log('讀取完成', e);
    }
    reader.onload = function(e){
        console.log('文件讀取成功', e);
        img.src = e.target.result;
    }
    reader.onabort = function(e){
        console.log('中斷時觸發', e);
    }
    reader.onerror = function(e){
        console.log('出錯時觸發', e);
    }
    </script>

  在文件讀取中我們可以知道兩個值  loaded、total

已知這兩個值,我們就可以實現加載進度條了

    <style>
    .img{
        height: 300px;
    }
    .wrapper{
        width: 300px;
        height: 30px;
        border: 1px solid black;
    }
    .wrapper .content{
        width: 0;
        height: 30px;
        background-color:blue;
        overflow: hidden;
    }

    </style>
</head>
<body>
    <input type="file">
    <img src="" alt="" class="img">
    <div class="wrapper">
        <div class="content"></div>
    </div>
    <span class="text"></span>
    <script>
    var reader = new FileReader();   //創建FileReader(讀文件對象)
    var inp = document.getElementsByTagName('input')[0];
    var img = document.getElementsByClassName('img')[0];
    var con = document.getElementsByClassName('content')[0];
    var text = document.querySelector('.text');
    inp.onchange = function(){       //onchange是當用戶改變input輸入框內容時執行一段JS代碼時觸發
        console.log(inp.files);      //flies 是你上傳什么文件,他就會給你返回一個文件信息的偽數組
        reader.readAsDataURL(inp.files[0]);//讀取文件,偽數組中的第0項
    }
    reader.onloadstart = function(e){
        console.log('讀取開始時觸發', e);
    }
    reader.onprogress = function(e){
        // console.log('讀取中', e。loaded / e.total * 100%);
        var precent = e.loaded / e.total * 100;  //當前讀取的值除以文件總大小,乘以100%。在讀取中會不斷觸發
        var width = Math.round(300 * precent / 100); //進度條長度300乘以前面得到的值,除以100%,四舍五入取整
        con.style.width = width + 'px'; //把值賦給寬度
        text.innerHTML = Math.round(precent) + '%'; //把讀取中的值取整把數字賦給文字進度條
    }
    reader.onloadend = function(e){
        console.log('讀取完成', e);
    }
    reader.onload = function(e){
        console.log('文件讀取成功', e);
        img.src = e.target.result;
    }
    reader.onabort = function(e){
        console.log('中斷時觸發', e);
    }
    reader.onerror = function(e){
        console.log('出錯時觸發', e);
    }
    </script>

   

 然后我們還可以添加終止讀取,就是在文件上傳的中途,停止上傳

只需要添加一個按鈕,和一個點擊事件

        btn.onclick = function () {
            reader.abort();
            console.log('終止');
        }

 

 

5.2 fileReader 可實現的功能

 圖片預覽、異步向發送服務端發送請求

六、websocket(不受同源策略限制)

 websocket是一種網絡協議,是在HTTP基礎上做了一些優化的協議,與HTTP無直接關系。

6.1  簡單回憶HTTP協議

 

 6.2為什么有HTTP還需要websocket呢?

因為HTTP協議有一個缺陷:通信只能由客戶端發起

服務器端不能實時的發送最新數據給客戶端,

我想要最新的數據怎么辦呢? 只能用Ajax輪詢(開啟一個定時器,每隔一段時間調用請求一次數據)

然而websocket呢只需要發送一次請求,只要服務器有最新數據就會自動給你發送過來,不用再次請求

比如現在做的是一個天氣狀況的項目,每當天氣有變化就會自動更新最新天氣狀況了

 6.3 websocket的特點

 

6.4 websocket事件 

6.5 創建websocket

ws://echo.websocket.org/    是用來測試的地址
    var socket = new WebSocket('ws://echo.websocket.org/');

 

調用e.data就可以打印出來數據了

我們再來看看close這個方法

 6.6 websocket屬性

 

6.7 websocket的優點

 客戶端與服務器都可以主動傳送數據給對方;

不用頻率創建TCP請求及銷毀請求,減少網絡帶寬資源的占用,同時也節省服務器資源;

 可以只請求一次,就會自動更新返回


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM