復(fù)習(xí)2HTML5

一姻僧、HTML5簡(jiǎn)介

HTML5是根據(jù)2014年由萬(wàn)維網(wǎng)聯(lián)盟(W3C)完成標(biāo)準(zhǔn)制定的沸呐,他的設(shè)計(jì)目的主要是為了在移動(dòng)設(shè)備上支持多媒體蛆楞。

HTML5新特性:

  • 繪畫(huà)canvas元素
  • 用于媒體回放video和audio元素
  • 對(duì)于本地離線(xiàn)儲(chǔ)存的更好支持
  • 新的特殊內(nèi)容元素 article为严、footer逛漫、header、nav锤灿、section
  • 新的表單控件 calendar挽拔、date、time但校、email篱昔、url、search

HTML5改進(jìn):

  • 新元素
  • 新屬性
  • 完全支持css3
  • Video 和 Audio
  • 2D/3D制圖
  • 本地儲(chǔ)存
  • 本地 SQL 數(shù)據(jù)
  • Web 應(yīng)用

HTML5多媒體

  • video
  • audio

HTML5圖形

使用 HTML5 你可以簡(jiǎn)單的繪制圖形:

HTML5 使用 CSS3

  • 新選擇器
  • 新屬性
  • 動(dòng)畫(huà)
  • 2D/3D 轉(zhuǎn)換
  • 圓角
  • 陰影效果
  • 可下載的字體

語(yǔ)義元素

HTML5 添加了很多語(yǔ)義元素如下所示:

標(biāo)簽 描述
<article> 定義頁(yè)面獨(dú)立的內(nèi)容區(qū)域穗椅。
<aside> 定義頁(yè)面的側(cè)邊欄內(nèi)容。
<bdi> 允許您設(shè)置一段文本奶栖,使其脫離其父元素的文本方向設(shè)置匹表。
<command> 定義命令按鈕,比如單選按鈕宣鄙、復(fù)選框或按鈕
<details> 用于描述文檔或文檔某個(gè)部分的細(xì)節(jié)
<dialog> 定義對(duì)話(huà)框袍镀,比如提示框
<summary> 標(biāo)簽包含 details 元素的標(biāo)題
<figure> 規(guī)定獨(dú)立的流內(nèi)容(圖像、圖表冻晤、照片苇羡、代碼等等)。
<figcaption> 定義 <figure> 元素的標(biāo)題
<footer> 定義 section 或 document 的頁(yè)腳鼻弧。
<header> 定義了文檔的頭部區(qū)域
<mark> 定義帶有記號(hào)的文本设江。
<meter> 定義度量衡。僅用于已知最大和最小值的度量攘轩。
<nav> 定義導(dǎo)航鏈接的部分叉存。
<progress> 定義任何類(lèi)型的任務(wù)的進(jìn)度。
<ruby> 定義 ruby 注釋?zhuān)ㄖ形淖⒁艋蜃址?br> <rt> 定義字符(中文注音或字符)的解釋或發(fā)音度帮。
<rp> 在 ruby 注釋中使用歼捏,定義不支持 ruby 元素的瀏覽器所顯示的內(nèi)容。
<section> 定義文檔中的節(jié)(section笨篷、區(qū)段)瞳秽。
<time> 定義日期或時(shí)間。
<wbr> 規(guī)定在文本中的何處適合添加換行符冕屯。

已移除元素

以下的 HTML 4.01 元素在HTML5中已經(jīng)被刪除:

  • <acronym>
  • <applet>
  • <basefont>
  • <big>
  • <center>
  • <dir>
  • <font>
  • <frame>
  • <frameset>
  • <noframes>
  • <strike>

二寂诱、HTML5瀏覽器支持

將 HTML5 元素定義為塊元素

HTML5 定了 8 個(gè)新的 HTML 語(yǔ)義(semantic) 元素。所有這些元素都是 塊級(jí) 元素安聘。
為了能讓舊版本的瀏覽器正確顯示這些元素痰洒,你可以設(shè)置 CSS 的 display 屬性值為 block:

實(shí)例
header, section, footer, aside, nav, main, article, figure {
    display: block; 
}

為 HTML 添加新元素

你可以為 HTML 添加新的元素瓢棒。

該實(shí)例向 HTML 添加的新的元素,并為該元素定義樣式丘喻,元素名為 <myHero> :

實(shí)例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>為 HTML 添加新元素</title>
<script>
document.createElement("myHero")
</script>
<style>
myHero {
    display: block;
    background-color: #ddd;
    padding: 50px;
    font-size: 30px;
}
</style> 
</head>
 
<body>
 
<h1>我的第一個(gè)標(biāo)題</h1>
 
<p>我的第一個(gè)段落脯宿。</p>
 
<myHero>我的第一個(gè)新元素</myHero>
 
</body>
</html>

Internet Explorer 瀏覽器問(wèn)題

你可以使用以上的方法來(lái)為 IE 瀏覽器添加 HTML5 元素,但是:

|
Note

Internet Explorer 8 及更早 IE 版本的瀏覽器不支持以上的方式泉粉。
我們可以使用 Sjoerd Visscher 創(chuàng)建的 "HTML5 Enabling JavaScript", "** shiv**" 來(lái)解決該問(wèn)題:

<!--[if lt IE 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

以上代碼是一個(gè)注釋?zhuān)饔檬窃?IE 瀏覽器的版本小于 IE9 時(shí)將讀取 html5.js 文件连霉,并解析它。
注意:國(guó)內(nèi)用戶(hù)請(qǐng)使用本站靜態(tài)資源庫(kù)(Google 資源庫(kù)在國(guó)內(nèi)不穩(wěn)定):

<!--[if lt IE 9]>
  <script src="http://cdn.static.runoob.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->

針對(duì)IE瀏覽器html5shiv 是比較好的解決方案嗡靡。html5shiv主要解決HTML5提出的新的元素不被IE6-8識(shí)別跺撼,這些新元素不能作為父節(jié)點(diǎn)包裹子元素,并且不能應(yīng)用CSS樣式讨彼。

完美的 Shiv 解決方案

實(shí)例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>渲染 HTML5</title>
  <!--[if lt IE 9]>
  <script src="http://cdn.static.runoob.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
  <![endif]-->
</head>
 
<body>
 
<h1>我的第一篇文章</h1>
 
<article>
</article>
 
</body>
</html>

三歉井、HTML5新元素

<canvas> 新元素

| 標(biāo)簽 | 描述 |

  • <canvas> | 標(biāo)簽定義圖形,比- 如圖表和其他圖像哈误。該標(biāo)簽基于 JavaScript 的繪圖 API |

新多媒體元素

| 標(biāo)簽 | 描述 |

  • <audio> | 定義音頻內(nèi)容 |
  • <video> | 定義視頻(video 或者 movie) |
  • <source> | 定義多媒體資源 <video> 和 <audio> |
  • <embed> | 定義嵌入的內(nèi)容哩至,比如插件。 |
  • <track> | 為諸如 <video> 和 <audio> 元素之類(lèi)的媒介規(guī)定外部文本軌道蜜自。 |

新表單元素

| 標(biāo)簽 | 描述 |

  • <datalist> | 定義選項(xiàng)列表菩貌。請(qǐng)與 input 元素配合使用該元素,來(lái)定義 input 可能的值重荠。 |
  • <keygen> | 規(guī)定用于表單的密鑰對(duì)生成器字段箭阶。 |
  • <output> | 定義不同類(lèi)型的輸出,比如腳本的輸出晚缩。 |

新的語(yǔ)義和結(jié)構(gòu)元素

HTML5提供了新的元素來(lái)創(chuàng)建更好的頁(yè)面結(jié)構(gòu):

| 標(biāo)簽 | 描述 |

  • <article> | 定義頁(yè)面獨(dú)立的內(nèi)容區(qū)域尾膊。 |
  • <aside> | 定義頁(yè)面的側(cè)邊欄內(nèi)容媳危。 |
  • <bdi> | 允許您設(shè)置一段文本荞彼,使其脫離其父元素的文本方向設(shè)置。 |
  • <command> | 定義命令按鈕待笑,比如單選按鈕鸣皂、復(fù)選框或按鈕 |
  • <details> | 用于描述文檔或文檔某個(gè)部分的細(xì)節(jié) |
  • <dialog> | 定義對(duì)話(huà)框,比如提示框 |
  • <summary> | 標(biāo)簽包含 details 元素的標(biāo)題 |
  • <figure> | 規(guī)定獨(dú)立的流內(nèi)容(圖像暮蹂、圖表寞缝、照片、代碼等等)仰泻。 |
  • <figcaption> | 定義 <figure> 元素的標(biāo)題 |
  • <footer> | 定義 section 或 document 的頁(yè)腳荆陆。 |
  • <header> | 定義了文檔的頭部區(qū)域 |
  • <mark> | 定義帶有記號(hào)的文本。 |
  • <meter> | 定義度量衡集侯。僅用于已知最大和最小值的度量被啼。 |
  • <nav> | 定義導(dǎo)航鏈接的部分帜消。 |
  • <progress> | 定義任何類(lèi)型的任務(wù)的進(jìn)度。 |
  • <ruby> | 定義 ruby 注釋?zhuān)ㄖ形淖⒁艋蜃址?|
  • <rt> | 定義字符(中文注音或字符)的解釋或發(fā)音浓体。 |
  • <rp> | 在 ruby 注釋中使用泡挺,定義不支持 ruby 元素的瀏覽器所顯示的內(nèi)容。 |
  • <section> | 定義文檔中的節(jié)(section命浴、區(qū)段)娄猫。 |
  • <time> | 定義日期或時(shí)間。 |
  • <wbr> | 規(guī)定在文本中的何處適合添加換行符生闲。 |

已移除的元素

以下的 HTML 4.01 元素在HTML5中已經(jīng)被刪除:

  • <acronym>
  • <applet>
  • <basefont>
  • <big>
  • <center>
  • <dir>
  • <font>
  • <frame>
  • <frameset>
  • <noframes>
  • <strike>
  • <tt>

四媳溺、Canvas

什么是 canvas?

HTML5 <canvas> 元素用于圖形的繪制,通過(guò)腳本 (通常是JavaScript)來(lái)完成.
<canvas> 標(biāo)簽只是圖形容器碍讯,您必須使用腳本來(lái)繪制圖形褂删。
你可以通過(guò)多種方法使用 canvas 繪制路徑,盒、圓冲茸、字符以及添加圖像屯阀。

創(chuàng)建一個(gè)畫(huà)布

<canvas id="myCanvas" width="200" height="100"></canvas>

使用 JavaScript 來(lái)繪制圖像

canvas 元素本身是沒(méi)有繪圖能力的。所有的繪制工作必須在 JavaScript 內(nèi)部完成:

實(shí)例
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);

實(shí)例解析:

首先轴术,找到 <canvas> 元素:

var c=document.getElementById("myCanvas");

然后难衰,創(chuàng)建 context 對(duì)象:

var ctx=c.getContext("2d");
  • getContext("2d") 對(duì)象是內(nèi)建的 HTML5 對(duì)象,擁有多種繪制路徑逗栽、矩形盖袭、圓形匾嘱、字符以及添加圖像的方法吮成。

下面的兩行代碼繪制一個(gè)紅色的矩形:

ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);
  • 設(shè)置fillStyle屬性可以是CSS顏色,漸變凰浮,或圖案凭峡。fillStyle 默認(rèn)設(shè)置是#000000(黑色)拙已。

  • fillRect(x,y,width,height) 方法定義了矩形當(dāng)前的填充方式。

