h5新特性總覽
<a name="t1"></a><a target="_blank" name="t1" style="color:rgb(12,137,207)"></a>移除的元素
純表現的元素:
basefont、big、center捻撑、font等
對可用性產生負面影響的元素:
frame艾君、frameset仆潮、noframes
<a name="t2"></a><a target="_blank" name="t2" style="color:rgb(12,137,207)"></a>新增的API
語義:
能夠讓你更恰當地描述你的內容是什么限嫌。
連通性:
能夠讓你和服務器之間通過創(chuàng)新的新技術方法進行通信(web sockets等)。
離線 & 存儲:
能夠讓網頁在客戶端本地存儲數據以及更高效地離線運行(離線資源册养、在線和離線事件傲绣、DOM存儲掠哥、IndexDB、自web應用程序中使用文件[FileReader])秃诵。
多媒體:
使 video 和 audio 成為了在所有 Web 中的一等公民续搀。
2D/3D 繪圖 & 效果:
提供了一個更加分化范圍的呈現選擇(canvas、webGL)菠净。
性能 & 集成:
提供了非常顯著的性能優(yōu)化和更有效的計算機硬件使用(WebWorkers禁舷、XMLHttpRequest2彪杉、HistoryAPI、拖放牵咙、requestAnimationFrame派近、全屏API、指針鎖定API洁桌、在線和離線事件)渴丸。
設備訪問 Device Access:
能夠處理各種輸入和輸出設備(觸控事件touch、使用地理位置定位另凌、檢測設備方向)谱轨。
<a name="t3"></a><a target="_blank" name="t3" style="color:rgb(12,137,207)"></a>部分API詳述
由于篇幅較長,可以選擇感興趣的部分閱讀
存儲機制
File API
Web Worker
history對象
2D繪圖(canvas和svg)
H5的兼容性
<a name="t4"></a><a target="_blank" name="t4" style="color:rgb(12,137,207)"></a>web存儲機制
Web Storage的目的是克服由cookie帶來的一些限制吠谢,當數據需要被嚴格控制在客戶端上時土童,無需持續(xù)地將數據發(fā)回服務器。Web Storage的兩個主要目標是:提供一種在cookie之外存儲會話數據的途徑工坊;提供一種存儲大量可以跨會話存在的數據機制献汗。最初的Web Storage規(guī)范包含了兩種對象的定義:sessionStorage和globalStorage。這兩個對象在支持的瀏覽器中都是以windows對象屬性的形式存在的栅组。
<a target="_blank" name="t5" style="color:rgb(12,137,207)"></a>sessionStorage對象
sessionStorage對象存儲特定于某個會話的數據雀瓢,也就是該數據只保持到瀏覽器關閉枢析。這個對象就像會話cookie玉掸,也會在瀏覽器關閉后消失。存儲在sessionStorage中的數據可以跨越頁面刷新而存在醒叁,同時如果瀏覽器支持司浪,瀏覽器崩潰并重啟之后依然可用(FireFox和WebKit都支持,IE不支持)
因為sessionStorage對象綁定于某個服務器會話把沼,所以當文件在本地運行的時候是不可用的啊易,存儲在sessionStorage中的數據只能由最初給對象存儲數據的野蠻訪問到,所以對多頁面應用有限制饮睬。
sessionStorage對象可以使用setItem()或者直接設置新的屬性來存儲數據
//使用sessionStorage方法存儲數據
sessionStorage.setitem('name','Nicholas');
//使用屬性存儲數據
sessionStorage.book = 'Profession JavaScript';
不同瀏覽器寫入數據方面略有不同租谈。FireFox和WebKit實現了同步寫入,所以添加到存儲空間中的數據時立刻被提交的捆愁。而IE的實現則是異步寫入數據割去,所以在設置數據和將數據實際寫入磁盤之間可能有一些延遲。對于少量數據而言昼丑,這個差異是可以忽略的呻逆。對于大量數據,IE要比其他瀏覽器更快的恢復執(zhí)行菩帝,因為它會跳過實際的磁盤寫入過程
在IE8中可以強制把數據寫入磁盤:在設置新數據之前使用begin()方法咖城,并且在所有設置完成后調用commit()方法
sessionStorage.begin();//確保在這段代碼執(zhí)行的時候不會發(fā)生其他磁盤寫入操作
sessionStorage.setitem('name','Nicholas');
sessionStorage.book = 'Profession JavaScript';
sessionStorage.commit();
sessionStorage中有數據時茬腿,可以使用getItem()或者通過直接訪問屬性名來獲取數據。
//使用方法讀取數據
var name = sessionStorage.getItem('name');
//使用屬性讀取數據
var book = sessionStorage.book;
還可以通過結合length屬性和key()方法來迭代sessionStorage的值宜雀。
for(var i = 0,len = sessionStorage.length; i < len; i++){
var key = sessionStorage.key(i);
var value = sessionStorage.getItem(key);
alert(key + "=" + value);
}
要從sessionStorage中刪除數據可以使用delete操作符刪除對象屬性切平,也可以調用removeItem()方法。
delete sessionStorage.name;
sessionStorge.removeItem('book');
<a target="_blank" name="t6" style="color:rgb(12,137,207)"></a>globalStorage對象
sessionStorage對象應該主要用于針對會話的小段數據的存儲辐董。如果需要跨越花花存儲數據揭绑,那么globalStorage或者localStorage更為合適
要使用globalStorage,首先要制定哪些域可以訪問該數據郎哭∷耍可以通過方括號標記使用屬性來實現。
//保存數據
globalStorage['wrox.com'].name = 'Nicholas';
//獲取數據
var name = globalStorage['wrox.com].name;
在這里夸研,訪問的是針對域名wrox.com的存儲空間邦蜜。這個存儲空間對于wrox.com及其所有子域都是可以訪問的。
對globalStorage空間的訪問亥至,是依據發(fā)起請求的頁面的域名悼沈、協(xié)議和端口來限制的(類似于ajax請求的同源策略)。如果實現不能確定域名姐扮,那么使用location.host作為屬性名比較安全
globalStorage[location.host].name = 'Nicholas';
var book = globalStorage[location.host].getItem('book');
如果不使用removeItem()或者delete刪除絮供,或者用戶為清除瀏覽器緩存,存儲在globalStorage屬性中的數據會一直保留在磁盤上茶敏。這讓globalStorage非常適合在客戶端存儲文檔或者長期保存用戶偏好設置
<a target="_blank" name="t7" style="color:rgb(12,137,207)"></a>localStorage對象
localStorage對象在修訂過的HTML5規(guī)范中作為持久保存客戶端數據的方案取代了globalStorage壤靶。與globalStorage不同,不能給localStorage指定任何訪問規(guī)則惊搏;規(guī)則實現就設定好了贮乳。要訪問同一個localStorage對象,頁面必須來自同一個域名恬惯,使用同一種協(xié)議向拆,在同一個端口上。這相當于globalStorage[location.host]
由于localStorage是Storage的實例酪耳,所以可以像使用sessionStorage一樣來使用它浓恳。
//使用方法存儲數據
localStorage.setItem('name','Nichoalas');
//使用屬性存儲數據
localStorage.book = 'Professional JavaScript';
//使用方法讀取數據
var name = localStorage.getItem('name')
//使用屬性讀取數據
var book = localStorage.book;
存儲在localStorage中的數據和存儲在globalStorage中的數據一樣,都遵循相同的規(guī)則:數據保留到通過JavaScript
刪除或者是用戶清除瀏覽器緩存
<a name="t5"></a><a target="_blank" name="t8" style="color:rgb(12,137,207)"></a>File API
File API在表單中的文件輸入字段的基礎上碗暗,又添加了一些直接訪問文件信息的接口颈将。H5在DOM中為文件輸入元素添加了一個files集合,在通過文本輸入字段選擇了一或多個文件時讹堤,files集合中將包含一組File對象吆鹤,每個File對象對應著一個文件。每個File對象都有下列只讀屬性
- name: 本地文件系統(tǒng)的文件名
- size: 文件的字節(jié)大小
- type:字符串洲守,文件的MIME類型疑务。
- lastModifiedDate:字符串沾凄,文件上一次被修改的事件(只有chrome實現了這個屬性)
現在我們獲取id為‘files-list’的input為file的元素,將該元素中上傳的文件輸出到控制臺
var filesList = document.getElementById('files-list');
EventUtil.addHandler(filesList,'change',funciton(e){
var files = EventUtil.getTarget(e).files,
i = 0,
len = files.length;
while(i<len){
console.log(files[i].name + '('+files[i].type+','+files[i].size +'bytes)');
i++;
}
})
<a target="_blank" name="t9" style="color:rgb(12,137,207)"></a>FileReader類型
FlieReader類型實現的是一種異步文件讀取機制知允∪鲶埃可以把FileReader想象成XMLHttpRequest,區(qū)別只是它讀取的是文件心痛温鸽,而不是遠程服務器保屯。為了讀取文件中的數據,FileReader提供了如下幾個方法:
- readAsText(file, encoding):以純文本的形式讀取文件涤垫,將讀取到的文本保存在result屬性中姑尺。
- readAsDataURL(file):讀取文件并將文件一數據URI的形式保存在result屬性中
- readAsBinaryString(file)(已廢棄):讀取文件并將一個字符串保存在result屬性中,字符串中的每一個字符表示一字節(jié)
- readAsArrayBuffer(file):讀取文件并將一個包含文件內容的ArrayBuffer保存在result屬性中蝠猬。
由于讀取過程是異步的切蟋,因此FileReader也提供了幾個事件。其中最有用的三個事件是progress榆芦、error和load柄粹,分別表示是否又讀取了新數據,是否發(fā)生了錯誤以及是否讀完了整個文件匆绣。
var filesList = document.getElementById("files-list");
EventUtil.addHandler(filesList, "change", function(event){
var info = "",
output = document.getElementById("output"),
progress = document.getElementById("progress"),
files = EventUtil.getTarget(event).files,
type = "default",
reader = new FileReader();
if (/image/.test(files[0].type)){
reader.readAsDataURL(files[0]);
type = "image";
} else {
reader.readAsText(files[0]);
type = "text";
}
reader.onerror = function(){
output.innerHTML = "Could not read file, error code is " + reader.error.code;
};
reader.onprogress = function(event){
if (event.lengthComputable){
progress.innerHTML = event.loaded + "/" + event.total;
}
};
reader.onload = function(){
var html = "";
switch(type){
case "image":
html = "<img src=\"" + reader.result + "\">";
break;
case "text":
html = reader.result;
break;
}
output.innerHTML = html;
};
});
<a target="_blank" name="t10" style="color:rgb(12,137,207)"></a>讀取部分內容
File對象支持一個slice()方法以實現讀取文件的一部分而不是全部內容驻右,這個方法在FireFox中的實現叫mozSlice()融柬,在chrome中的實現是webkitSlice()刽锤,Safiri的5.1及之前的版本不支持這個方法囤捻。Slice()方法接收兩個參數:起始字節(jié)及要讀取的字節(jié)數淌实。這個方法返回一個Blob實例,Blob是File類型的父類型猖辫。下面是一個通用的函數踢关,可以在不同實踐中使用slice()方法:
function blobSlice(blob,startByte,length){
if(blob.slice){
return blob.slice(startByte,length);
} else if(blob.webkitSlice){
return blob.webkitSlice(startByte,length);
} else if(blob.webkitSlice){
return blob.webkitSlice(startByte,length);
} else {
return null;
}
}
blob類型有一個size屬性和一個type屬性,而且它也支持slice()方法咐鹤,以便進一步切割數據。通過FileReader也可以從Blob中讀取數據圣絮。下面這個例子只讀取文件的32B內容
var filesList = document.getElementById('files-list');
EventUtil.addHandler(filesList, "change", function(event){
var info = "",
output = document.getElementById("output"),
progress = document.getElementById("progress"),
files = EventUtil.getTarget(event).files,
type = "default",
reader = new FileReader();
blob = blobSlice(files[0],0,32);
if (blob){
reader.readAsText(blob);
reader.onerror = function(){
outpit.innerHTML = 'could not read file,error code is' + reader.error.code;
}
reader.onload = function(){
output.innerHTML = reader.result;
};
} else {
alert('your browser does not support slice()');
}
reader.onerror = function(){
output.innerHTML = "Could not read file, error code is " + reader.error.code;
};
只讀取文件的一部分可以節(jié)省時間祈惶,非常適合只關注數據中某個特定部分(如請求頭部)的情況
<a target="_blank" name="t11" style="color:rgb(12,137,207)"></a>對象URL
對象URL也被稱為blob URL,指的是引用保存在File或Blob中數據的URL扮匠。使用對象URL的好處是可以不必把文件內容讀取到JavaScript中而直接使用文件內容捧请。為此,只要在需要文件內容的地方提供對象URL即可棒搜。要創(chuàng)建對象URL疹蛉,可以使用window.URL.createObjectURL()方法,并傳入File或Blob對象力麸。這個方法在Chrome中的實現叫window.webkitURL.createObjectURL()可款,因此可以通過如下函數來消除命名的差異:
function createObjectURL(blob){
if(window.URL){
return window.URL.createObjectURL(blob);
} else if (window.webkitURL) {
return window.webkitURL.createObjectURL(blob);
} else {
return null;
}
}
這個函數的返回值是一個字符串育韩,指向一塊內存的地址。因為這個字符串是URL闺鲸,所以在DOM中也能使用筋讨。例如,以下代碼可以在頁面中顯示一個圖像文件:
var filesList = document.getElementById("files-list");
EventUtil.addHandler(filesList, "change", function(event){
var info = "",
output = document.getElementById("output"),
progress = document.getElementById("progress"),
files = EventUtil.getTarget(event).files,
type = "default",
reader = new FileReader();
url = createObjectURL(files[0]);
if(url) {
if (/image/.test(files[0].type)){
output.innerHTML="<img src =\"" + url + "\">"
} else {
output.innerHTML = 'not an image';
}
} else {
output.innerHTML = "your browser doesn't support object URLs";
}
});
reader.onerror = function(){
output.innerHTML = "Could not read file, error code is " + reader.error.code;
};
reader.onprogress = function(event){
if (event.lengthComputable){
progress.innerHTML = event.loaded + "/" + event.total;
}
};
<a target="_blank" name="t12" style="color:rgb(12,137,207)"></a>讀取拖放的文件
圍繞讀取文件信息摸恍,結合使用Html5拖放API和文件API悉罕,能夠創(chuàng)造出令人矚目的用戶界面:在頁面上創(chuàng)建了自定義的放置目標后,可以從桌面上把文件拖放到該目標立镶。與拖放一張圖片或者一個鏈接類似壁袄,從桌面上把文件拖放到瀏覽器中也會觸發(fā)drop事件。而且可以在e.dataTransfer.files中讀到被放置的文件媚媒,當然此時它是一個File對象然想,與童年過文件輸入字段取得的File對象一樣。
var droptarget = document.getElementById('droptarget');
function handleEvent(e){
var info = '';
var output = document.getElementById('output');
var files, i, len;
e.preventDefault();
if(e.type == 'drop') {
files = e.dataTransfer.files;
i = 0;
len = files.length;
while(i < len){
info += files[i].name + '(' + files[i].type + ',' + files[i].size + 'bytes<br>';
i++;
}
output.innerHTML = info;
}
}
droptarget.addHandler('dragenter',handleEvent,false);
droptarget.addHandler('drageover',handleEvent,false);
droptarget.addHandler('drop',handleEvent,false);
<a name="t6"></a><a target="_blank" name="t13" style="color:rgb(12,137,207)"></a>Web Workers
專用Web Worker提供可一個簡單的方法使的web內容能夠在后臺運行腳本欣范。一旦worker創(chuàng)建后变泄,它可以向由它的創(chuàng)建者指定的事件監(jiān)聽函數傳遞消息,這樣改worker生成的所有任務就都會接收到這個消息恼琼。worker線程能夠在不干擾UI的情況下執(zhí)行任務妨蛹。
<a target="_blank" name="t14" style="color:rgb(12,137,207)"></a>生成worker
創(chuàng)建一個新的worker十分簡單。就是調用Worker()構造函數晴竞,指定一個要在worker線程內運行的腳本的URI蛙卤,如果希望能夠收到worker的通知,可以將worker的onmessage屬性設置成一個特定的事件處理函數噩死,如果希望能夠發(fā)送信息到worker颤难,可以使用postmessage方法
var myWorker = new Worker("my_task.js");
myWorker.onmessage = function (oEvent) {
console.log("Called back by the worker!\n");
};
myWorker.postMessage(""); // start the worker.
<a target="_blank" name="t15" style="color:rgb(12,137,207)"></a>傳遞數據
在主頁面與worker之間傳遞的數據是通過拷貝,而不是共享來完成的已维。傳遞給worker的對象需要經過序列化行嗤,接下來在另一端還需要反序列化。頁面與worker不會共享同一個實例垛耳,最終的結果就是在每次通信結束時生成了數據的一個副本栅屏。大部分瀏覽器使用結構化拷貝來實現該特性。
example.html(主頁面)
var myWorker = new Worker("my_task.js");
myWorker.onmessage = function (oEvent) {
console.log("Worker said : " + oEvent.data);
};
myWorker.postMessage("ali");
my_task.js(worker)
postMessage("I\'m working before postMessage(\'ali\').");
onmessage = function (oEvent) {
postMessage("Hi " + oEvent.data);
};
<a target="_blank" name="t16" style="color:rgb(12,137,207)"></a>Worker全局作用域
關于Web Worker堂鲜,最重要的是要知道它所執(zhí)行的JavaScript代碼完全在另一個作用域栈雳,與當前網頁中的代碼不共享作用域。在Web Worker中缔莲,同樣有一個全局對象和其他對象以及方法哥纫。但是Web Worker中的代碼不能訪問DOM,也無法通過任何方式影響頁面的外觀
Web Worker中的全局對象是worker對象本身痴奏。也就是說蛀骇,在這個特殊的全局作用域中奖慌,this和sele引用的都是worker對象。為便于處理數據松靡,Web Worker本身也是一個最小化的運行環(huán)境
- 最小化的navgator對象 : online简僧、appName、appVersion雕欺、userAgent岛马、platform
- 只讀的location對象 : 所有屬性都是只讀的
- self : 指向全局 worker 對象
- 所有的ECMA對象,Object屠列、Array啦逆、Date等
- XMLHttpRequest構造器
- setTimeout、setInterval笛洛、clearTimeout()和clearInterval()方法
在worker內部夏志,調用close()方法也可以停止工作。Worker停止工作后就不會再有事件發(fā)生苛让。
另外沟蔑,Worker的全局作用域中提供了importScripts()方法。這個方法接收一個或多個指向JavaScript文件的URL狱杰。每個加載過程都是異步進行的瘦材,因此素有的腳本加載并執(zhí)行完成之后,importScripts()才會執(zhí)行
importScripts('file1.js','file2.js');
即使file2.js先于file1.js下載完仿畸,執(zhí)行的時候仍然會按照先后順序實行食棕。而且,這些腳本是在Worker的全局作用域中執(zhí)行错沽,如果腳本中包含與頁面香瓜你的JavaScript代碼簿晓,那么腳本可能無法正確運行。
<a name="t7"></a><a target="_blank" name="t17" style="color:rgb(12,137,207)"></a>history對象
history對象保存著用戶上網的歷史記錄千埃,從窗口被打開的那一刻算起憔儿。
使用Go()方法可以在用戶的歷史記錄中任意跳轉,可以向后也可以向前镰禾。這個方法接受一個參數皿曲,表示向后或向前跳轉的頁面數的一個整數值。負數表示向后跳轉(類似于單擊瀏覽器的‘后退’按鈕)吴侦,正數表示向前跳轉(類似于單擊瀏覽器的“前進”按鈕)
history.go(-1);//后退一頁
history.go(1);//前進一頁
history.go(2);//前進兩頁
也可以給go()方法傳遞一個字符串參數,此時瀏覽器會跳轉到歷史記錄中包含該字符串的第一個位置–可能后退坞古,也可能前進备韧,具體看那個位置最近。如果歷史記錄中不包含該字符串痪枫,那么這個方法什么也不做
history.go('wrox.com');//跳到最近的wrox.com頁面
另外织堂,還可以使用兩個簡寫方法back()和forward()來代替go()叠艳。這兩個方法都可以模仿瀏覽器的‘后退’和‘前進’按鈕。
history.back();//后退一頁
history.forward();//前進一頁
history對象還有一個length屬性易阳,保存著歷史記錄的數量附较。這個數量包括所有的歷史記錄,即所有向后和向前的記錄潦俺。
<a target="_blank" name="t18" style="color:rgb(12,137,207)"></a>history在h5中新增的屬性和方法
h5中的history對象新增了兩個新方法:history.pushState()和history.replaeState();
兩種方法都允許我們添加和更新歷史記錄拒课,它們的工作原理相同并且可以添加數量相同的參數。但是pushState()是在history棧中添加一個新的條目事示,replaceState()是替換當前的記錄值早像。除了方法之外,還有popstate 事件
pushState(data肖爵,title[,url])和replaceState(data卢鹦,title[,url])參數一樣,參數說明如下:
- data:一個表示狀態(tài)的對象劝堪,json格式數據
- title:一個string格式的標題(大多數瀏覽器不支持或忽略這個參數冀自,最好用null代替)
- url:一個url(用于替換當前URL)
當瀏覽會話記錄的時候,不管點擊前進或者后退按鈕秒啦,還是使用history.go和history.back方法凡纳,popstate事件都會被觸發(fā)。當事件發(fā)生時帝蒿,瀏覽器會從history中取出URL和對應的state對象替換當前的URL和history.state荐糜。通過event.state也可以獲取history.state
需要說明的是pushState只是將當前頁面保存到history的歷史記錄中(并作為最近的一個記錄),并且將當前瀏覽器的地址欄改為參數url指定的值葛超,但并不會加載它暴氏。這點與普通的通過鏈接打開或瀏覽器地址輸入url完全不一樣。所以如果想在url改變的時候需要監(jiān)聽popstate事件绣张。
利用history可以彌補ajax無法回退的缺陷答渔。如下方法是模擬ajax操作的實現方法。
<input type="button" value="加1" onclick="add()" />
<div id="info" style="border:red 1px solid;width:200px;padding:10px;">0</div>
<script>
var info = document.getElementById('info');
var i = 1;
function add() {
var data = {
param : i,
func : func
};
info.innerHTML = i;
document.title = i;
History.push(data);
i++;
}
function func(i) {
info.innerHTML = i;
document.title = i;
}
History = function() {
var
list = [],
index = 1,
func, scope;
function push(data) {
if(typeof data !== 'object') return;
if(typeof data.param == undefined || typeof data.func !== 'function') return;
func = data.func;
scope = data.scope;
history.pushState({param: data.param}, index, '#' + index);
index++;
}
window.onpopstate = function(e) {
if(e.state) {
var state = e.state,
param = state.param;
if(param) {
func.call(scope, param);
}
}
else{
if(func){
func.call(scope, 0);
}
}
}
return {
push : push
};
}();
</script>
<a name="t8"></a><a target="_blank" name="t19" style="color:rgb(12,137,207)"></a>2D繪圖(canvas和svg)
<a target="_blank" name="t20" style="color:rgb(12,137,207)"></a>SVG
SVG 是一種使用 XML 描述 2D 圖形的語言侥涵。
SVG 基于 XML沼撕,這意味著 SVG DOM 中的每個元素都是可用的。您可以為某個元素附加 JavaScript 事件處理器芜飘。
在 SVG 中务豺,每個被繪制的圖形均被視為對象。如果 SVG 對象的屬性發(fā)生變化嗦明,那么瀏覽器能夠自動重現圖形笼沥。
<a target="_blank" name="t21" style="color:rgb(12,137,207)"></a>canvas
Canvas 通過 JavaScript 來繪制 2D 圖形。
Canvas 是逐像素進行渲染的。
在 canvas 中奔浅,一旦圖形被繪制完成馆纳,它就不會繼續(xù)得到瀏覽器的關注。如果其位置發(fā)生變化汹桦,那么整個場景也需要重新繪制鲁驶,包括任何或許已被圖形覆蓋的對象。
<a target="_blank" name="t22" style="color:rgb(12,137,207)"></a>Canvas 與 SVG 的比較
下表列出了 canvas 與 SVG 之間的一些不同之處舞骆。
Canvas
依賴分辨率
不支持事件處理器
弱的文本渲染能力
能夠以 .png 或 .jpg 格式保存結果圖像
最適合圖像密集型的游戲钥弯,其中的許多對象會被頻繁重繪
SVG
不依賴分辨率
支持事件處理器
最適合帶有大型渲染區(qū)域的應用程序(比如谷歌地圖)
復雜度高會減慢渲染速度(任何過度使用 DOM 的應用都不快)
不適合游戲應用
<a name="t9"></a><a target="_blank" name="t23" style="color:rgb(12,137,207)"></a>h5的兼容性問題
IE6/IE7/IE8支持通過document.createElement方法產生的標簽,可以利用這一特性讓這些瀏覽器支持HTML5新標簽葛作。但是瀏覽器支持新標簽后寿羞,還需要添加標簽默認的樣式。