Canvas 坐標(biāo)

canvas 是一個(gè)二維網(wǎng)格摧冀。
canvas 的左上角坐標(biāo)為 (0,0)
上面的 fillRect 方法擁有參數(shù) (0,0,150,75)倍踪。
意思是:在畫(huà)布上繪制 150x75 的矩形,從左上角開(kāi)始 (0,0)索昂。
坐標(biāo)實(shí)例
畫(huà)布的 X 和 Y 坐標(biāo)用于在畫(huà)布上對(duì)繪畫(huà)進(jìn)行定位.

Canvas - 路徑

在Canvas上畫(huà)線(xiàn)建车,我們將使用以下兩種方法:

  • moveTo(x,y) 定義線(xiàn)條開(kāi)始坐標(biāo)
  • lineTo(x,y) 定義線(xiàn)條結(jié)束坐標(biāo)
    繪制線(xiàn)條我們必須使用到 "ink" 的方法,就像stroke().
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.moveTo(0,0);
ctx.lineTo(200,100);
ctx.stroke();

在canvas中繪制圓形, 我們將使用以下方法:

arc(x,y,r,start,stop)

實(shí)際上我們?cè)诶L制圓形時(shí)使用了 "ink" 的方法, 比如 stroke() 或者 fill().

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.arc(95,50,40,0,2*Math.PI);
ctx.stroke();

Canvas - 文本

使用 canvas 繪制文本椒惨,重要的屬性和方法如下:

  • font - 定義字體
  • fillText(text,x,y) - 在 canvas 上繪制實(shí)心的文本
  • strokeText(text,x,y) - 在 canvas 上繪制空心的文本
    使用 fillText():

實(shí)例
使用 "Arial" 字體在畫(huà)布上繪制一個(gè)高 30px 的文字(實(shí)心):

JavaScript:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.fillText("Hello World",10,50);

使用 strokeText():
實(shí)例

使用 "Arial" 字體在畫(huà)布上繪制一個(gè)高 30px 的文字(空心):
JavaScript:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.strokeText("Hello World",10,50);

Canvas - 漸變

漸變可以填充在矩形, 圓形, 線(xiàn)條, 文本等等, 各種形狀可以自己定義不同的顏色缤至。

以下有兩種不同的方式來(lái)設(shè)置Canvas漸變:

createLinearGradient(x,y,x1,y1) - 創(chuàng)建線(xiàn)條漸變
createRadialGradient(x,y,r,x1,y1,r1) - 創(chuàng)建一個(gè)徑向/圓漸變

當(dāng)我們使用漸變對(duì)象,必須使用兩種或兩種以上的停止顏色康谆。

addColorStop()方法指定顏色停止领斥,參數(shù)使用坐標(biāo)來(lái)描述错洁,可以是0至1.

使用漸變,設(shè)置fillStyle或strokeStyle的值為 漸變戒突,然后繪制形狀屯碴,如矩形,文本膊存,或一條線(xiàn)导而。

使用 createLinearGradient():
JavaScript:

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
 
// 創(chuàng)建漸變
var grd=ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
 
// 填充漸變
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);
使用 createRadialGradient():

實(shí)例
創(chuàng)建一個(gè)徑向/圓漸變。使用漸變填充矩形:

JavaScript:

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
 
// 創(chuàng)建漸變
var grd=ctx.createRadialGradient(75,50,5,90,60,100);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
 
// 填充漸變
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);

Canvas - 圖像

把一幅圖像放置到畫(huà)布上, 使用以下方法:

drawImage(image,x,y)

JavaScript:

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("scream");
ctx.drawImage(img,10,10);

五隔崎、HTML5 內(nèi)聯(lián) SVG

什么是SVG今艺?

  • SVG 指可伸縮矢量圖形 (Scalable Vector Graphics)
  • SVG 用于定義用于網(wǎng)絡(luò)的基于矢量的圖形
  • SVG 使用 XML 格式定義圖形
  • SVG 圖像在放大或改變尺寸的情況下其圖形質(zhì)量不會(huì)有損失
  • SVG 是萬(wàn)維網(wǎng)聯(lián)盟的標(biāo)準(zhǔn)

SVG優(yōu)勢(shì)

與其他圖像格式相比(比如 JPEG 和 GIF),使用 SVG 的優(yōu)勢(shì)在于:

  • SVG 圖像可通過(guò)文本編輯器來(lái)創(chuàng)建和修改
  • SVG 圖像可被搜索爵卒、索引虚缎、腳本化或壓縮
  • SVG 是可伸縮的
  • SVG 圖像可在任何的分辨率下被高質(zhì)量地打印
  • SVG 可在圖像質(zhì)量不下降的情況下被放大
Internet Explorer 9+, Firefox, Opera, Chrome, 和 Safari 支持內(nèi)聯(lián)SVG。

SVG 與 Canvas兩者間的區(qū)別

  • SVG 是一種使用 XML 描述 2D 圖形的語(yǔ)言钓株。
  • Canvas 通過(guò) JavaScript 來(lái)繪制 2D 圖形实牡。
  • SVG 基于 XML,這意味著 SVG DOM 中的每個(gè)元素都是可用的轴合。您可以為某個(gè)元素附加 JavaScript 事件處理器创坞。在 SVG 中,每個(gè)被繪制的圖形均被視為對(duì)象受葛。如果 SVG 對(duì)象的屬性發(fā)生變化题涨,那么瀏覽器能夠自動(dòng)重現(xiàn)圖形。Canvas 是逐像素進(jìn)行渲染的总滩。在 canvas 中纲堵,一旦圖形被繪制完成,它就不會(huì)繼續(xù)得到瀏覽器的關(guān)注闰渔。如果其位置發(fā)生變化席函,那么整個(gè)場(chǎng)景也需要重新繪制,包括任何或許已被圖形覆蓋的對(duì)象澜建。

Canvas 與 SVG 的比較

下表列出了 canvas 與 SVG 之間的一些不同之處向挖。

Canvas | SVG

  • 依賴(lài)分辨率 | 不依賴(lài)分辨率
  • 不支持事件處理器 | 支持事件處理器
  • 弱的文本渲染能力 | 最適合帶有大型渲染區(qū)域的應(yīng)用程序(比如谷歌地圖)
  • 能夠以 .png 或 .jpg 格式保存結(jié)果圖像 | 復(fù)雜度高會(huì)減慢渲染速度(任何過(guò)度使 用 DOM 的應(yīng)用都不快)
  • 最適合圖像密集型的游戲,其中的許多對(duì)象會(huì)被頻繁重繪 | 不適合游戲應(yīng)用

六炕舵、HTML5 拖放(Drag 和 Drop)

HTML5 拖放實(shí)例

下面的例子是一個(gè)簡(jiǎn)單的拖放實(shí)例:

實(shí)例
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"> 
<title>菜鳥(niǎo)教程(runoob.com)</title>
<style type="text/css">
#div1 {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;}
</style>
<script>
function allowDrop(ev)
{
    ev.preventDefault();
}
 
function drag(ev)
{
    ev.dataTransfer.setData("Text",ev.target.id);
}
 
function drop(ev)
{
    ev.preventDefault();
    var data=ev.dataTransfer.getData("Text");
    ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
 
<p>拖動(dòng) RUNOOB.COM 圖片到矩形框中:</p>
 
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img loading="lazy" id="drag1" src="/images/logo.png" draggable="true" ondragstart="drag(event)" width="336" height="69">
 
</body>
</html>

設(shè)置元素為可拖放

首先,為了使元素可拖動(dòng)跟畅,把 draggable 屬性設(shè)置為 true :

<img draggable="true">

拖動(dòng)什么 - ondragstart 和 setData()

然后咽筋,規(guī)定當(dāng)元素被拖動(dòng)時(shí),會(huì)發(fā)生什么徊件。
在上面的例子中奸攻,ondragstart 屬性調(diào)用了一個(gè)函數(shù)蒜危,drag(event),它規(guī)定了被拖動(dòng)的數(shù)據(jù)睹耐。
dataTransfer.setData() 方法設(shè)置被拖數(shù)據(jù)的數(shù)據(jù)類(lèi)型和值:

function drag(ev)
{
    ev.dataTransfer.setData("Text",ev.target.id);
}

Text 是一個(gè) DOMString 表示要添加到 drag object 的拖動(dòng)數(shù)據(jù)的類(lèi)型辐赞。值是可拖動(dòng)元素的 id ("drag1")。

放到何處 - ondragover

ondragover 事件規(guī)定在何處放置被拖動(dòng)的數(shù)據(jù)硝训。
默認(rèn)地响委,無(wú)法將數(shù)據(jù)/元素放置到其他元素中。如果需要設(shè)置允許放置窖梁,我們必須阻止對(duì)元素的默認(rèn)處理方式赘风。
這要通過(guò)調(diào)用 ondragover 事件的 event.preventDefault() 方法:

event.preventDefault()

進(jìn)行放置 - ondrop

當(dāng)放置被拖數(shù)據(jù)時(shí),會(huì)發(fā)生 drop 事件纵刘。

在上面的例子中邀窃,ondrop 屬性調(diào)用了一個(gè)函數(shù),drop(event):

function drop(ev)
{
    ev.preventDefault();
    var data=ev.dataTransfer.getData("Text");
    ev.target.appendChild(document.getElementById(data));
}

代碼解釋?zhuān)?/p>

  • 調(diào)用 preventDefault() 來(lái)避免瀏覽器對(duì)數(shù)據(jù)的默認(rèn)處理(drop 事件的默認(rèn)行為是以鏈接形式打開(kāi))
  • 通過(guò) dataTransfer.getData("Text") 方法獲得被拖的數(shù)據(jù)假哎。該方法將返回在setData() 方法中設(shè)置為相同類(lèi)型的任何數(shù)據(jù)瞬捕。
  • 被拖數(shù)據(jù)是被拖元素的 id ("drag1")
  • 把被拖元素追加到放置元素(目標(biāo)元素)中

七、HTML5 Geolocation(地理定位)

Internet Explorer 9+, Firefox, Chrome, Safari 和 Opera 支持Geolocation(地理定位)

注意: Geolocation(地理定位)對(duì)于擁有 GPS 的設(shè)備舵抹,比如 iPhone山析,地理定位更加精確。

HTML5 - 使用地理定位

請(qǐng)使用 getCurrentPosition() 方法來(lái)獲得用戶(hù)的位置掏父。
下例是一個(gè)簡(jiǎn)單的地理定位實(shí)例笋轨,可返回用戶(hù)位置的經(jīng)度和緯度:

實(shí)例
var x=document.getElementById("demo");
function getLocation()
{
    if (navigator.geolocation)
    {
        navigator.geolocation.getCurrentPosition(showPosition);
    }
    else
    {
        x.innerHTML="該瀏覽器不支持獲取地理位置。";
    }
}
 
function showPosition(position)
{
    x.innerHTML="緯度: " + position.coords.latitude + 
    "<br>經(jīng)度: " + position.coords.longitude;    
}

實(shí)例解析:

  • 檢測(cè)是否支持地理定位
  • 如果支持赊淑,則運(yùn)行 getCurrentPosition() 方法爵政。如果不支持,則向用戶(hù)顯示一段消息陶缺。
  • 如果 getCurrentPosition() 運(yùn)行成功钾挟,則向參數(shù)showPosition中規(guī)定的函數(shù)返回一個(gè) coordinates 對(duì)象
  • showPosition() 函數(shù)獲得并顯示經(jīng)度和緯度

處理錯(cuò)誤和拒絕

getCurrentPosition() 方法的第二個(gè)參數(shù)用于處理錯(cuò)誤。它規(guī)定當(dāng)獲取用戶(hù)位置失敗時(shí)運(yùn)行的函數(shù):

實(shí)例
function showError(error)
{
    switch(error.code) 
    {
        case error.PERMISSION_DENIED:
            x.innerHTML="用戶(hù)拒絕對(duì)獲取地理位置的請(qǐng)求饱岸。"
            break;
        case error.POSITION_UNAVAILABLE:
            x.innerHTML="位置信息是不可用的掺出。"
            break;
        case error.TIMEOUT:
            x.innerHTML="請(qǐng)求用戶(hù)地理位置超時(shí)。"
            break;
        case error.UNKNOWN_ERROR:
            x.innerHTML="未知錯(cuò)誤苫费。"
            break;
    }
}

錯(cuò)誤代碼:

  • Permission denied - 用戶(hù)不允許地理定位
  • Position unavailable - 無(wú)法獲取當(dāng)前位置
  • Timeout - 操作超時(shí)

在地圖中顯示結(jié)果

如需在地圖中顯示結(jié)果汤锨,您需要訪(fǎng)問(wèn)可使用經(jīng)緯度的地圖服務(wù),比如谷歌地圖或百度地圖:

實(shí)例
function showPosition(position)
{
    var latlon=position.coords.latitude+","+position.coords.longitude;
 
    var img_url="http://maps.googleapis.com/maps/api/staticmap?center="
    +latlon+"&zoom=14&size=400x300&sensor=false";
    document.getElementById("mapholder").innerHTML="<img src='"+img_url+"'>";
}

給定位置的信息

本頁(yè)演示的是如何在地圖上顯示用戶(hù)的位置百框。不過(guò)闲礼,地理定位對(duì)于給定位置的信息同樣很有用處。
可用于:

  • 更新本地信息
  • 顯示用戶(hù)周?chē)呐d趣點(diǎn)
  • 交互式車(chē)載導(dǎo)航系統(tǒng) (GPS)

getCurrentPosition() 方法 - 返回?cái)?shù)據(jù)

T若成功,則 getCurrentPosition() 方法返回對(duì)象柬泽。始終會(huì)返回 latitude慎菲、longitude 以及 accuracy 屬性。如果可用锨并,則會(huì)返回其他下面的屬性露该。
屬性 描述

  • coords.latitude 十進(jìn)制數(shù)的緯度
  • coords.longitude 十進(jìn)制數(shù)的經(jīng)度
  • coords.accuracy 位置精度
  • coords.altitude 海拔,海平面以上以米計(jì)
  • coords.altitudeAccuracy 位置的海拔精度
  • coords.heading 方向第煮,從正北開(kāi)始以度計(jì)
  • coords.speed 速度解幼,以米/每秒計(jì)
  • timestamp 響應(yīng)的日期/時(shí)間

Geolocation 對(duì)象 - 其他有趣的方法

watchPosition() - 返回用戶(hù)的當(dāng)前位置,并繼續(xù)返回用戶(hù)移動(dòng)時(shí)的更新位置(就像汽車(chē)上的 GPS)空盼。
clearWatch() - 停止 watchPosition() 方法
下面的例子展示 watchPosition() 方法书幕。您需要一臺(tái)精確的 GPS 設(shè)備來(lái)測(cè)試該例(比如 iPhone):

實(shí)例
var x=document.getElementById("demo");
function getLocation()
{
    if (navigator.geolocation)
    {
        navigator.geolocation.watchPosition(showPosition);
    }
    else
    {
        x.innerHTML="該瀏覽器不支持獲取地理位置。";
    }
}
function showPosition(position)
{
    x.innerHTML="緯度: " + position.coords.latitude + 
    "<br>經(jīng)度: " + position.coords.longitude; 
}

七揽趾、HTML5 Video(視頻)

Internet Explorer 9+, Firefox, Opera, Chrome, 和 Safari 支持 <video> 元素.

HTML5 (視頻)- 如何工作

如需在 HTML5 中顯示視頻台汇,您所有需要的是:

實(shí)例
<video width="320" height="240" controls>
  <source src="movie.mp4" type="video/mp4">
  <source src="movie.ogg" type="video/ogg">
您的瀏覽器不支持Video標(biāo)簽。
</video>
  • <video> 元素提供了 播放篱瞎、暫停和音量控件來(lái)控制視頻苟呐。
    同時(shí) <video> 元素也提供了 width 和 height 屬性控制視頻的尺寸.如果設(shè)置的高度和寬度,所需的視頻空間會(huì)在頁(yè)面加載時(shí)保留俐筋。如果沒(méi)有設(shè)置這些屬性牵素,瀏覽器不知道大小的視頻,瀏覽器就不能再加載時(shí)保留特定的空間澄者,頁(yè)面就會(huì)根據(jù)原始視頻的大小而改變笆呆。
  • <video> 與</video> 標(biāo)簽之間插入的內(nèi)容是提供給不支持 video 元素的瀏覽器顯示的。
  • <video> 元素支持多個(gè) <source> 元素. <source> 元素可以鏈接不同的視頻文件粱挡。瀏覽器將使用第一個(gè)可識(shí)別的格式:

視頻格式與瀏覽器的支持

當(dāng)前赠幕, <video> 元素支持三種視頻格式: MP4, WebM, 和 Ogg:

瀏覽器 | MP4 | WebM | Ogg
Internet Explorer | YES | NO | NO
Chrome | YES | YES | YES
Firefox | YES | YES | YES
Safari | YES | NO | NO
Opera | YES (從 Opera 25 起) | YES | YES

  • MP4 = 帶有 H.264 視頻編碼和 AAC 音頻編碼的 MPEG 4 文件
  • WebM = 帶有 VP8 視頻編碼和 Vorbis 音頻編碼的 WebM 文件
  • Ogg = 帶有 Theora 視頻編碼和 Vorbis 音頻編碼的 Ogg 文件

視頻格式

格式 | MIME-type
MP4 | video/mp4
WebM | video/webm
Ogg | video/ogg

HTML5 <video> - 使用 DOM 進(jìn)行控制

HTML5 <video> 和 <audio> 元素同樣擁有方法、屬性和事件询筏。
<video> 和 <audio>元素的方法榕堰、屬性和事件可以使用JavaScript進(jìn)行控制.
其中的方法用于播放、暫停以及加載等嫌套。其中的屬性(比如時(shí)長(zhǎng)逆屡、音量等)可以被讀取或設(shè)置。其中的 DOM 事件能夠通知您踱讨,比方說(shuō)魏蔗,<video> 元素開(kāi)始播放、已暫停勇蝙,已停止沫勿,等等挨约。
例中簡(jiǎn)單的方法味混,向我們演示了如何使用 <video> 元素产雹,讀取并設(shè)置屬性,以及如何調(diào)用方法翁锡。

HTML5 Video 標(biāo)簽

| 標(biāo)簽 | 描述 |

  • <video> | 定義一個(gè)視頻 |
  • <source> | 定義多種媒體資源,比如 <video> 和<audio> |
  • <track> | 定義在媒體播放器文本軌跡 |

九蔓挖、HTML5 Audio(音頻)

Internet Explorer 9+, Firefox, Opera, Chrome, 和 Safari 都支持 <audio> 元素.

HTML5 Audio - 如何工作

如需在 HTML5 中播放音頻,你需要使用以下代碼:

實(shí)例

<audio  controls>  <source  src="horse.ogg"  type="audio/ogg">  <source  src="horse.mp3"  type="audio/mpeg"> 您的瀏覽器不支持 audio 元素馆衔。 </audio>

嘗試一下 ?
control 屬性供添加播放瘟判、暫停和音量控件。
在<audio> 與 </audio> 之間你需要插入瀏覽器不支持的<audio>元素的提示文本 角溃。
<audio> 元素允許使用多個(gè) <source> 元素. <source> 元素可以鏈接不同的音頻文件拷获,瀏覽器將使用第一個(gè)支持的音頻文件

音頻格式的MIME類(lèi)型

Format MIME-type

  • MP3 audio/mpeg
  • Ogg audio/ogg
  • Wav audio/wav

HTML5 Audio 標(biāo)簽

| 標(biāo)簽 | 描述 |

  • <audio> | 定義了聲音內(nèi)容 |
  • <source> | 規(guī)定了多媒體資源, 可以是多個(gè),在 <video> 與 <audio>標(biāo)簽中使用 |

十减细、HTML5 新的 Input 類(lèi)型

HTML5 擁有多個(gè)新的表單輸入類(lèi)型匆瓜。這些新特性提供了更好的輸入控制和驗(yàn)證。
本章全面介紹這些新的輸入類(lèi)型:

  • color
  • date
  • datetime
  • datetime-local
  • email
  • month
  • number
  • range
  • search
  • tel
  • time
  • url
  • week
    注意:并不是所有的主流瀏覽器都支持新的input類(lèi)型未蝌,不過(guò)您已經(jīng)可以在所有主流的瀏覽器中使用它們了驮吱。即使不被支持,仍然可以顯示為常規(guī)的文本域萧吠。

Input 類(lèi)型: color

color 類(lèi)型用在input字段主要用于選取顏色左冬,如下所示:
實(shí)例
從拾色器中選擇一個(gè)顏色:

<input type="color" name="favcolor">

Input 類(lèi)型: date

date 類(lèi)型允許你從一個(gè)日期選擇器選擇一個(gè)日期。
實(shí)例
定義一個(gè)時(shí)間控制器:

生日: <input type="date" name="bday">

Input 類(lèi)型: datetime

datetime 類(lèi)型允許你選擇一個(gè)日期(UTC 時(shí)間)纸型。
實(shí)例
定義一個(gè)日期和時(shí)間控制器(本地時(shí)間):

生日 (日期和時(shí)間): <input type="datetime" name="bdaytime">

Input 類(lèi)型: datetime-local

datetime-local 類(lèi)型允許你選擇一個(gè)日期和時(shí)間 (無(wú)時(shí)區(qū)).
實(shí)例
定義一個(gè)日期和時(shí)間 (無(wú)時(shí)區(qū)):

生日 (日期和時(shí)間): <input type="datetime-local" name="bdaytime">

Input 類(lèi)型: email

email 類(lèi)型用于應(yīng)該包含 e-mail 地址的輸入域拇砰。
實(shí)例
在提交表單時(shí),會(huì)自動(dòng)驗(yàn)證 email 域的值是否合法有效:

E-mail: <input type="email" name="email">

Input 類(lèi)型: month

month 類(lèi)型允許你選擇一個(gè)月份狰腌。
實(shí)例
定義月與年 (無(wú)時(shí)區(qū)):

生日 (月和年): <input type="month" name="bdaymonth">

Input 類(lèi)型: number

number 類(lèi)型用于應(yīng)該包含數(shù)值的輸入域除破。
您還能夠設(shè)定對(duì)所接受的數(shù)字的限定:
實(shí)例
定義一個(gè)數(shù)值輸入域(限定):

數(shù)量 ( 1 到 5 之間 ): <input type="number" name="quantity" min="1" max="5">

使用下面的屬性來(lái)規(guī)定對(duì)數(shù)字類(lèi)型的限定:

屬性 描述

  • disabled 規(guī)定輸入字段是禁用的
  • max 規(guī)定允許的最大值
  • maxlength 規(guī)定輸入字段的最大字符長(zhǎng)度
  • min 規(guī)定允許的最小值
  • pattern 規(guī)定用于驗(yàn)證輸入字段的模式
  • readonly 規(guī)定輸入字段的值無(wú)法修改
  • required 規(guī)定輸入字段的值是必需的
  • size 規(guī)定輸入字段中的可見(jiàn)字符數(shù)
  • step 規(guī)定輸入字段的合法數(shù)字間隔
  • value 規(guī)定輸入字段的默認(rèn)值

Input 類(lèi)型: range

range 類(lèi)型用于應(yīng)該包含一定范圍內(nèi)數(shù)字值的輸入域。
range 類(lèi)型顯示為滑動(dòng)條癌别。
實(shí)例
定義一個(gè)不需要非常精確的數(shù)值(類(lèi)似于滑塊控制):

<input type="range" name="points" min="1" max="10">

請(qǐng)使用下面的屬性來(lái)規(guī)定對(duì)數(shù)字類(lèi)型的限定:

  • max - 規(guī)定允許的最大值
  • min - 規(guī)定允許的最小值
  • step - 規(guī)定合法的數(shù)字間隔
  • value - 規(guī)定默認(rèn)值

Input 類(lèi)型: search

search 類(lèi)型用于搜索域皂岔,比如站點(diǎn)搜索或 Google 搜索。
實(shí)例
定義一個(gè)搜索字段 (類(lèi)似站點(diǎn)搜索或者Google搜索):

Search Google: <input type="search" name="googlesearch">

Input 類(lèi)型: tel

實(shí)例
定義輸入電話(huà)號(hào)碼字段:

電話(huà)號(hào)碼: <input type="tel" name="usrtel">

Input 類(lèi)型: time

time 類(lèi)型允許你選擇一個(gè)時(shí)間展姐。
實(shí)例
定義可輸入時(shí)間控制器(無(wú)時(shí)區(qū)):

選擇時(shí)間: <input type="time" name="usr_time">

Input 類(lèi)型: url

url 類(lèi)型用于應(yīng)該包含 URL 地址的輸入域躁垛。
在提交表單時(shí),會(huì)自動(dòng)驗(yàn)證 url 域的值圾笨。
實(shí)例
定義輸入U(xiǎn)RL字段:

添加您的主頁(yè): <input type="url" name="homepage">

Input 類(lèi)型: week

week 類(lèi)型允許你選擇周和年教馆。
實(shí)例
定義周和年 (無(wú)時(shí)區(qū)):

選擇周: <input type="week" name="week_year">

十一、HTML5 表單元素

HTML5 新的表單元素

HTML5 有以下新的表單元素:

  • <datalist>
  • <keygen>
  • <output>
    注意:不是所有的瀏覽器都支持HTML5 新的表單元素擂达,但是你可以在使用它們土铺,即使瀏覽器不支持表單屬性,仍然可以顯示為常規(guī)的表單元素。

HTML5 <datalist> 元素

<datalist> 元素規(guī)定輸入域的選項(xiàng)列表悲敷。
<datalist> 屬性規(guī)定 form 或 input 域應(yīng)該擁有自動(dòng)完成功能究恤。當(dāng)用戶(hù)在自動(dòng)完成域中開(kāi)始輸入時(shí),瀏覽器應(yīng)該在該域中顯示填寫(xiě)的選項(xiàng):
使用 <input> 元素的列表屬性與 <datalist> 元素綁定.
實(shí)例

<input> 元素使用<datalist>預(yù)定義值:
<input list="browsers">
<datalist id="browsers">
  <option value="Internet Explorer">
  <option value="Firefox">
  <option value="Chrome">
  <option value="Opera">
  <option value="Safari">
</datalist>

HTML5 <keygen> 元素

<keygen> 元素的作用是提供一種驗(yàn)證用戶(hù)的可靠方法后德。
<keygen>標(biāo)簽規(guī)定用于表單的密鑰對(duì)生成器字段部宿。
當(dāng)提交表單時(shí),會(huì)生成兩個(gè)鍵瓢湃,一個(gè)是私鑰理张,一個(gè)公鑰。
私鑰(private key)存儲(chǔ)于客戶(hù)端绵患,公鑰(public key)則被發(fā)送到服務(wù)器雾叭。公鑰可用于之后驗(yàn)證用戶(hù)的客戶(hù)端證書(shū)(client certificate)。
實(shí)例
帶有keygen字段的表單:

<form action="demo_keygen.asp" method="get">
用戶(hù)名: <input type="text" name="usr_name">
加密: <keygen name="security">
<input type="submit">
</form>

HTML5 <output> 元素

<output> 元素用于不同類(lèi)型的輸出落蝙,比如計(jì)算或腳本輸出:
實(shí)例
將計(jì)算結(jié)果顯示在 <output> 元素:

<form oninput="x.value=parseInt(a.value)+parseInt(b.value)">0
<input type="range" id="a" value="50">100 +
<input type="number" id="b" value="50">=
<output name="x" for="a b"></output>
</form>

HTML5 新表單元素

| 標(biāo)簽 | 描述 |

  • <datalist> | <input>標(biāo)簽定義選項(xiàng)列表织狐。請(qǐng)與 input 元素配合使用該元素,來(lái)定義 input 可能的值掘殴。 |
  • <keygen> | <keygen> 標(biāo)簽規(guī)定用于表單的密鑰對(duì)生成器字段赚瘦。 |
  • <output> | <output> 標(biāo)簽定義不同類(lèi)型的輸出,比如腳本的輸出奏寨。 |

十二起意、HTML5 表單屬性

HTML5 的 <form> 和 <input>標(biāo)簽添加了幾個(gè)新屬性.

<form>新屬性:

  • autocomplete

  • novalidate
    <input>新屬性:

  • autocomplete

  • autofocus

  • form

  • formaction

  • formenctype

  • formmethod

  • formnovalidate

  • formtarget

  • height 與 width

  • list

  • min 與 max

  • multiple

  • pattern (regexp)

  • placeholder

  • required

  • step

<form> / <input> autocomplete 屬性

autocomplete 屬性規(guī)定 form 或 input 域應(yīng)該擁有自動(dòng)完成功能。
當(dāng)用戶(hù)在自動(dòng)完成域中開(kāi)始輸入時(shí)病瞳,瀏覽器應(yīng)該在該域中顯示填寫(xiě)的選項(xiàng)揽咕。
提示: autocomplete 屬性有可能在 form元素中是開(kāi)啟的,而在input元素中是關(guān)閉的套菜。
注意: autocomplete 適用于 <form> 標(biāo)簽亲善,以及以下類(lèi)型的 <input> 標(biāo)簽:text, search, url, telephone, email, password, datepickers, range 以及 color。
實(shí)例
HTML form 中開(kāi)啟 autocomplete (一個(gè) input 字段關(guān)閉 autocomplete ):

<form action="demo-form.php" autocomplete="on">
  First name:<input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  E-mail: <input type="email" name="email" autocomplete="off"><br>
  <input type="submit">
</form>

<form> novalidate 屬性

novalidate 屬性是一個(gè) boolean(布爾) 屬性.
novalidate 屬性規(guī)定在提交表單時(shí)不應(yīng)該驗(yàn)證 form 或 input 域逗柴。
實(shí)例
無(wú)需驗(yàn)證提交的表單數(shù)據(jù)

<form action="demo-form.php" novalidate>
  E-mail: <input type="email" name="user_email">
  <input type="submit">
</form>

<input> autofocus 屬性

autofocus 屬性是一個(gè) boolean 屬性.
autofocus 屬性規(guī)定在頁(yè)面加載時(shí)蛹头,域自動(dòng)地獲得焦點(diǎn)。
實(shí)例
讓 "First name" input 輸入域在頁(yè)面載入時(shí)自動(dòng)聚焦:

First name:<input type="text" name="fname" autofocus>

<input> form 屬性

form 屬性規(guī)定輸入域所屬的一個(gè)或多個(gè)表單戏溺。
提示:如需引用一個(gè)以上的表單渣蜗,請(qǐng)使用空格分隔的列表。
實(shí)例
位于form表單外的 input 字段引用了 HTML form (該 input 表單仍然屬于form表單的一部分):

<form action="demo-form.php" id="form1">
  First name: <input type="text" name="fname"><br>
  <input type="submit" value="提交">
</form>
Last name: <input type="text" name="lname" form="form1">

<input> formaction 屬性

The formaction 屬性用于描述表單提交的URL地址.
The formaction 屬性會(huì)覆蓋<form> 元素中的action屬性.
注意: The formaction 屬性用于 type="submit" 和 type="image".
實(shí)例
以下HTMLform表單包含了兩個(gè)不同地址的提交按鈕:

<form action="demo-form.php">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  <input type="submit" value="提交"><br>
  <input type="submit" formaction="demo-admin.php"
  value="提交">
</form>

<input> formenctype 屬性

formenctype 屬性描述了表單提交到服務(wù)器的數(shù)據(jù)編碼 (只對(duì)form表單中 method="post" 表單)
formenctype 屬性覆蓋 form 元素的 enctype 屬性旷祸。
主要: 該屬性與 type="submit" 和 type="image" 配合使用耕拷。
實(shí)例
第一個(gè)提交按鈕已默認(rèn)編碼發(fā)送表單數(shù)據(jù),第二個(gè)提交按鈕以 "multipart/form-data" 編碼格式發(fā)送表單數(shù)據(jù):

<form action="demo-post_enctype.php" method="post">
  First name: <input type="text" name="fname"><br>
  <input type="submit" value="提交">
  <input type="submit" formenctype="multipart/form-data"
  value="以 Multipart/form-data 提交">
</form>

<input> formmethod 屬性

formmethod 屬性定義了表單提交的方式托享。
formmethod 屬性覆蓋了 <form> 元素的 method 屬性骚烧。
注意: 該屬性可以與 type="submit" 和 type="image" 配合使用浸赫。
實(shí)例
重新定義表單提交方式實(shí)例:

<form action="demo-form.php" method="get">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  <input type="submit" value="提交">
  <input type="submit" formmethod="post" formaction="demo-post.php"
  value="使用 POST 提交">
</form>

<input> formnovalidate 屬性

novalidate 屬性是一個(gè) boolean 屬性.
novalidate屬性描述了 <input> 元素在表單提交時(shí)無(wú)需被驗(yàn)證。
formnovalidate 屬性會(huì)覆蓋 <form> 元素的novalidate屬性.
注意: formnovalidate 屬性與type="submit一起使用
實(shí)例
兩個(gè)提交按鈕的表單(使用與不適用驗(yàn)證 ):

<form action="demo-form.php">
  E-mail: <input type="email" name="userid"><br>
  <input type="submit" value="提交"><br>
  <input type="submit" formnovalidate value="不驗(yàn)證提交">
</form>

<input> formtarget 屬性

formtarget 屬性指定一個(gè)名稱(chēng)或一個(gè)關(guān)鍵字來(lái)指明表單提交數(shù)據(jù)接收后的展示赃绊。
The formtarget 屬性覆蓋 <form>元素的target屬性.
注意: formtarget 屬性與type="submit" 和 type="image"配合使用.
實(shí)例
兩個(gè)提交按鈕的表單, 在不同窗口中顯示:

<form action="demo-form.php">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  <input type="submit" value="正常提交">
  <input type="submit" formtarget="_blank"
  value="提交到一個(gè)新的頁(yè)面上">
</form>

<input> height 和 width 屬性

height 和 width 屬性規(guī)定用于 image 類(lèi)型的 <input> 標(biāo)簽的圖像高度和寬度既峡。
注意: height 和 width 屬性只適用于 image 類(lèi)型的<input> 標(biāo)簽。
提示:圖像通常會(huì)同時(shí)指定高度和寬度屬性凭戴。如果圖像設(shè)置高度和寬度涧狮,圖像所需的空間 在加載頁(yè)時(shí)會(huì)被保留炕矮。如果沒(méi)有這些屬性么夫, 瀏覽器不知道圖像的大小,并不能預(yù)留 適當(dāng)?shù)目臻g肤视。圖片在加載過(guò)程中會(huì)使頁(yè)面布局效果改變 (盡管圖片已加載)档痪。
實(shí)例
定義了一個(gè)圖像提交按鈕, 使用了 height 和 width 屬性:

<input type="image" src="img_submit.gif" alt="Submit" width="48" height="48">

<input> list 屬性

list 屬性規(guī)定輸入域的 datalist。datalist 是輸入域的選項(xiàng)列表邢滑。
實(shí)例
在 <datalist>中預(yù)定義 <input> 值:

<input list="browsers">

<datalist id="browsers">
  <option value="Internet Explorer">
  <option value="Firefox">
  <option value="Chrome">
  <option value="Opera">
  <option value="Safari">
</datalist>

<input> min 和 max 屬性

min腐螟、max 和 step 屬性用于為包含數(shù)字或日期的 input 類(lèi)型規(guī)定限定(約束)。
注意: min困后、max 和 step 屬性適用于以下類(lèi)型的 <input> 標(biāo)簽:date pickers乐纸、number 以及 range。
實(shí)例
<input> 元素最小值與最大值設(shè)置:

Enter a date before 1980-01-01:
<input type="date" name="bday" max="1979-12-31">

Enter a date after 2000-01-01:
<input type="date" name="bday" min="2000-01-02">

Quantity (between 1 and 5):
<input type="number" name="quantity" min="1" max="5">

<input> multiple 屬性

multiple 屬性是一個(gè) boolean 屬性.
multiple 屬性規(guī)定<input> 元素中可選擇多個(gè)值摇予。
注意: multiple 屬性適用于以下類(lèi)型的 <input> 標(biāo)簽:email 和 file:
實(shí)例
上傳多個(gè)文件:

Select images: <input type="file" name="img" multiple>

<input> pattern 屬性

pattern 屬性描述了一個(gè)正則表達(dá)式用于驗(yàn)證 <input> 元素的值汽绢。
注意:pattern 屬性適用于以下類(lèi)型的 <input> 標(biāo)簽: text, search, url, tel, email, 和 password.
提示: 是用來(lái)全局 title 屬性描述了模式.
提示: 您可以在我們的 JavaScript 教程中學(xué)習(xí)到有關(guān)正則表達(dá)式的內(nèi)容
實(shí)例
下面的例子顯示了一個(gè)只能包含三個(gè)字母的文本域(不含數(shù)字及特殊字符):

Country code: <input type="text" name="country_code" pattern="[A-Za-z]{3}" title="Three letter country code">

<input> placeholder 屬性

placeholder 屬性提供一種提示(hint),描述輸入域所期待的值侧戴。
簡(jiǎn)短的提示在用戶(hù)輸入值前會(huì)顯示在輸入域上宁昭。
注意: placeholder 屬性適用于以下類(lèi)型的 <input> 標(biāo)簽:text, search, url, telephone, email 以及 password。
實(shí)例
input 字段提示文本t:

<input type="text" name="fname" placeholder="First name">

<input> required 屬性

required 屬性是一個(gè) boolean 屬性.
required 屬性規(guī)定必須在提交之前填寫(xiě)輸入域(不能為空)酗宋。
注意:required 屬性適用于以下類(lèi)型的 <input> 標(biāo)簽:text, search, url, telephone, email, password, date pickers, number, checkbox, radio 以及 file积仗。
實(shí)例
不能為空的input字段:

Username: <input type="text" name="usrname" required>

<input> step 屬性

step 屬性為輸入域規(guī)定合法的數(shù)字間隔。
如果 step="3"蜕猫,則合法的數(shù)是 -3,0,3,6 等
提示: step 屬性可以與 max 和 min 屬性創(chuàng)建一個(gè)區(qū)域值.
注意: step 屬性與以下type類(lèi)型一起使用: number, range, date, datetime, datetime-local, month, time 和 week.
實(shí)例
規(guī)定input step步長(zhǎng)為3:

<input type="number" name="points" step="3">

十三寂曹、HTML5 語(yǔ)義元素

HTML5中新的語(yǔ)義元素

許多現(xiàn)有網(wǎng)站都包含以下HTML代碼: <div id="nav">, <div class="header">, 或者 <div id="footer">, 來(lái)指明導(dǎo)航鏈接, 頭部, 以及尾部.
HTML5 提供了新的語(yǔ)義元素來(lái)明確一個(gè)Web頁(yè)面的不同部分:

  • <header>
  • <nav>
  • <section>
  • <article>
  • <aside>
  • <figcaption>
  • <figure>
  • <footer>

十四、HTML5 Web 存儲(chǔ)

Internet Explorer 8+, Firefox, Opera, Chrome, 和 Safari支持Web 存儲(chǔ)回右。

注意: Internet Explorer 7 及更早IE版本不支持web 存儲(chǔ).

localStorage 和 sessionStorage

客戶(hù)端存儲(chǔ)數(shù)據(jù)的兩個(gè)對(duì)象為:

  • localStorage - 用于長(zhǎng)久保存整個(gè)網(wǎng)站的數(shù)據(jù)隆圆,保存的數(shù)據(jù)沒(méi)有過(guò)期時(shí)間,直到手動(dòng)去除楣黍。
  • sessionStorage - 用于臨時(shí)保存同一窗口(或標(biāo)簽頁(yè))的數(shù)據(jù)匾灶,在關(guān)閉窗口或標(biāo)簽頁(yè)之后將會(huì)刪除這些數(shù)據(jù)。
    在使用 web 存儲(chǔ)前,應(yīng)檢查瀏覽器是否支持 localStorage 和sessionStorage:
if(typeof(Storage)!=="undefined")
{
    // 是的! 支持 localStorage  sessionStorage 對(duì)象!
    // 一些代碼.....
} else {
    // 抱歉! 不支持 web 存儲(chǔ)租漂。
}

localStorage 對(duì)象

localStorage 對(duì)象存儲(chǔ)的數(shù)據(jù)沒(méi)有時(shí)間限制阶女。第二天颊糜、第二周或下一年之后,數(shù)據(jù)依然可用秃踩。
實(shí)例

localStorage.sitename="菜鳥(niǎo)教程"; document.getElementById("result").innerHTML="網(wǎng)站名:" + localStorage.sitename;

實(shí)例解析:

  • 使用 key="sitename" 和 value="菜鳥(niǎo)教程" 創(chuàng)建一個(gè) localStorage 鍵/值對(duì)衬鱼。
  • 檢索鍵值為"sitename" 的值然后將數(shù)據(jù)插入 id="result"的元素中。
    以上實(shí)例也可以這么寫(xiě):
// 存儲(chǔ)  localStorage.sitename = "菜鳥(niǎo)教程"; // 查找  document.getElementById("result").innerHTML = localStorage.sitename;

移除 localStorage 中的 "sitename" :

localStorage.removeItem("sitename");

不管是 localStorage憔杨,還是 sessionStorage鸟赫,可使用的API都相同,常用的有如下幾個(gè)(以localStorage為例):

  • 保存數(shù)據(jù):localStorage.setItem(key,value);
  • 讀取數(shù)據(jù):localStorage.getItem(key);
  • 刪除單個(gè)數(shù)據(jù):localStorage.removeItem(key);
  • 刪除所有數(shù)據(jù):localStorage.clear();
  • 得到某個(gè)索引的key:localStorage.key(index);
    提示: 鍵/值對(duì)通常以字符串存儲(chǔ)消别,你可以按自己的需要轉(zhuǎn)換該格式抛蚤。
    下面的實(shí)例展示了用戶(hù)點(diǎn)擊按鈕的次數(shù)。
    代碼中的字符串值轉(zhuǎn)換為數(shù)字類(lèi)型:
    實(shí)例
if  (localStorage.clickcount)  {  localStorage.clickcount=Number(localStorage.clickcount)+1; }  else  {  localStorage.clickcount=1; }  document.getElementById("result").innerHTML=" 你已經(jīng)點(diǎn)擊了按鈕 " + localStorage.clickcount + " 次 ";

sessionStorage 對(duì)象

sessionStorage 方法針對(duì)一個(gè) session 進(jìn)行數(shù)據(jù)存儲(chǔ)寻狂。當(dāng)用戶(hù)關(guān)閉瀏覽器窗口后岁经,數(shù)據(jù)會(huì)被刪除。
如何創(chuàng)建并訪(fǎng)問(wèn)一個(gè) sessionStorage:
實(shí)例

if (sessionStorage.clickcount)
{
    sessionStorage.clickcount=Number(sessionStorage.clickcount)+1;
}
else
{
    sessionStorage.clickcount=1;
}
document.getElementById("result").innerHTML="在這個(gè)會(huì)話(huà)中你已經(jīng)點(diǎn)擊了該按鈕 " + sessionStorage.clickcount + " 次 ";

Web Storage 開(kāi)發(fā)一個(gè)簡(jiǎn)單的網(wǎng)站列表程序

網(wǎng)站列表程序?qū)崿F(xiàn)以下功能:

  • 可以輸入網(wǎng)站名蛇券,網(wǎng)址缀壤,以網(wǎng)站名作為key存入localStorage;
  • 根據(jù)網(wǎng)站名纠亚,查找網(wǎng)址塘慕;
  • 列出當(dāng)前已保存的所有網(wǎng)站;
    以下代碼用于保存于查找數(shù)據(jù):
  • save() 與 find() 方法
//保存數(shù)據(jù)  
function save(){  
    var siteurl = document.getElementById("siteurl").value;  
    var sitename = document.getElementById("sitename").value;  
    localStorage.setItem(sitename, siteurl);
    alert("添加成功");
}
//查找數(shù)據(jù)  
function find(){  
    var search_site = document.getElementById("search_site").value;  
    var sitename = localStorage.getItem(search_site);  
    var find_result = document.getElementById("find_result");  
    find_result.innerHTML = search_site + "的網(wǎng)址是:" + sitename;  
}

完整實(shí)例演示如下:

實(shí)例

<div style="border: 2px dashed #ccc;width:320px;text-align:center;">     
    <label for="sitename">網(wǎng)站名(key):</label>  
    <input type="text" id="sitename" name="sitename" class="text"/>  
    <br/>  
    <label for="siteurl">網(wǎng) 址(value):</label>  
    <input type="text" id="siteurl" name="siteurl"/>  
    <br/>  
    <input type="button" onclick="save()" value="新增記錄"/>  
    <hr/>  
    <label for="search_site">輸入網(wǎng)站名:</label>  
    <input type="text" id="search_site" name="search_site"/>  
    <input type="button" onclick="find()" value="查找網(wǎng)站"/>  
    <p id="find_result"><br/></p>  
</div>

筆記

增加了刪除方法蒂胞,并簡(jiǎn)單優(yōu)化了添加和刪除图呢,每次執(zhí)行完都會(huì)刷新頁(yè)面顯示最新操作的數(shù)據(jù):

//刪除數(shù)據(jù)   
function del(name) {
  localStorage.removeItem(name);
  alert("刪除成功!");
  loadAll();
}

如何隔離開(kāi)不同頁(yè)面之間的localStorage(總不能在百度的頁(yè)面上能讀到騰訊的localStorage吧,哈哈哈)啤誊。

localStorage只要在相同的協(xié)議岳瞭、相同的主機(jī)名、相同的端口下蚊锹,就能讀取/修改到同一份localStorage數(shù)據(jù)瞳筏。

sessionStorage比localStorage更嚴(yán)苛一點(diǎn),除了協(xié)議牡昆、主機(jī)名姚炕、端口外,還要求在同一窗口(也就是瀏覽器的標(biāo)簽頁(yè))下丢烘。

十五柱宦、HTML5 Web SQL 數(shù)據(jù)庫(kù)

核心方法

以下是規(guī)范中定義的三個(gè)核心方法:

  • openDatabase:這個(gè)方法使用現(xiàn)有的數(shù)據(jù)庫(kù)或者新建的數(shù)據(jù)庫(kù)創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)對(duì)象。
  • transaction:這個(gè)方法讓我們能夠控制一個(gè)事務(wù)播瞳,以及基于這種情況執(zhí)行提交或者回滾掸刊。
  • executeSql:這個(gè)方法用于執(zhí)行實(shí)際的 SQL 查詢(xún)。

打開(kāi)數(shù)據(jù)庫(kù)

我們可以使用 openDatabase() 方法來(lái)打開(kāi)已存在的數(shù)據(jù)庫(kù)赢乓,如果數(shù)據(jù)庫(kù)不存在忧侧,則會(huì)創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù)瓷耙,使用代碼如下:

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);

openDatabase() 方法對(duì)應(yīng)的五個(gè)參數(shù)說(shuō)明:

  • 數(shù)據(jù)庫(kù)名稱(chēng)
  • 版本號(hào)
  • 描述文本
  • 數(shù)據(jù)庫(kù)大小
  • 創(chuàng)建回調(diào)
    第五個(gè)參數(shù)堆巧,創(chuàng)建回調(diào)會(huì)在創(chuàng)建數(shù)據(jù)庫(kù)后被調(diào)用。

執(zhí)行查詢(xún)操作

執(zhí)行操作使用 database.transaction() 函數(shù):

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function (tx) {  
   tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
});

上面的語(yǔ)句執(zhí)行后會(huì)在 'mydb' 數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)名為 LOGS 的表拳锚。

插入數(shù)據(jù)

在執(zhí)行上面的創(chuàng)建表語(yǔ)句后谁尸,我們可以插入一些數(shù)據(jù):

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function (tx) {
   tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
   tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "菜鳥(niǎo)教程")');
   tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "www.runoob.com")');
});

我們也可以使用動(dòng)態(tài)值來(lái)插入數(shù)據(jù):

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function (tx) {  
  tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
  tx.executeSql('INSERT INTO LOGS (id,log) VALUES (?, ?)', [e_id, e_log]);
});

讀取數(shù)據(jù)

以下實(shí)例演示了如何讀取數(shù)據(jù)庫(kù)中已經(jīng)存在的數(shù)據(jù):

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
 
db.transaction(function (tx) {
   tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
   tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "菜鳥(niǎo)教程")');
   tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "www.runoob.com")');
});
 
db.transaction(function (tx) {
   tx.executeSql('SELECT * FROM LOGS', [], function (tx, results) {
      var len = results.rows.length, i;
      msg = "<p>查詢(xún)記錄條數(shù): " + len + "</p>";
      document.querySelector('#status').innerHTML +=  msg;
    
      for (i = 0; i < len; i++){
         alert(results.rows.item(i).log );
      }
    
   }, null);
});

實(shí)例中的 e_id 和 e_log 是外部變量沸毁,executeSql 會(huì)映射數(shù)組參數(shù)中的每個(gè)條目給 "?"摩桶。

完整實(shí)例

實(shí)例

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
var msg;
 
db.transaction(function (tx) {
    tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
    tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "菜鳥(niǎo)教程")');
    tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "www.runoob.com")');
    msg = '<p>數(shù)據(jù)表已創(chuàng)建烁试,且插入了兩條數(shù)據(jù)。</p>';
    document.querySelector('#status').innerHTML =  msg;
});
 
db.transaction(function (tx) {
tx.executeSql('SELECT * FROM LOGS', [], function (tx, results) {
    var len = results.rows.length, i;
    msg = "<p>查詢(xún)記錄條數(shù): " + len + "</p>";
    document.querySelector('#status').innerHTML +=  msg;
 
    for (i = 0; i < len; i++){
        msg = "<p><b>" + results.rows.item(i).log + "</b></p>";
        document.querySelector('#status').innerHTML +=  msg;
    }
}, null);
});

刪除記錄

刪除記錄使用的格式如下:

db.transaction(function (tx) {
    tx.executeSql('DELETE FROM LOGS  WHERE id=1');
});
刪除指定的數(shù)據(jù)id也可以是動(dòng)態(tài)的:

db.transaction(function(tx) {
    tx.executeSql('DELETE FROM LOGS WHERE id=?', [id]);
});

更新記錄

更新記錄使用的格式如下:

db.transaction(function (tx) {
    tx.executeSql('UPDATE LOGS SET log=\'www.w3cschool.cc\' WHERE id=2');
});
更新指定的數(shù)據(jù)id也可以是動(dòng)態(tài)的:

db.transaction(function(tx) {
    tx.executeSql('UPDATE LOGS SET log=\'www.w3cschool.cc\' WHERE id=?', [id]);
});

完整實(shí)例

實(shí)例

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
var msg;
 
 db.transaction(function (tx) {
    tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
    tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "菜鳥(niǎo)教程")');
    tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "www.runoob.com")');
    msg = '<p>數(shù)據(jù)表已創(chuàng)建驯击,且插入了兩條數(shù)據(jù)烁兰。</p>';
    document.querySelector('#status').innerHTML =  msg;
 });
 
 db.transaction(function (tx) {
      tx.executeSql('DELETE FROM LOGS  WHERE id=1');
      msg = '<p>刪除 id 為 1 的記錄。</p>';
      document.querySelector('#status').innerHTML =  msg;
 });
 
 db.transaction(function (tx) {
     tx.executeSql('UPDATE LOGS SET log=\'www.w3cschool.cc\' WHERE id=2');
      msg = '<p>更新 id 為 2 的記錄余耽。</p>';
      document.querySelector('#status').innerHTML =  msg;
 });
 
 db.transaction(function (tx) {
    tx.executeSql('SELECT * FROM LOGS', [], function (tx, results) {
       var len = results.rows.length, i;
       msg = "<p>查詢(xún)記錄條數(shù): " + len + "</p>";
       document.querySelector('#status').innerHTML +=  msg;
       
       for (i = 0; i < len; i++){
          msg = "<p><b>" + results.rows.item(i).log + "</b></p>";
          document.querySelector('#status').innerHTML +=  msg;
       }
    }, null);
 });

十六缚柏、HTML5 應(yīng)用程序緩存

Internet Explorer 10, Firefox, Chrome, Safari 和 Opera 支持應(yīng)用程序緩存.

什么是應(yīng)用程序緩存(Application Cache)?

HTML5 引入了應(yīng)用程序緩存碟贾,這意味著 web 應(yīng)用可進(jìn)行緩存,并可在沒(méi)有因特網(wǎng)連接時(shí)進(jìn)行訪(fǎng)問(wèn)轨域。

應(yīng)用程序緩存為應(yīng)用帶來(lái)三個(gè)優(yōu)勢(shì):

  • 離線(xiàn)瀏覽 - 用戶(hù)可在應(yīng)用離線(xiàn)時(shí)使用它們
  • 速度 - 已緩存資源加載得更快
  • 減少服務(wù)器負(fù)載 - 瀏覽器將只從服務(wù)器下載更新過(guò)或更改過(guò)的資源袱耽。

Cache Manifest 基礎(chǔ)

如需啟用應(yīng)用程序緩存,請(qǐng)?jiān)谖臋n的<html> 標(biāo)簽中包含 manifest 屬性:

<!DOCTYPE HTML>
<html manifest="demo.appcache">
...
</html>

每個(gè)指定了 manifest 的頁(yè)面在用戶(hù)對(duì)其訪(fǎng)問(wèn)時(shí)都會(huì)被緩存干发。如果未指定 manifest 屬性朱巨,則頁(yè)面不會(huì)被緩存(除非在 manifest 文件中直接指定了該頁(yè)面)。
manifest 文件的建議的文件擴(kuò)展名是:".appcache"枉长。
請(qǐng)注意冀续,manifest 文件需要配置正確的 MIME-type,即 "text/cache-manifest"必峰。必須在 web 服務(wù)器上進(jìn)行配置洪唐。

Manifest 文件

manifest 文件是簡(jiǎn)單的文本文件,它告知瀏覽器被緩存的內(nèi)容(以及不緩存的內(nèi)容)吼蚁。
manifest 文件可分為三個(gè)部分:

  • CACHE MANIFEST - 在此標(biāo)題下列出的文件將在首次下載后進(jìn)行緩存
  • NETWORK - 在此標(biāo)題下列出的文件需要與服務(wù)器的連接凭需,且不會(huì)被緩存
  • FALLBACK - 在此標(biāo)題下列出的文件規(guī)定當(dāng)頁(yè)面無(wú)法訪(fǎng)問(wèn)時(shí)的回退頁(yè)面(比如 404 頁(yè)面)

CACHE MANIFEST

第一行,CACHE MANIFEST肝匆,是必需的:

CACHE MANIFEST
/theme.css
/logo.gif
/main.js

上面的 manifest 文件列出了三個(gè)資源:一個(gè) CSS 文件粒蜈,一個(gè) GIF 圖像,以及一個(gè) JavaScript 文件旗国。當(dāng) manifest 文件加載后枯怖,瀏覽器會(huì)從網(wǎng)站的根目錄下載這三個(gè)文件。然后能曾,無(wú)論用戶(hù)何時(shí)與因特網(wǎng)斷開(kāi)連接度硝,這些資源依然是可用的设捐。

NETWORK

下面的 NETWORK 小節(jié)規(guī)定文件 "login.php" 永遠(yuǎn)不會(huì)被緩存,且離線(xiàn)時(shí)是不可用的:

NETWORK:
login.php

可以使用星號(hào)來(lái)指示所有其他資源/文件都需要因特網(wǎng)連接:

NETWORK:
*

FALLBACK

下面的 FALLBACK 小節(jié)規(guī)定如果無(wú)法建立因特網(wǎng)連接塘淑,則用 "offline.html" 替代 /html5/ 目錄中的所有文件:

FALLBACK:
/html/ /offline.html

注意: 第一個(gè) URI 是資源萝招,第二個(gè)是替補(bǔ)。

更新緩存

一旦應(yīng)用被緩存存捺,它就會(huì)保持緩存直到發(fā)生下列情況:

  • 用戶(hù)清空瀏覽器緩存
  • manifest 文件被修改(參閱下面的提示)
  • 由程序來(lái)更新應(yīng)用緩存

實(shí)例 - 完整的 Manifest 文件

CACHE MANIFEST
# 2012-02-21 v1.0.0
/theme.css
/logo.gif
/main.js

NETWORK:
login.php

FALLBACK:
/html/ /offline.html

提示:以 "#" 開(kāi)頭的是注釋行槐沼,但也可滿(mǎn)足其他用途。應(yīng)用的緩存會(huì)在其 manifest 文件更改時(shí)被更新捌治。如果您編輯了一幅圖片岗钩,或者修改了一個(gè) JavaScript 函數(shù),這些改變都不會(huì)被重新緩存肖油。更新注釋行中的日期和版本號(hào)是一種使瀏覽器重新緩存文件的辦法兼吓。

關(guān)于應(yīng)用程序緩存的說(shuō)明

請(qǐng)留心緩存的內(nèi)容。

一旦文件被緩存森枪,則瀏覽器會(huì)繼續(xù)展示已緩存的版本视搏,即使您修改了服務(wù)器上的文件。為了確保瀏覽器更新緩存县袱,您需要更新 manifest 文件浑娜。

注意: 瀏覽器對(duì)緩存數(shù)據(jù)的容量限制可能不太一樣(某些瀏覽器設(shè)置的限制是每個(gè)站點(diǎn) 5MB)。

十七式散、HTML5 Web Workers

Internet Explorer 10, Firefox, Chrome, Safari 和 Opera 都支持Web workers.

什么是 Web Worker筋遭?

當(dāng)在 HTML 頁(yè)面中執(zhí)行腳本時(shí),頁(yè)面的狀態(tài)是不可響應(yīng)的暴拄,直到腳本已完成漓滔。

web worker 是運(yùn)行在后臺(tái)的 JavaScript,獨(dú)立于其他腳本乖篷,不會(huì)影響頁(yè)面的性能响驴。您可以繼續(xù)做任何愿意做的事情:點(diǎn)擊、選取內(nèi)容等等那伐,而此時(shí) web worker 在后臺(tái)運(yùn)行踏施。

檢測(cè)瀏覽器是否支持 Web Worker

在創(chuàng)建 web worker 之前,請(qǐng)檢測(cè)用戶(hù)的瀏覽器是否支持它:

if(typeof(Worker)!=="undefined")
{
    // 是的! Web worker 支持!
    // 一些代碼.....
}
else
{
    //抱歉! Web Worker 不支持
}

創(chuàng)建 web worker 文件

現(xiàn)在罕邀,讓我們?cè)谝粋€(gè)外部 JavaScript 中創(chuàng)建我們的 web worker畅形。

在這里,我們創(chuàng)建了計(jì)數(shù)腳本诉探。該腳本存儲(chǔ)于 "demo_workers.js" 文件中:

var i=0;

function timedCount()
{
    i=i+1;
    postMessage(i);
    setTimeout("timedCount()",500);
}

timedCount();

以上代碼中重要的部分是 postMessage() 方法 - 它用于向 HTML 頁(yè)面?zhèn)骰匾欢蜗ⅰ?/p>

注意: web worker 通常不用于如此簡(jiǎn)單的腳本日熬,而是用于更耗費(fèi) CPU 資源的任務(wù)。

創(chuàng)建 Web Worker 對(duì)象

我們已經(jīng)有了 web worker 文件肾胯,現(xiàn)在我們需要從 HTML 頁(yè)面調(diào)用它竖席。

下面的代碼檢測(cè)是否存在 worker耘纱,如果不存在,- 它會(huì)創(chuàng)建一個(gè)新的 web worker 對(duì)象毕荐,然后運(yùn)行 "demo_workers.js" 中的代碼:

if(typeof(w)=="undefined")
{
    w=new Worker("demo_workers.js");
}

然后我們就可以從 web worker 發(fā)生和接收消息了束析。

向 web worker 添加一個(gè) "onmessage" 事件監(jiān)聽(tīng)器:

w.onmessage=function(event){
    document.getElementById("result").innerHTML=event.data;
};

終止 Web Worker

當(dāng)我們創(chuàng)建 web worker 對(duì)象后,它會(huì)繼續(xù)監(jiān)聽(tīng)消息(即使在外部腳本完成之后)直到其被終止為止憎亚。

如需終止 web worker员寇,并釋放瀏覽器/計(jì)算機(jī)資源,請(qǐng)使用 terminate() 方法:

w.terminate();

完整的 Web Worker 實(shí)例代碼

我們已經(jīng)看到了 .js 文件中的 Worker 代碼第美。下面是 HTML 頁(yè)面的代碼:

實(shí)例

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>菜鳥(niǎo)教程(runoob.com)</title> 
</head>
<body>
 
<p>計(jì)數(shù): <output id="result"></output></p>
<button onclick="startWorker()">開(kāi)始工作</button> 
<button onclick="stopWorker()">停止工作</button>
 
<p><strong>注意:</strong> Internet Explorer 9 及更早 IE 版本瀏覽器不支持 Web Workers.</p>
 
<script>
var w;
 
function startWorker() {
    if(typeof(Worker) !== "undefined") {
        if(typeof(w) == "undefined") {
            w = new Worker("demo_workers.js");
        }
        w.onmessage = function(event) {
            document.getElementById("result").innerHTML = event.data;
        };
    } else {
        document.getElementById("result").innerHTML = "抱歉蝶锋,你的瀏覽器不支持 Web Workers...";
    }
}
 
function stopWorker() 
{ 
    w.terminate();
    w = undefined;
}
</script>
 
</body>
</html>

Web Workers 和 DOM

由于 web worker 位于外部文件中,它們無(wú)法訪(fǎng)問(wèn)下列 JavaScript 對(duì)象:

  • window 對(duì)象
  • document 對(duì)象
  • parent 對(duì)象

十八什往、HTML5 服務(wù)器發(fā)送事件(Server-Sent Events)

HTML5 服務(wù)器發(fā)送事件(server-sent event)允許網(wǎng)頁(yè)獲得來(lái)自服務(wù)器的更新扳缕。

Server-Sent 事件 - 單向消息傳遞

Server-Sent 事件指的是網(wǎng)頁(yè)自動(dòng)獲取來(lái)自服務(wù)器的更新。

以前也可能做到這一點(diǎn)别威,前提是網(wǎng)頁(yè)不得不詢(xún)問(wèn)是否有可用的更新躯舔。通過(guò)服務(wù)器發(fā)送事件,更新能夠自動(dòng)到達(dá)兔港。

例子:Facebook/Twitter 更新庸毫、股價(jià)更新、新的博文衫樊、賽事結(jié)果等。

接收 Server-Sent 事件通知

EventSource 對(duì)象用于接收服務(wù)器發(fā)送事件通知:

實(shí)例

var source=new EventSource("demo_sse.php");
source.onmessage=function(event)
{
    document.getElementById("result").innerHTML+=event.data + "<br>";
};

實(shí)例解析:

  • 創(chuàng)建一個(gè)新的 EventSource 對(duì)象利花,然后規(guī)定發(fā)送更新的頁(yè)面的 URL(本例中是 "demo_sse.php")
  • 每接收到一次更新科侈,就會(huì)發(fā)生 onmessage 事件
  • 當(dāng) onmessage 事件發(fā)生時(shí),把已接收的數(shù)據(jù)推入 id 為 "result" 的元素中

檢測(cè) Server-Sent 事件支持

以下實(shí)例炒事,我們編寫(xiě)了一段額外的代碼來(lái)檢測(cè)服務(wù)器發(fā)送事件的瀏覽器支持情況:

if(typeof(EventSource)!=="undefined")
{
    // 瀏覽器支持 Server-Sent
    // 一些代碼.....
}
else
{
    // 瀏覽器不支持 Server-Sent..
}

服務(wù)器端代碼實(shí)例

為了讓上面的例子可以運(yùn)行臀栈,您還需要能夠發(fā)送數(shù)據(jù)更新的服務(wù)器(比如 PHP 和 ASP)。

服務(wù)器端事件流的語(yǔ)法是非常簡(jiǎn)單的挠乳。把 "Content-Type" 報(bào)頭設(shè)置為 "text/event-stream"∪ㄊ恚現(xiàn)在,您可以開(kāi)始發(fā)送事件流了睡扬。

實(shí)例

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
?>

ASP 代碼 (VB) (demo_sse.asp):

<%
Response.ContentType="text/event-stream"
Response.Expires=-1
Response.Write("data: " & now())
Response.Flush()
%>

代碼解釋:

  • 把報(bào)頭 "Content-Type" 設(shè)置為 "text/event-stream"
  • 規(guī)定不對(duì)頁(yè)面進(jìn)行緩存
  • 輸出發(fā)送日期(始終以 "data: " 開(kāi)頭)
  • 向網(wǎng)頁(yè)刷新輸出數(shù)據(jù)

EventSource 對(duì)象

在上面的例子中盟蚣,我們使用 onmessage 事件來(lái)獲取消息。不過(guò)還可以使用其他事件:

事件 描述

  • onopen 當(dāng)通往服務(wù)器的連接被打開(kāi)
  • onmessage 當(dāng)接收到消息
  • onerror 當(dāng)發(fā)生錯(cuò)誤

筆記

在上面 asp 代碼里卖怜,別忘記 \n\n屎开。

如果你用ASP.NET C#制作,則 demo_sse.aspx 代碼如下:

<%@ Page Language="C#"   %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.ContentType = "text/event-stream";
        Response.Expires = -1;
        Response.Write("data:" + DateTime.Now + "\n\n");
        Response.Flush();
    }
</script>

需要以 \n\n 結(jié)尾马靠,否則奄抽,會(huì)得不到數(shù)據(jù)蔼两。

十九、HTML5 WebSocket

WebSocket 是 HTML5 開(kāi)始提供的一種在單個(gè) TCP 連接上進(jìn)行全雙工通訊的協(xié)議逞度。

WebSocket 使得客戶(hù)端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡(jiǎn)單额划,允許服務(wù)端主動(dòng)向客戶(hù)端推送數(shù)據(jù)。在 WebSocket API 中档泽,瀏覽器和服務(wù)器只需要完成一次握手俊戳,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸茁瘦。

在 WebSocket API 中品抽,瀏覽器和服務(wù)器只需要做一個(gè)握手的動(dòng)作,然后甜熔,瀏覽器和服務(wù)器之間就形成了一條快速通道圆恤。兩者之間就直接可以數(shù)據(jù)互相傳送。

現(xiàn)在腔稀,很多網(wǎng)站為了實(shí)現(xiàn)推送技術(shù)盆昙,所用的技術(shù)都是 Ajax 輪詢(xún)。輪詢(xún)是在特定的的時(shí)間間隔(如每1秒)焊虏,由瀏覽器對(duì)服務(wù)器發(fā)出HTTP請(qǐng)求淡喜,然后由服務(wù)器返回最新的數(shù)據(jù)給客戶(hù)端的瀏覽器。這種傳統(tǒng)的模式帶來(lái)很明顯的缺點(diǎn)诵闭,即瀏覽器需要不斷的向服務(wù)器發(fā)出請(qǐng)求炼团,然而HTTP請(qǐng)求可能包含較長(zhǎng)的頭部,其中真正有效的數(shù)據(jù)可能只是很小的一部分疏尿,顯然這樣會(huì)浪費(fèi)很多的帶寬等資源瘟芝。

HTML5 定義的 WebSocket 協(xié)議,能更好的節(jié)省服務(wù)器資源和帶寬褥琐,并且能夠更實(shí)時(shí)地進(jìn)行通訊锌俱。
瀏覽器通過(guò) JavaScript 向服務(wù)器發(fā)出建立 WebSocket 連接的請(qǐng)求,連接建立以后敌呈,客戶(hù)端和服務(wù)器端就可以通過(guò) TCP 連接直接交換數(shù)據(jù)贸宏。

當(dāng)你獲取 Web Socket 連接后,你可以通過(guò) send() 方法來(lái)向服務(wù)器發(fā)送數(shù)據(jù)磕洪,并通過(guò) onmessage 事件來(lái)接收服務(wù)器返回的數(shù)據(jù)吭练。

以下 API 用于創(chuàng)建 WebSocket 對(duì)象。

var Socket = new WebSocket(url, [protocol] );

以上代碼中的第一個(gè)參數(shù) url, 指定連接的 URL褐鸥。第二個(gè)參數(shù) protocol 是可選的线脚,指定了可接受的子協(xié)議。

WebSocket 屬性

以下是 WebSocket 對(duì)象的屬性。假定我們使用了以上代碼創(chuàng)建了 Socket 對(duì)象:

屬性 描述
Socket.readyState
只讀屬性 readyState 表示連接狀態(tài)浑侥,可以是以下值:

  • 0 - 表示連接尚未建立姊舵。
  • 1 - 表示連接已建立,可以進(jìn)行通信寓落。
  • 2 - 表示連接正在進(jìn)行關(guān)閉括丁。
  • 3 - 表示連接已經(jīng)關(guān)閉或者連接不能打開(kāi)。

Socket.bufferedAmount

  • 只讀屬性 bufferedAmount 已被 send() 放入正在隊(duì)列中等待傳輸伶选,但是還沒(méi)有發(fā)出的 UTF-8 文本字節(jié)數(shù)史飞。

WebSocket 事件

以下是 WebSocket 對(duì)象的相關(guān)事件。假定我們使用了以上代碼創(chuàng)建了 Socket 對(duì)象:

事件 事件處理程序 描述

  • open Socket.onopen 連接建立時(shí)觸發(fā)
  • message Socket.onmessage 客戶(hù)端接收服務(wù)端數(shù)據(jù)時(shí)觸發(fā)
  • error Socket.onerror 通信發(fā)生錯(cuò)誤時(shí)觸發(fā)
  • close Socket.onclose 連接關(guān)閉時(shí)觸發(fā)

WebSocket 方法

以下是 WebSocket 對(duì)象的相關(guān)方法仰税。假定我們使用了以上代碼創(chuàng)建了 Socket 對(duì)象:

方法 描述

  • Socket.send()
    使用連接發(fā)送數(shù)據(jù)

  • Socket.close()
    關(guān)閉連接

WebSocket 實(shí)例

WebSocket 協(xié)議本質(zhì)上是一個(gè)基于 TCP 的協(xié)議构资。

為了建立一個(gè) WebSocket 連接,客戶(hù)端瀏覽器首先要向服務(wù)器發(fā)起一個(gè) HTTP 請(qǐng)求陨簇,這個(gè)請(qǐng)求和通常的 HTTP 請(qǐng)求不同吐绵,包含了一些附加頭信息,其中附加頭信息"Upgrade: WebSocket"表明這是一個(gè)申請(qǐng)協(xié)議升級(jí)的 HTTP 請(qǐng)求河绽,服務(wù)器端解析這些附加的頭信息然后產(chǎn)生應(yīng)答信息返回給客戶(hù)端己单,客戶(hù)端和服務(wù)器端的 WebSocket 連接就建立起來(lái)了,雙方就可以通過(guò)這個(gè)連接通道自由的傳遞信息耙饰,并且這個(gè)連接會(huì)持續(xù)存在直到客戶(hù)端或者服務(wù)器端的某一方主動(dòng)的關(guān)閉連接纹笼。

客戶(hù)端的 HTML 和 JavaScript

目前大部分瀏覽器支持 WebSocket() 接口,你可以在以下瀏覽器中嘗試實(shí)例: Chrome, Mozilla, Opera 和 Safari苟跪。

runoob_websocket.html 文件內(nèi)容

<!DOCTYPE HTML>
<html>
   <head>
   <meta charset="utf-8">
   <title>菜鳥(niǎo)教程(runoob.com)</title>
    
      <script type="text/javascript">
         function WebSocketTest()
         {
            if ("WebSocket" in window)
            {
               alert("您的瀏覽器支持 WebSocket!");
               
               // 打開(kāi)一個(gè) web socket
               var ws = new WebSocket("ws://localhost:9998/echo");
                
               ws.onopen = function()
               {
                  // Web Socket 已連接上廷痘,使用 send() 方法發(fā)送數(shù)據(jù)
                  ws.send("發(fā)送數(shù)據(jù)");
                  alert("數(shù)據(jù)發(fā)送中...");
               };
                
               ws.onmessage = function (evt) 
               { 
                  var received_msg = evt.data;
                  alert("數(shù)據(jù)已接收...");
               };
                
               ws.onclose = function()
               { 
                  // 關(guān)閉 websocket
                  alert("連接已關(guān)閉..."); 
               };
            }
            
            else
            {
               // 瀏覽器不支持 WebSocket
               alert("您的瀏覽器不支持 WebSocket!");
            }
         }
      </script>
        
   </head>
   <body>
   
      <div id="sse">
         <a href="javascript:WebSocketTest()">運(yùn)行 WebSocket</a>
      </div>
      
   </body>
</html>

安裝 pywebsocket

在執(zhí)行以上程序前,我們需要?jiǎng)?chuàng)建一個(gè)支持 WebSocket 的服務(wù)件已。從 pywebsocket 下載 mod_pywebsocket ,或者使用 git 命令下載:

git clone https://github.com/googlearchive/pywebsocket
<p>
mod_pywebsocket  需要 python 環(huán)境支持</p>
mod_pywebsocket 是一個(gè) Apache HTTP 的 Web Socket擴(kuò)展牍疏,安裝步驟如下:</p>

<ul>
<li><p>解壓下載的文件。</p></li>
<li><p>進(jìn)入 <b>pywebsocket</b> 目錄拨齐。</p></li>
<li><p>執(zhí)行命令:</p>
<pre>$ python setup.py build
$ sudo python setup.py install

查看文檔說(shuō)明:

$ pydoc mod_pywebsocket

開(kāi)啟服務(wù)

在 pywebsocket/mod_pywebsocket 目錄下執(zhí)行以下命令:

$ sudo python standalone.py -p 9998 -w ../example/

筆記

Websocket 使用 ws 或 wss 的統(tǒng)一資源標(biāo)志符,類(lèi)似于 HTTPS昨寞,其中 wss 表示在 TLS 之上的 Websocket瞻惋。如:

ws://example.com/wsapi
wss://secure.example.com/

Websocket 使用和 HTTP 相同的 TCP 端口,可以繞過(guò)大多數(shù)防火墻的限制援岩。默認(rèn)情況下歼狼,Websocket 協(xié)議使用 80 端口;運(yùn)行在 TLS 之上時(shí)享怀,默認(rèn)使用 443 端口羽峰。
一個(gè)典型的Websocket握手請(qǐng)求如下:
客戶(hù)端請(qǐng)求

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

服務(wù)器回應(yīng)

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/
  • Connection 必須設(shè)置 Upgrade,表示客戶(hù)端希望連接升級(jí)。
  • Upgrade 字段必須設(shè)置 Websocket梅屉,表示希望升級(jí)到 Websocket 協(xié)議值纱。
  • Sec-WebSocket-Key 是隨機(jī)的字符串,服務(wù)器端會(huì)用這些數(shù)據(jù)來(lái)構(gòu)造出一個(gè) SHA-1 的信息摘要坯汤。把 “Sec-WebSocket-Key” 加上一個(gè)特殊字符串 “258EAFA5-E914-47DA-95CA-C5AB0DC85B11”虐唠,然后計(jì)算 SHA-1 摘要,之后進(jìn)行 BASE-64 編碼惰聂,將結(jié)果做為 “Sec-WebSocket-Accept” 頭的值疆偿,返回給客戶(hù)端。如此操作搓幌,可以盡量避免普通 HTTP 請(qǐng)求被誤認(rèn)為 Websocket 協(xié)議杆故。
  • Sec-WebSocket-Version 表示支持的 Websocket 版本。RFC6455 要求使用的版本是 13溉愁,之前草案的版本均應(yīng)當(dāng)棄用处铛。
  • Origin 字段是可選的,通常用來(lái)表示在瀏覽器中發(fā)起此 Websocket 連接所在的頁(yè)面叉钥,類(lèi)似于 Referer罢缸。但是,與 Referer 不同的是投队,Origin 只包含了協(xié)議和主機(jī)名稱(chēng)枫疆。
  • 其他一些定義在 HTTP 協(xié)議中的字段,如 Cookie 等敷鸦,也可以在 Websocket 中使用息楔。

在服務(wù)器方面,網(wǎng)上都有不同對(duì)websocket支持的服務(wù)器:

說(shuō)到 websocket 我覺(jué)得有必要說(shuō)下跟 socket 的區(qū)別。

軟件通信有七層結(jié)構(gòu)碟案,下三層結(jié)構(gòu)偏向與數(shù)據(jù)通信愿险,上三層更偏向于數(shù)據(jù)處理,中間的傳輸層則是連接上三層與下三層之間的橋梁价说,每一層都做不同的工作辆亏,上層協(xié)議依賴(lài)與下層協(xié)議”钅浚基于這個(gè)通信結(jié)構(gòu)的概念扮叨。

Socket 其實(shí)并不是一個(gè)協(xié)議,是應(yīng)用層與 TCP/IP 協(xié)議族通信的中間軟件抽象層领迈,它是一組接口彻磁。當(dāng)兩臺(tái)主機(jī)通信時(shí)碍沐,讓 Socket 去組織數(shù)據(jù),以符合指定的協(xié)議衷蜓。TCP 連接則更依靠于底層的 IP 協(xié)議累提,IP 協(xié)議的連接則依賴(lài)于鏈路層等更低層次。

WebSocket 則是一個(gè)典型的應(yīng)用層協(xié)議恍箭。

總的來(lái)說(shuō):Socket 是傳輸控制層協(xié)議刻恭,WebSocket 是應(yīng)用層協(xié)議。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扯夭,一起剝皮案震驚了整個(gè)濱河市鳍贾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌交洗,老刑警劉巖骑科,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異构拳,居然都是意外死亡咆爽,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)置森,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)斗埂,“玉大人,你說(shuō)我怎么就攤上這事凫海∏盒祝” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵行贪,是天一觀(guān)的道長(zhǎng)漾稀。 經(jīng)常有香客問(wèn)我,道長(zhǎng)建瘫,這世上最難降的妖魔是什么崭捍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮啰脚,結(jié)果婚禮上殷蛇,老公的妹妹穿的比我還像新娘。我一直安慰自己橄浓,他們只是感情好晾咪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著贮配,像睡著了一般。 火紅的嫁衣襯著肌膚如雪塞赂。 梳的紋絲不亂的頭發(fā)上泪勒,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼圆存。 笑死叼旋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沦辙。 我是一名探鬼主播夫植,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼油讯!你這毒婦竟也來(lái)了详民?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤陌兑,失蹤者是張志新(化名)和其女友劉穎沈跨,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體兔综,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饿凛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了软驰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涧窒。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖锭亏,靈堂內(nèi)的尸體忽然破棺而出纠吴,到底是詐尸還是另有隱情,我是刑警寧澤贰镣,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布呜象,位于F島的核電站,受9級(jí)特大地震影響碑隆,放射性物質(zhì)發(fā)生泄漏恭陡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一上煤、第九天 我趴在偏房一處隱蔽的房頂上張望休玩。 院中可真熱鬧,春花似錦劫狠、人聲如沸拴疤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)呐矾。三九已至,卻和暖如春懦砂,著一層夾襖步出監(jiān)牢的瞬間蜒犯,已是汗流浹背组橄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留罚随,地道東北人玉工。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像淘菩,于是被迫代替她去往敵國(guó)和親遵班。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容