這是以前作HTML 5的學習筆記,以後還會分享出一些其餘的筆記。都是一些早期無知少年筆記,喜歡就看吧。不喜歡,扔了!!javascript
能夠將內容複製粘貼本身看,或者直接另存成HTML文件也能夠。筆記是經過evernote編寫的,本人能夠直接導出成HTML文檔等。須要的能夠留Email,我能夠發文件。
php
這個文檔只適合看看了解一下HTML 5,裏面也有demo。或者複習一下,真正深刻學習的話,仍是買點書。研究一下協議~~
html
一、主體結構元素
<article>
<header>
<h1>蘋果</h1>
<p>發表日期:<time pubdate="pubdate">2010/10/09</time></p>
</header>
<p><b>蘋果</b>, 植物類水果,屢次花果.....("蘋果"文章正文)</p>
<footer>
<p><small>著做版權###公司全部。</small></p>
</footer>
</article>
article元素是能夠嵌套使用的,內層的內容再原則上須要與外層的內容相關聯。例如,一篇博文,針對該文章的評論就可使用嵌套article。(pubdate表明發佈時間)
....
<p><b>蘋果</b>, 植物類水果,屢次花果.....("蘋果"文章正文)</p>
<section>
<h2>評論</h2>
<article>
<header>
<h3>發表者:lucy</h3>
<p>
<time pubdate datetime="2010-10-10T19:00-08:00">
1小時前
</time>
</p>
<header>
</article>
<article>...</article>
</section>
</article>
article元素也能夠用來表示插件,它的做用是使插件看起來好像內嵌在頁面中。
<article>
<h1>My Fruit Spinner</h1>
<object>
<param name="allowFullScreen" value="true">
<embed src="#" width="600" height="395"></embeb>
</object>
</article>
section元素用於對網站或應用程序中頁面上的內容進行分塊。section元素由內容和標題組成。但section元素是一個特殊的容器元素,當一個容器須要被直接定義樣式或經過腳本定義行爲時,推薦使用div而非section元素。一般不推薦位那些沒有標題的內容使用section元素。
<body>
<h1>技術資料</h1>
<nav>
<ul>
<li><a href="/">主頁</a></li>
<li><a herf="/events">開發文檔</a></li>
</ul>
</nav>
<article>
<header>
<h1> HTML 5 與 CSS 3的歷史</h1>
<nav>
<ul>
<li><a href="#HTML 5">HTML 5的歷史</a></li>
<li><a href="#CSS 3">CSS 3的歷史</a></li>
</ul>
</nav>
</header>
<section id="HTML 5">
<h1>HTML 5的歷史</h1>
<p>講述HTML 5的歷史的正文</p>
</section>
<section id="CSS 3">
<h1>CSS 3的歷史</h1>
<p>講述CSS 3的歷史的正文</p>
</section>
..。
<footer>
<p>
<a href="?edit">編輯</a> |
<a href="?delete">刪除</a> |
<a href="?rename">重命名</a>
</p>
</footer>
</article>
<footer>
<p><small>版權全部...</small></p>
</footer>
</body>
nav元素能夠用於如下這些場合
傳統導航條
側邊欄導航
頁內導航
翻頁操做
aside元素用來表示當前頁面或文章的附屬信息部分,它能夠包含與當前頁面或主要內容相關的引用、側邊欄、廣告、導航條
有些機器編碼過程會對時間產生歧義,HTML 5增長了一個新的元素來無歧義地、明確地對機器的日期和時間進行編碼,而且以讓人易讀的方式來展現它
<time datetime="2010-11-13">2010年11月13日</time>
<time datetime="2010-11-13T20:00">我生日的晚上8點</time>
編碼時機器讀到的部分在datetime屬性裏,而元素的開始標記和結束標記中間的部分顯示在網頁上。
<header>
<hgroup>
<h1>IT 新技術</h1>
<a href="http://blog.sina.com.cn/itnewtech">
http://blog.sina.com.cn/itnewtech
</a>
<a href="#">[訂閱]</a>
<a href="#">[手機訂閱]</a>
</hgroup>
<nav>
<ul>
<li>首頁</li>
<li><a href="#">博文目錄</a></li>
<li><a href="#">圖片</a></li>
<li><a href="#">關於我</a></li>
</ul>
</nav>
</header>
hgroup元素
hgroup元素是將標題及其子標題進行分組的元素。hgroup元素一般會將h1~h6元素進行分組,譬如一個內容區塊的標及其子標題算一組。
<header>
<hgroup>
<h1>主標題</h1>
<h2>子標題</h2>
</hgroup>
</header>
footer元素能夠做爲其上層父級內容區塊或者根區塊的腳註。footer一般包括其相關區塊的腳註信息,如做者、相關閱讀連接及版權信息等。
address元素
address元素用來在文檔呈現聯繫信息,包括文檔做者或文檔維護者的名字、他們的網站連接、電子郵箱、真實地址、電話號碼等。
<address>
<a href="#">lucy</a>
<a href="#">lily</a>
<a href="#">cecil</a>
</address>
結構元素大致用div也能夠實現,只是若是使用結構元素的話,那麼網頁代碼的可讀性則會大大增強。純HTML 5結構的網頁實例:
2、表單和文件
一、新增元素和屬性
在HTML4中,表單內的從屬元素必須書寫在表單內部,可是在HTML5中,能夠把它們書寫在頁面上任何地方,而後給該元素指定一個form屬性,屬性值爲該表單的id,這樣就能夠聲明該元素從屬於指定表單了。
<form id="testform">
<input type="text">
</form>
<textarea form="testform"></textarea>
在HTML4中,一個表單內的全部元素都只能經過表單的action屬性統一提交到另外一個頁面,而在HTML5中能夠給全部的提交按鈕,諸如<input type="submit">、
<input type="image">、<button type="submit">都增長不一樣的formaction屬性
<form id="testform" action="serve.jsp">
<input type="submit" name="s1" value="v1" formation="s1.jsp">提交到S1
<input type="submit" name="s2" value="v2" formation="s2.jsp">提交到S2
<input type="submit" name="s3" value="v3" formation="s3.jsp">提交到S3
<input type="submit">
</form>
PS: 目前尚沒有瀏覽器支持這一屬性
placeholder是指當文本框(input、textarea)處於未輸入狀態時文本框中顯示的輸入提示。
<input type="text" placeholder="input me"/>
給文本框、選擇框或按鈕控件加上該屬性,當畫面打開時,該控件自動得到光標焦點
<input type="text" autofocus/>
在HTML5中,爲單行文本框(<input type="text">) 增長了一個list屬性,該屬性的值爲某個datalist元素的id。datalist元素也是HTML5新增的元素,改元素相似於選擇框,可是當用戶想要設定的值不在選擇列表以內時,容許其自行輸入。該元素自己並不顯示,而是當文本框得到焦點時以提示輸入的方式顯示。爲了不在沒有支持該元素的瀏覽器顯示,能夠用CSS將其隱藏。
<input type="text" name="greeting" list="greetings"/>
<!--使用style="display:none;" 將datalist元素設定爲不顯示-->
<datalist id="greetings" style="display:none;">
<option value="Good Morning">Good Morning</option>
<option value="Hello">Hello</option>
<option value="Good Afternoon">Good Afternoon</option>
</datalist>
輔助輸入所用的自動完成
<input type="text" name="greeting" list="greetings" autocomplete="on"/>
PS: chrome20不支持
search、tel、url、email等,可參照:
output元素
output元素必須從屬於某個表單,也就是說,必須將它書寫在表單內部,或者對它添加form屬性
<form id="testform">
請選擇一個值
<input name="range1" type=range min=0 max=100 step=5/>
<output onforminput="value=range1.value">50</output>
</form>
PS: 目前只有Opera支持得比較好
二、表單驗證
2.一、自動驗證
<form method="post">
<input name="text" type="text" required pattern="^\w.*$"/>
<input type="submit"/>
</form>
min與max這兩個屬性是數值類型或日期類型的input元素的專用屬性
step屬性控制input元素中的值增長或減小時的步幅
2.二、顯示驗證
form元素與input元素(包括select元素與textarea元素)都具備一個checkValidity方法。調用該方法,能夠顯示地對錶單內全部元素內容或單個元素內容進行有效性驗證。checkValidity方法以boolean的形式返回驗證結果。
<script language="javascript">
function check(){
var email = document.getElementById("email");
if(email.value==""){
alert("請輸入Email地址");
return false;
}...
}
</script>
<form id="testform" onsubmit="return check();">
Email:
<input name="email" type="email" id="email"/><br/>
<input type="submit"/>
</form>
三、加強的頁面元素
figure元素用來表示網頁上一塊獨立的內容,能夠是圖片、統計圖或代碼示例,甚至是音頻插件、視頻插件等。figcaption元素表示figure元素的標題,從屬figure元素,必須寫在figure元素內部。
<figure>
<img src="lufu.jpg" alt="lufu"/>
<img src="lufu2.jpg" alt="lufu"/>
<figcaption>路飛</figcaption>
</figure>
提供了一種替代JavaScript的、將畫面上局部區域進行展開或收縮的方法。summary元素從屬於details元素,用鼠標點擊summary元素中的內容文字時,detail元素中的其餘從屬元素將會展開或收縮。若是沒有summary元素,瀏覽器也會提供默認的樣式。details元素還提供了「open」屬性, 使用<details open>,則默認頁面加載時就打開details裏面的內容。
<details>
<summary>HTML 5</summary>
This document teaches you everything you have to learn about HTML5
</details>
mark元素表示頁面中須要突出顯示或高亮顯示的,通常能夠用於顯示關鍵字高亮,或者是與用戶相關須要提醒用戶的時候使用。
<h1>搜索"<mark>HTML 5</mark>", 找到相關網頁約10,200,000篇,用時0.041秒</h1>
<section id="search-results">
<article>
<h2>
<a href="#">專題:<mark>HTML 5 </mark> 下一代web開發標準</a>
</h2>
<p><mark>HTML 5</mark>近十年XXXXXXXXX</p>
</article>
<article>
<h2>
<a href="#">專題:<mark>HTML 5 </mark> 下一代web開發標準</a>
</h2>
<p><mark>HTML 5</mark>近十年XXXXXXXXX</p>
</article>
</section>
PS:mark元素的做用與em元素、strong元素是有區別的,mark元素的標示目的與原文做者無關,而是在後來引用時添加上去的,目的是爲了吸引當前用戶或者給用戶作參考。而em、strong是原文做者用來強調一段文字的重要性添加的。
progress元素表明一個任務的完成進度
meter元素表示規定範圍內的數量值
四、文件API
在HTML5中,經過添加multiple屬性,file控件內容許一次放置多個文件。控件內的每個用戶選擇的文件都是一個file對象,而FileList對象則爲這些file對象的列表,表明用戶選擇的全部文件。
<script language=javascript>
function showFileName(){
var file;
for(var i=0; i < document.getElementById("file").files.length; i++){
file = document.getElementById("file").files[i];
alert(file.name + ": 最後一次修改時間" + file.lastModifiedDate);
}
}
</script>
選擇文件:
<input type="file" id="file" multiple size="80"/><br/>
<input type="button" onclick="showFileName();" value="show File Name"/>
表示二進制原始數據,它提供了一個slice方法,能夠經過該方法訪問到字節內部的原始數據塊。file對象繼承了Blog對象。Blob對象有兩個屬性,size屬性表示一個Blob對象的字節長度,type屬性表示Blob的MIME類型,若是未知類型,返回空字符。
HTML5 對file控件添加了accept屬性,但目前僅支持圖像,其餘的設置無效
<input type="file" id="file" multiple size="80" accept="image/*"/>
FileReader接口擁有4個方法,3個用於讀取文件(readAsBinaryString、readAsText、readAsDataURL【主要是圖片和html文件】),另外一個用來將讀取過程當中斷(abort)。另外,FileReader接口還提供了一套完整的事件模型。(onabort、onerror、onloadstart、onprogerss、onload、onloadend)
PS: 須要在服務器上運行纔有效
<script language=javascript>
var result = document.getElementById("result");
var file = document.getElementById("file");
if(typeof FileReader == 'undefined'){
result.innerHTML = "<p>抱歉,你的瀏覽器不支持 FileReader</p>";
file.setAttribute('disabled', 'disabled');
}
//將文件以Data URL形式讀入頁面
function readAsDataURL(){
var file = document.getElementById("file").files[0];
if(file == null){
alert("請選擇文件!!");
return false;
}
if(!/image\/\w+/.test(file.type)){
alert("請確保文件爲圖像類型");
return false;
}
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e){
var result = document.getElementById("result");
result.innerHTML = '<img src="' + this.result + '" alt=""/>';
}
}
//將文件以二進制形式讀入頁面
function readAsBinaryString(){
var file = document.getElementById("file").files[0];
if(file == null){
alert("請選擇文件!!");
return false;
}
var reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = function(f){
var result = document.getElementById("result");
result.innerHTML = this.result;
}
}
//將文件以文本形式讀入頁面
function readAsText(){
var file = document.getElementById("file").files[0];
if(file == null){
alert("請選擇文件!!");
return false;
}
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function(f){
var result = document.getElementById("result");
result.innerHTML = this.result;
}
}
</script>
<p>
<label>請選擇一個文件: </label>
<input type="file" id="file"/><br/>
<input type="button" value="讀取圖像" onclick="readAsDataURL();"/>
<input type="button" value="讀取二進制數據" onclick="readAsBinaryString();"/>
<input type="button" value="讀取文本文件" onclick="readAsText();"/>
</p>
<div name="result" id="result">
</div>
五、拖放API
5.1 操做:
- 將想要拖放的對象元素的draggable屬性設爲true(draggable="true"),另外,img元素與a元素(必須指定href)默認容許拖放
- 編寫與拖放相關的事件處理代碼(dragstart、drag、dragenter、dragover、dragleave、drop、dragend)
<script language=javascript>
function init(){
var source = document.getElementById("dragme");
var dest = document.getElementById("text");
//drag start
source.addEventListener("dragstart", function(ev){
var dt = ev.dataTransfer;
//DataTransfer專門用來存放拖放時要攜帶的數據
dt.effectAllowed = "all";
dt.setData("text/plain", "hello");
}, false);
//drag end
dest.addEventListener("dragend", function(ev){
ev.preventDefault();
}, false);
//drop
dest.addEventListener("drop", function(ev){
var dt = ev.dataTransfer;
var text = dt.getData("text/plain");
dest.textContent += text;
ev.preventDefault();
ev.stopPropagation();
},false);
}
document.ondragover = function(e){e.preventDefault();};
document.ondrop = function(e){e.preventDefault();};
</script>
<body onload="init()">
<h1>simple drag demo</h1>
<div id="dragme" draggable="true" style="width: 200px; border: 1px solid gray;">
please drag
</div>
<div id="text" style="width: 200px; height: 200px; border: 1px solid gray;"></div>
</body>
5.2 DataTransfer對象的屬性與方法
如今支持拖動處理的MIME的類型爲text/plain、text/html、text/xml、text/uri-list。
若是DataTransfer對象的屬性和方法使用得好,能夠實現定製拖放圖標,讓它只支持特定拖放(譬如拷貝/移動)等。
3、繪製圖形
一、canvas繪製
首先,要指定ID、width、height三個屬性。canvas在頁面放置的時候跟其餘元素沒有太大區別。
<canvas id="canvas" width="400" height="300"/>
繪製步驟:
- 取得canvas元素
- 取得上下文,須要使用canvas對象的getContext方法來得到圖形上下文。
- 填充與繪製邊框
- 設定繪製樣式
- 指定線寬lineWidth
- 指定顏色值
- 繪製矩形
canvas元素繪製圖形,通常有兩種方式——填充(fill) 與繪製邊框 (stroke), 經過filleStyle指定填充樣式,strokeStyle指定圖形邊框樣式。fillRect方法和storkeRect方法來填充矩形和繪製矩形邊框。
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title> first canvas demo ### </title>
<script type="text/javascript" src="firstCanvas.js"></script>
</head>
<body onload="draw('canvas')">
<h1>canvas元素實例</h1>
<canvas id="canvas" width="400" height="300"/>
</body>
#########firstCanvas.js######
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
context.fillStyle="#EEEEFF";
context.fillRect(0, 0, 400, 300);
context.fillStyle = "red";
context.strokeStyle = "blue";
context.lineWidth = 1;
context.fillRect(50, 50, 100, 100);
context.strokeRect(50, 50, 100, 100);
}
另外,還有一個context.clearRect(x, y, width, height)方法, 該方法將擦除指定的矩形區域中的圖形,使得矩形區域中的顏色所有變爲透明。
二、使用路徑
除了長方形或正方形,要畫其餘的圖形,須要使用路徑,依然是最開始取得上下文,以後步驟:
- 開始建立路徑 context.beginPath()
- 建立圖形的路徑 context.arc(x, y, radius, startAngle, endAngle, anticlockwise)
- 路徑建立完成後,關閉路徑 context.closePath()
- 設定繪製樣式,調用繪製方法,繪製路徑 contex.fillStyle="rgba(255, 0, 0, 0.25)" ;context.fill();
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
context.fillStyle = '#EEEEFF';
context.fillRect(0, 0, 400, 300);
var n = 0;
for(var i=0; i < 10; i++){
context.beginPath();
context.arc(i*25, i*25, i*10, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = 'rgba(255, 0, 0, 0.25)';
context.fill();
}
}
繪製直線時,通常會用到moveTo與lineTo。moveTo(x, y)方法是將光標移動到指定座標點,lineTo(x, y)方法在moveTo方法中指定的直線起點與參數中指定的直線終點之間繪製一條線。
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
context.fillStyle = '#EEEEFF';
context.fillRect(0, 0, 400, 300);
var n = 0;
var dx = 150;
var dy = 150;
var s = 100;
context.beginPath();
context.fillStyle = 'rgb(100, 255, 100)';
context.strokeStyle = 'rgb(0, 0, 100)';
var x = Math.sin(0);
var y = Math.cos(0);
var dig = Math.PI / 15 * 11;
for(var i=0; i < 30; i++){
var x = Math.sin(i * dig);
var y = Math.cos(i * dig);
context.lineTo(dx + x * s, dy + y * s);
}
context.closePath();
context.fill();
context.stroke();
}
三、繪製漸變圖形
3.1 線性漸變
繪製線性漸變時,須要用到LinearGradient對象。使用圖形上下文對象的createLinearGradient方法建立該對象:
context.createLinearGradient(xStart, yStart, xEnd, yEnd),xStart爲漸變起始地點的橫座標,yStart爲漸變起始地點的縱座標,xEnd爲漸變結束點的橫座標,yEnd爲漸變結束點的縱座標。
在LinearGradient對象後,使用addColorStop方法進行漸變的顏色設定:
context.addColorStop(offset, color), offset爲所設定的顏色離開漸變起始點的偏移量。該參數的值是一個範圍在0到1之間的浮點值。由於是漸變,須要至少使用兩次addColorStop方法以追加兩個顏色(開始顏色與結束顏色),能夠追加多個顏色。例如「從藍色漸變到白色,而後漸變到綠色」。
以後把fillStyle設定爲LinearGradient對象,而後執行填充的方法,就能夠繪製出漸變圖形。
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
var g1 = context.createLinearGradient(0, 0, 0, 300);
g1.addColorStop(0, 'rgb(255, 255, 0)');
g1.addColorStop(1, 'rgb(0, 255, 255)');
context.fillStyle = g1;
context.fillRect(0, 0, 400, 300);
var n = 0;
var g2 = context.createLinearGradient(0, 0, 300, 0);
g2.addColorStop(0, 'rgba(0, 0, 255, 0.5)');
g2.addColorStop(1, 'rgba(255, 0, 0, 0.5)');
for(var i=0; i < 10; i++){
context.beginPath();
context.fillStyle = g2;
context.arc(i * 25, i * 25, i * 10, 0, Math.PI * 2, true);
context.closePath();
context.fill();
}
}
3.2 徑向漸變
徑向漸變指沿着圓形的半徑方向向外進行擴散的漸變方式,方法定義以下:
context.createRadialGradient(xStart, yStart, radiusStart, xEnd, yEnd, radiusEnd),xStart爲漸變開始圓的圓心橫座標,yStart爲漸變開始圓的圓心縱座標,radiusStart爲開始圓的半徑,xEnd爲漸變結束圓的圓心橫座標,yEnd爲漸變結束圓的圓心縱座標,radiusEnd爲結束圓的半徑。分別指定了兩個圓的大小與位置,從第一個圓的圓心處向外進行擴散漸變,一直擴散到第二圓的外輪廓處。
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
var g1 = context.createRadialGradient(400, 0, 0, 400, 0, 400);
g1.addColorStop(0.1, 'rgb(255, 255, 0)');
g1.addColorStop(0.3, 'rgb(255, 0, 255)');
g1.addColorStop(1, 'rgb(0, 255, 255)');
context.fillStyle = g1;
context.fillRect(0, 0, 400, 300);
var n = 0;
var g2 = context.createLinearGradient(250, 250, 0, 250, 250, 300);
g2.addColorStop(0.1, 'rgba(255, 0, 0, 0.5)');
g2.addColorStop(0.7, 'rgba(255, 255, 0, 0.5)');
g2.addColorStop(1, 'rgba(0, 0, 255, 0.5)');
for(var i=0; i < 10; i++){
context.beginPath();
context.fillStyle = g2;
context.arc(i * 25, i * 25, i * 10, 0, Math.PI * 2, true);
context.closePath();
context.fill();
}
}
四、繪製變形圖形
4.1 座標變換
context.translate(x, y); x表示將座標軸原點向左移動多少個單位,默認狀況下爲像素;y表示將座標軸原點向下移動多少個單位。
context.scale(x, y); x是水平方向的放大倍數,y是垂直方向的放大倍數,若是是縮寫,能夠填入0到1之間的小數。
context.rotate(angle); angle指旋轉的角度,旋轉的中心點是座標軸的原點,旋轉是以順時針進行的,要想逆時針旋轉,則把angle設爲負數
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
context.fillStyle = '#EEEEFF';
context.fillRect(0, 0, 400, 300);
//繪製圖形
context.translate(200, 50);
context.fillStyle = 'rgba(255, 0, 0, 0.25)';
for(var i=0; i < 50; i++){
context.translate(25, 25);
context.scale(0.95, 0.95);
context.rotate(Math.PI/10);
//畫矩形
context.fillRect(0, 0, 100, 50);
}
}
4.2 座標變換與路徑的結合使用
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
context.fillStyle = '#EEEEFF';
context.fillRect(0, 0, 400, 300);
//繪製圖形
context.translate(200, 50);
context.fillStyle = 'rgba(255, 0, 0, 0.25)';
for(var i=0; i < 50; i++){
context.translate(25, 25);
context.scale(0.95, 0.95);
context.rotate(Math.PI/10);
//畫複雜圖形
create5Star(context);
context.fill();
}
}
function create5Star(context){
var n = 0;
var dx = 100;
var dy = 0;
var s = 50;
//建立路徑
context.beginPath();
context.fillStyle = 'rgba(255, 0 ,0 , 0.5)';
var x = Math.sin(0);
var y = Math.cos(0);
var dig = Math.PI/5 * 4;
for(var i=0; i < 5; i++){
var x = Math.sin(i * dig);
var y = Math.cos(i * dig);
context.lineTo(dx + x * s, dy + y * s);
}
}
4.3 矩陣變換
變換矩陣是專門用來實現圖形變形的,它與座標一塊兒配合使用,以達到變形的目的。當圖形上下文被建立完畢時,事實上也建立了一個默認的變換矩陣,若是不對這個變換矩陣進行修改,那麼接下來繪製的圖形將以畫布的最左上角爲座標原點繪製圖形,繪製出來的圖形也不通過縮放、變形的處理,但若是對這個變換矩陣進行修改,那麼狀況就徹底不同了。
context.transform(m11, m12, m21, m22, dx, dy);
PS: transform須要必定的矩陣知識,比較難理解。
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'navy', 'purple'];
context.lineWidth = 10;
context.transform(1, 0 , 0 , 1, 100, 0);
for(var i=0; i < colors.length; i++){
context.transform(1, 0, 0, 1, 0, 10);
context.strokeStyle = colors[i];
context.beginPath();
context.arc(50, 100, 100, 0, Math.PI, true);
context.stroke();
}
}
4.4 圖形組合
使用上下文對象的globalCompositeOperation屬性能決定圖形的組合方式,使用方法以下:
context.globalCompositeOperation=type
type的值必須是下面幾種字符串之一:
- source-over(默認) 新建立的圖形覆蓋到原有圖形之上
- destination-over 表示原有圖形之下繪製新圖形
- source-in 新圖形與原有圖形作in運算,只顯示重疊部分,新舊圖形其餘部分變成透明
- destination-in 原有圖形與新圖形作in運算,只顯示原有圖形中與新圖形重疊部分,其餘部分透明
- source-out 新圖形與原有圖形作out運算,只顯示新圖形中與原有圖形不重疊部分,其餘部分透明
- destination-out 原有圖形和新圖形作out運算,只顯示原有圖形中與新圖形不重疊的部分,其餘部分透明
- source-atop 只繪製新圖形中與原有圖形重疊的部分與未被重疊覆蓋的原有圖形,新圖形的其餘部分透明
- destination-atop 只繪製原有圖形中被新圖形重疊的部分與新圖形的其餘部分,原有圖形中的其餘部門透明
- lighter 原有圖形與新圖形均繪製,重疊部分作加色處理
- xor 只繪製新圖形中與原有圖形不重疊的部分,重疊部分變成透明
- copy 只繪製新圖形,原有圖形中未與新圖形重疊的部分變成透明
若是指定的type不在這幾個字符串當中,則按默認方式組合圖形。
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
var oprtns = new Array(
"source-atop",
"source-in",
"source-out",
"source-over",
"destination-atop",
"destination-in",
"destination-out",
"destination-over",
"lighter",
"copy",
"xor"
);
i=8;
context.fillStyle = "blue";
context.fillRect(10, 10, 60, 60);
context.globalCompositeOperation = oprtns[i];
context.beginPath();
context.fillStyle = "red";
context.arc(60, 60, 30, 0, Math.PI*2, false);
context.fill();
}
4.5 給圖形繪製陰影
使用Canvas元素給添加陰影效果時,只需利用圖形上下文對象的幾個關於陰影繪製的屬性就能夠了,以下:
shadowOffsetX —— 陰影的橫向位移量
shadowOffsetY —— 陰影的縱向位移量
shadowColor —— 陰影的顏色
shadowBlur —— 陰影的模糊範圍
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
context.fillStyle = '#EEEEFF';
context.fillRect(0, 0, 400, 300);
//陰影參數
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.shadowColor = 'rgba(100, 100, 100, 0.5)';
context.shadowBlur = 7.5;
//繪製圖形
context.translate(0, 50);
for(var i=0; i < 3; i++){
context.translate(50, 50);
if(i == 2){
context.shadowColor = 'rgba(0, 0, 0, 0)';
}
create5Star(context);
context.fill();
}
}
shadowBlur屬性可選,它表示圖形陰影邊緣的模糊範圍。若是不但願陰影的邊緣太清晰,能夠設定該屬性值。可是必須大於0,不然會被忽略。通常設定在0至10之間。
若是不想每一個圖形具備陰影效果,能夠在繪製繪製的時候,設置shadowColor爲rgba(0, 0, 0, 0)。
4.6 使用圖像
4.6.1 繪製圖像
CanvasAPI不只能夠繪製圖形,還能夠讀取磁盤或網絡中的圖像文件,而後使用CanvasAPI將該圖像繪製在畫布中。
繪製圖像時,須要使用drawImage方法,定義以下:
- context.drawImage(image, x, y);
- context.drawImage(image, x, y, w, h);
- context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
第一個方法:image能夠是img元素、video元素或者JS中的Image對象,xy爲繪製該圖像在畫布中的起始座標
第二個方法: 前三個參數與上面的一致,w、h是指繪製圖像的寬度與高度
第三個方法: image和第一個方法同樣,sx、sy、sw、sh表示複製圖像的起點寬高,dx、dy、dw、dh表示複製到畫布的起點寬高,該方法能夠用於剪切圖像,或者縮放圖像。
由於設定好Image對象的src屬性後,不必定就馬上顯示圖像,因此建議:
image.onload = function(){繪製圖像函數}
在Image對象的onload事件中同步執行繪製圖像的函數,就能夠一邊裝載一邊繪製
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
context.fillStyle = '#EEEEFF';
context.fillRect(0, 0, 400, 300);
image = new Image();
image.src = 'lufu.jpg';
image.onload = function(){
drawImg(context, image);
}
}
function drawImg(context, image){
for(var i=0; i < 7; i++){
context.drawImage(image, 0 + i * 50, 0 + i * 25, 100, 100);
}
}
//######## 局部方法Demo
function drawImg(context, image){
var i = 0;
context.drawImage(image, 0, 0, 100, 100);
context.drawImage(image, 23, 5, 57, 80, 110, 0, 100, 100);
}
4.6.2 圖像平鋪
圖像平鋪有兩種方法,一種就是上面的drawImage:
function drawImg(canvas, context, image){
//平鋪比例
var scale = 2;
//縮小後圖像寬度
var n1 = image.width/scale;
var n2 = image.height/scale;
//平鋪橫向個數
var n3 = canvas.width/n1;
var n4 = canvas.width/n2;
for(var i=0; i < n3; i++)
for(var j=0; j < n4; j++)
context.drawImage(image, i*n1, j*n2, n1, n2);
}
可是該方法比較複雜,HTML 5提供了一個更簡便的方法,利用上下文對象的createPattern,以下:
context.createPattern(iamge, type);
image爲平鋪的圖像,type參數的值必須爲下面的字符串之一:
- no-repeat: 不平鋪
- repeat-x: 橫向平鋪
- repeat-y: 縱向平鋪
- repeat: 全方向平鋪
建立image對象並制定圖像文件以後,使用createPattern方法建立填充樣式,而後將該樣式制定給圖形上下文對象的fillStyle屬性。
var context = canvas.getContext('2d');
image = new Image();
image.src = 'pig.gif';
image.onload = function(){
var ptrn = context.createPattern(image, 'repeat');
//填充樣式
context.fillStyle = ptrn;
context.fillRect(0, 0, 400, 300);
}
4.6.2 圖像裁剪
Canvas API的圖像裁剪功能是指,在畫布內使用路徑,只繪製該路徑所包括區域內的圖像,不繪製路徑外部的圖像。首先建立好路徑,以後調用上下文的clip方法設置裁剪區域。
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
var gr = context.createLinearGradient(0, 400, 300, 0);
gr.addColorStop(0, 'rgb(255, 255, 0)');
gr.addColorStop(1, 'rgb(0, 255, 255)');
context.fillStyle = gr;
context.fillRect(0, 0, 400, 300);
iamge = new Image();
image.onload = function(){
drawImg(context, image);
}
image.src = 'lufu.jpg';
function drawImg(context, image){
create5StarClip(context);
context.drawImage(image, -50, -150, 300, 300);
}
function create5StarClip(context){
var n = 0;
var dx = 100;
var dy = 0;
var s = 150;
//建立路徑
context.beginPath();
context.translate(100, 150);
var x = Math.sin(0);
var y = Math.cos(0);
var dig = Math.PI/5 * 4;
for(var i=0; i < 5; i++){
var x = Math.sin(i * dig);
var y = Math.cos(i * dig);
context.lineTo(dx + x * s, dy + y * s);
}
context.clip();
}
裁剪區域一旦設置好以後,後面繪製的全部圖片就均可以使用這個裁剪區域,若是須要取消裁剪區域,那就須要使用繪製狀態的保存與恢復功能。這兩個功能保存與恢復圖形上下文的臨時狀態。在設置圖像裁剪區域時,首先調用save方法保存圖像上下文的當前狀態,在繪製完通過裁剪的圖像後,在調用restore恢復以前保存的圖形上下文的狀態。
4.6.3 像素處理(chrome不支持,opera和FF支持)
使用Canvas API 可以獲取圖像中的每個像素,而後獲得該像素顏色的rgb值或rgba值。使用上下文的getImageData方法來獲取圖像中的像素,定義以下:
var imagedata = context.getImageData(sx, sy, sw, sh);
sx、sy、sw、sh分別指起點和寬高,imagedata變量是一個CanvasPixelArray對象,具備height,width,data等屬性。data屬性是一個保存像素數據的數組,內容相似「[r1,g1,b1,a1,r2,g2,b2,a2,r3,g3,b3,a3,....]」。
context.putImageData(imagedata, dx, dy[,dirtyX,dirtyY,dirtyWidth,dirtyHeight ]);
putImageData 能夠傳入3個或者7個參數,dx, dy 表示重繪圖像的起點橫座標,起點縱座標,dirtyX、Y.... 則爲起點的座標和寬高
function draw(id){
var canvas=document.getElementById(id);
if(canvas==null){
return false;
}
var context=canvas.getContext('2d');
image=new Image();
image.src="lufu.jpg";
image.onload=function(){
context.drawImage(image,0,0);
var imagedata=context.getImageData(0,0,image.width,image.height);
for(var i=0,n=imagedata.data.length;i<n;i+=4){
imagedata.data[i+0]=255-imagedata.data[i+0];
imagedata.data[i+1]=255-imagedata.data[i+2];
imagedata.data[i+2]=255-imagedata.data[i+1];
}
context.putImageData(imagedata, 0, 0);
//context.putImageData(imagedata,30,30,10, 10, 50, 50);
};
}
4.7 繪製文字
在HTML 5中,Canvas也能夠繪製文字,使用fillText方法或strokeText方法。fillText方法用填充方式繪製字符串,filleText(text, x, y, [maxWidth]);,第四個是可選參數,表示顯示文字是的最大寬度,防止文字溢出。
strokeText(text, x, y, [maxWidth]);用輪廓的方式繪製字符串。
在繪製以前,要對一些屬性進行設置:
- font屬性:設置文字字體
- textAlign屬性: 設置文字水平對齊方式,屬性值能夠爲start、end、left、right、center。默認值爲start
- textBaseline屬性:設置文字垂直對齊方式,屬性值能夠爲top、hanging、middle、alphabetic、ideographic、bottom。默認值爲alphabetic
meatureText方法能夠獲得文字的寬度, metrics = context.meatrueText(text)
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
context.fillStyle = '#00f';
context.font = 'italic 20px sans-serif';
var txt = '字符串的寬度爲';
var tm1 = context.measureText(txt);
context.fillText (txt, 10, 30);
context.fillText(tm1.width, tm1.width + 10, 30);
context.font = 'bold 30px sans-serif';
var tm2 = context.measureText(txt);
context.fillText (txt, 10, 30);
context.fillText(tm2.width, tm2.width + 10, 30);
}
4.8 繪製文字
4.8.1 save和restore
以前提過若是裁剪樣式定了以後,以後都會居於裁剪樣式進行繪圖,可是以後可能不要,那麼能夠採用save當前在狀態,而後繪製了裁剪圖片以後,能夠restore回來。
var x, y;
for(var j=1; j < 50; j++){
ctx.save();
ctx.fillStyle = '#fff';
x = 75 - Math.floor(Math.random() * 150);
y = 75 - Math.floor(Math.random() * 150);
ctx.translate(x, y);
drawStar(ctx, Math.floor(Math.random() * 4) + 2);
ctx.restore();
}
4.8.2 保存文件
Canvas API也提供了保存文件的功能,Canvas API保存文件的原理其實是把當前的繪畫狀態輸出到一個data URL地址所指向的數據中的過程,所謂data URL,是指目前大多數瀏覽器可以識別的一種base64位編碼的URL,主要用於小型的、能夠在網頁中直接嵌入,而不須要從外部文件嵌入的數據,譬如img元素中的圖像文件等。
Canvas API 使用toDataURL方法把繪畫狀態輸出到一個data URL中,而後從新裝載,客戶可直接把裝載後的文件進行保存。
canvas.toDataURL(type); 該方法使用一個參數type,表示要輸出數據的MIME類型。
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
var context = canvas.getContext('2d');
context.fillStyle = 'rgb(0, 0, 255)';
context.fillRect(0, 0, 400, 300);
context.fillStyle = 'rgb(255, 255, 0)';
context.fillRect(10, 20, 50, 50);
window.location = canvas.toDataURL('image/jpeg');
}
4.8.2 簡單動畫製做
實際上就是不斷擦除、重繪、擦除、重繪的過程,具體步驟以下:
預先編寫好用來繪圖的函數,在該函數中先用clearRect方法將畫布總體或局部擦除。
使用setInterval方法設置動畫的間隔時間
var context;
var width, height;
var i;
function draw(id){
var canvas = document.getElementById(id);
if(canvas == null)
return false;
//
if(!!!canvas.getContext){
alert("抱歉,你的瀏覽器不支持canvas!!");
return false;
}
context = canvas.getContext('2d');
width = canvas.width;
height = canvas.height;
i=0;
setInterval(rorate, 100);
}
function rorate(){
context.clearRect(0, 0, width, height);
context.fillStyle = 'red';
context.fillRect(i, 0, 20, 20);
i = i + 20;
if(i == 400){
i = 0;
}
}
4、多媒體播放
HTML 5提供了兩個新元素 —— video元素與audio元素,其中video元素專門用來播放網絡上的視頻或電影,而audio元素專門用來播放網絡上的音頻數據。
PS: 記得加controls="controls",否則不顯示播放控件,默認不會自動播放歌曲
另外,能夠經過source元素來爲同一個媒體數據指定多個播放格式與編碼格式,以確保瀏覽器能夠從中選擇一種本身支持的播放格式進行播放,瀏覽器的選擇順序爲代碼中的書寫順序,它會從上往下判斷本身對該播放格式是否支持。
<video controls="controls">
<source src="sample.ogv" type="video/ogg; codecs='theora, vorbis'">
<source src="sample.mov" type="video/quicktime">
</video>
type表示媒體類型,其屬性值爲播放文件的MIME類型,該屬性中的codecs參數表示所使用的媒體的編碼格式。
一、屬性
- src 指定媒體數據的URL地址
- autoplay 指定媒體是否在頁面加載後自動播放(IOS不支持),<video src="ddd.mov" autoplay></video>
- preload 指定視頻或音頻數據是否預加載。該屬性有三個可選擇的值,none、metadata與auto,默認值爲auto
-
- none表示不行預加載
- metadata表示只預加載媒體的元數據(媒體字節數,第一幀,播放列表、持續時間等)。
- auto表示預加載所有視頻或音頻
- poster(video獨有) 當視頻不可用時,可使用該元素向用戶展現一幅替代圖片,<video src="ddd.mov" poster="cannotuse.jpg"></video>
- loop 指定是否循環播放
- controls 指定是否爲視頻或音頻添加瀏覽器自帶的播放用的控制條 <video src="sample.mov" controls></video>,固然也能夠自定義
- width與height(video獨有)
- error屬性 若是在媒體播放出問題時,error屬性將返回一個MediaError對象,該對象的code返回對應的錯誤狀態,錯誤狀態共有4個值:
-
- MEDIA_ERR_ABORTED(數字值爲1): 下載過程因爲用戶的操做緣由而被終止
- MEDIA_ERR_NETWORK(數字值2):確認資源可用,可是在下載時出現網絡錯誤,下載過程被終止
- MEDIA_ERR_DECODE(數字值3):確認資源可用,解碼時發生錯誤
- MEDIA_ERR_SRC_NOT_SUPPORTED(數字值4):媒體資源不可用媒體格式不被支持
error屬性爲只讀屬性
var video = document.getElementById("videoElement");
video.addEventListener("error", function(){
var error = video.error;
...
}
- networkState屬性 在媒體數據加載過程當中可使用video元素或audio元素的networkState屬性讀取當前網絡狀態,共有4個值:
-
- NETWORK_EMPTY(數字值爲0):元素處於初始狀態
- NETWORK_IDLE(數字值1):瀏覽器已選擇好用什麼編碼格式來播放媒體,但還沒有創建網絡鏈接
- NETWORK_LOADING(數字值2):媒體加載中
- NETWORK_NO_SOURCE(數字值爲3):沒有支持的編碼格式
var video = document.getElementById("videoElement");
video.addEventListener("progress", function(e){
var networkStateDisplay = document.getElementById("networkState");
if(video.networkState == 2){
//
}
.....
}
- currentSrc屬性 讀取URL地址: video/audio.currentSrc
- buffered屬性 可使用video元素或audio元素的buffered屬性來返回一個對象,該對象實現TimeRanges接口,以確認瀏覽器是否已緩存媒體數據。
- readyState屬性 返回媒體當前播放位置的就緒狀態,共5個值:
-
- HAVE_NOTHING(數字值爲0):沒有獲取到媒體的任何信息,當前播放位置沒有可播放數據
- HAVE_METADATA(數字值爲1):獲取到的媒體數據無效,不能播放
- HAVE_CURRENT_DATA(數字值爲2):當前媒體位置已經有數據能夠播放,但沒有獲取到可讓播放器前進的數據。
- HAVE_FUTURE_DATA(數字值爲3):當前媒體位置已經有數據能夠播放,獲取到可讓播放器前進的數據。
- HAVE_ENOUGH_DATA(數字值爲4):當前媒體位置已經有數據能夠播放,獲取到可讓播放器前進的數據,並且加載速度能夠確保媒體順利播放
- seeking屬性與seekable屬性 seeking屬性能夠返回一個布爾值,表示瀏覽器是否正在請求某一個特定播放位置的數據,seekable屬性返回一個TimeRanges對象,
- currentTime屬性、startTime屬性與duration屬性 currentTime當前播放位置,能夠經過修改currentTime屬性來修改當前播放位置。startTime開始時間,一般爲0。duration總的播放時間
- played屬性、paused屬性、ended屬性
- defaultPlaybackRate屬性與playbackRate屬性 播放速率
- volume屬性與muted屬性 播放音量,0到1,1爲最大,muted表示靜音狀態,布爾值。
二、方法
- play方法 將元素的paused屬性的值變爲false
- pause方法 使用pause方法來暫停播放,自動將元素的paused屬性的值變爲true
- load方法 使用load方法來從新載入媒體進行播放
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>video first Demo #######</title>
<script>
var video;
function init(){
video = document.getElementById("video1");
video.addEventListener("ended", function(){
alert("播放結束");
}, true);
video.addEventListener("error", function(){
switch(video.error.code){
case MediaError.MEDIA_ERROR_ABORTED:
alert("視頻的下載過程被停止");
break;
case MediaError.MEDIA_ERROR_NETWORK:
alert("網絡發生故障,視頻的下載過程被停止");
break;
case MediaError.MEDIA_ERROR_DECODE:
alert("解碼失敗");
break;
case MediaError.MEDIA_ERROR_SRC_NOT_SUPPORTED:
alert("不支持的視頻播放格式");
break;
default:
alert("未知錯誤");
}
}, false);
}
function play(){
video.play();
}
function pause(){
video.pause();
}
function next(){
if(video.src.indexOf("ren") > 0){
video.src = "KW7142.mp4";
}else{
video.src = "chonglangnanren.mp4";
}
}
</script>
</head>
<body onload="init()">
<video src="chonglangnanren.mp4" width="320" height="240" id="video1">
Your browser does not support the vedio element.
</video><br/>
<button onclick="play();">播放</button>
<button onclick="pause();">暫停</button>
<button onclick="next();">下一首</button>
</body>
</html>
- canPlayType 測試瀏覽器是否支持指定的媒體類型
var support = videoElement.canPlayType(type);
type值是MIME類型,與source元素的type參數同樣,該方法返回3個可能值:空字符,表示瀏覽器不支持;maybe,表示瀏覽器可能支持;probably,表示瀏覽器肯定該類型。
PS:addEventListener,若是capture,兩個嵌套元素同一個事件發生從外元素開始觸發,若是bubbing,則內元素開始觸發
三、事件
3.1 事件介紹
- loadstart 瀏覽器開始在網上尋找媒體數據
- progress 瀏覽器正在獲取媒體數據
- suspend 瀏覽器暫停獲取媒體數據,可是下載過程並無結束
- abort 瀏覽器在下載徹底部媒體數據以前停止獲取媒體數據,可是並非有錯誤引發
- error 獲取媒體數據過程當中出錯
- emptied video元素或audio元素所在網絡忽然變爲未初始化狀態,可能的緣由有兩個:
-
- 載入媒體過程當中忽然發生一個致命錯誤
- 在瀏覽器正在選擇支持的播放格式時,又調用了load方法從新載入媒體
- stalled 瀏覽器嘗試獲取媒體數據失敗
- play 即將開始播放,當執行了play方法時觸發,或數據下載後元素被設爲autoplay屬性
- pause 播放暫停,當執行了pause方法時觸發
loadedmetadata 瀏覽器獲取完畢媒體的時間長和字節數
loadeddata 瀏覽器加載完畢當前播放位置的媒體數據,準備播放
waiting 播放過程猶豫的得不到下一幀而暫停播放,但很快就可以獲得下一幀
playing 正在播放
canplay 瀏覽器可以播放媒體,但估計以當前播放速率不能直接將媒體播放完畢
canplaythrough 瀏覽器可以播放媒體,當前播放速率能直接將媒體播放完畢
seeking seeking屬性變爲true,瀏覽器正在請求數據
seeked seeking屬性變爲false,瀏覽器中止請求數據
timeupdate 當前播放位置被改變,多是播放過程當中的天然改變,也多是被認爲地改變,或因爲播放不能連續而發生的跳變
ended 播放結束後中止播放
ratechange defaultplaybackRate屬性或playbackRate屬性被改變
durationchange 播放時長被改變
volumechange volume屬性被改變或muted屬性被改變
5、本地存儲
一、WebStorage
webstorage 分sessionStorage和localstorage,sessionStorage是臨時保存,localStorage是永久保存。sessionStorage若是瀏覽器關閉了,數據就沒有了,而localStorage則不會。基本使用方法:
sessionStorage:
保存數據 sessionStorage.setItem(key, value);
讀取數據 sessionStorage.getItem(key);
localStorage:
保存數據 localStorage.setItem(key, value);
讀取數據 localStorage.getItem(key);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Web Storage示例</title>
<script type="text/javascript" src="webStorage.js"></script>
</head>
<body>
<h1>Web Storage 示例</h1>
<p id="msg"></p>
<input type="text" id="input">
<button onclick="saveStorage('input');">保存數據</button>
<button onclick="loadStorage('msg');">讀取數據</button>
</body>
</html>
function saveStorage(id){
var target = document.getElementById(id);
var str = target.value;
sessionStorage.setItem("message", str);
}
function loadStorage(id){
var target = document.getElementById(id);
var msg = sessionStorage.getItem("message");
target.innerHTML = msg;
}
若是使用得好,也可將webStorage做爲一個簡易的數據庫,鍵的值採用JSON字符串就能夠。固然這只是能夠實現,運用的時候,webStorage的空間仍是很珍貴的,通常大多數瀏覽器都只提供5M左右的空間。
2、本地數據庫
HTML 5的本地數據庫就是「SQLLite」文件型的SQL數據庫,首先使用openDatabase方法來建立一個訪問數據庫的對象。該方法的使用以下:
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
第一個參數是數據庫名稱,第二個參數爲版本號,第三個參數爲數據庫的描述,第四個參數爲數據庫的大小。該方法返回建立後的數據庫訪問對象,若是該數據庫不存在,則建立該數據庫。實際訪問數據庫的時候,還須要調用transaction方法,用來執行事務處理,防止在對數據庫操做的時候受外界打擾,組織別的用戶操做數據庫。
db.transaction(function (tx){
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS(id unique, Log)');
});
transaction使用一個回調函數爲參數,這個函數中,執行訪問數據庫的語句。函數裏面tx其實就是SQLTransaction(事務),這個事務只有一個
executeSql方法。
executeSql(sqlQuery, [], dataHandler, errorHandler);
第一個參數是執行的語句,第二個是執行語句裏面的參數,dataHandler成功執行返回處理,包含兩個參數tx,rs(結果集),errorHandler也包含兩個參數tx,error(錯誤信息)。
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE> HTML 5 SQLLite </TITLE>
<META charset="utf-8">
<SCRIPT type="text/javascript" src="webDB.js"></SCRIPT>
</HEAD>
<BODY onload="init();">
<h1>使用數據庫實現web留言板</h1>
<table>
<tr><td>姓名:</td><td><input type="text" id="name"/></td></tr>
<tr><td>留言:</td><td><input type="text" id="memo"/></td></tr>
<tr><td colspan="2"><button onclick="saveData();">保存</button></td></tr>
</table>
<!--建立一條水平線。 水平分隔線-->
<hr/>
<table id="datatable" border="1"></table>
<p id="msg"></p>
<button onclick="deleteAllData();">刪除全部數據</button>
</BODY>
</HTML>
JS:
var datatable = null;
var db = openDatabase("MyData", "", "My Database", 1024 * 1024);
function init(){
datatable = document.getElementById("datatable");
showAllData();
}
function removeAllData(){
for(var i=datatable.childNodes.length - 1; i>=0; i--){
datatable.removeChild(datatable.childNodes[i]);
}
var tr = document.createElement('tr');
var th1 = document.createElement('th');
var th2 = document.createElement('th');
var th3 = document.createElement('th');
th1.innerHTML = '姓名';
th2.innerHTML = '留言';
th3.innerHTML = '時間';
tr.appendChild(th1);
tr.appendChild(th2);
tr.appendChild(th3);
datatable.appendChild(tr);
}
function showData(row){
var tr = document.createElement('tr');
var td1 = document.createElement('td');
td1.innerHTML = row.name;
var td2 = document.createElement('td');
td2.innerHTML = row.message;
var td3 = document.createElement('td');
var t = new Date();
td3.innerHTML = t.toLocaleDateString() + " " + t.toLocaleTimeString();
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
datatable.appendChild(tr);
}
function showAllData(){
db.transaction(function(tx){
tx.executeSql("CREATE TABLE IF NOT EXISTS MsgData(name TEXT, message TEXT, time INTEGER)", []);
tx.executeSql("SELECT * FROM MsgData", [], function(tx, rs){
removeAllData();
for(var i=0; i < rs.rows.length; i++){
showData(rs.rows.item(i));
}
});
});
}
function addData(name, message, time){
db.transaction(function(tx){
tx.executeSql('INSERT INTO MsgData VALUES(?, ?, ?)'
, [name, message, time], function(tx, rs){
alert("保存數據成功!!");
}, function(tx, error){
alert(error.source + "::" + error.message);
}
);
});
}
function saveData(){
var name = document.getElementById("name").value;
var memo = document.getElementById("memo").value;
var time = new Date().getTime();
addData(name, memo, time);
showAllData();
}
function deleteAllData(){
db.transaction(function(tx){
tx.executeSql('DELETE FROM MsgData'
, [], function(tx, rs){
alert("刪除數據成功!!");
}, function(tx, error){
alert(error.source + "::" + error.message);
}
);
});
showAllData();
}
另外,在chrome裏面Web Storage能夠經過清理緩存什麼的清除,可是SQLLite不能夠,也不可使用「drop database dbName」語句清除數據庫,由於SQLLite歸根結底只是一個嵌入的數據庫,是一個文件,要到Chrome/User Data裏面去刪除文件。
6、離線Web應用
HTML 5提供了本地緩存,能夠Web應用離線的狀況下依然可使用。
Web應用程序的本地緩存是經過每一個頁面的manifest文件來管理的。manifest文件是一個簡單文本文件,在該文件以清單的形式列舉須要緩存和不須要緩存的資源文件的名字,以及這些資源文件的訪問路徑。能夠爲每一個頁面指定一個manifest文件,也能夠爲整個應用指定一個manifest文件。
CACHE MANIFEST
#文件的開頭必需要書寫CACHE MANIFEST
#這個manifest文件的版本號
#version 7
CACHE:
other.html
hello.js
images/myphoto.jpg
NETWORK:
http://localhost/NotOffline
NotOffline.php
*
FALLBACK:
online.js locale.js
CACHE:
newhello.html
newhello.js
在manifest文件中,第一行必須是「CACHE MANIFEST」文字,以把本文件的做用告知給瀏覽器。同時,真正運行或測試離線Web應用程序的時候,
須要對服務器進行配置,讓服務器支持text/cache-manifest這個MIME類型(text/cache-manifest)。例如Apache服務器進行配置的時候,須要找到{apache_home}/conf/mine.types這個文件,並在文件最後添加一行代碼:
text/cache-manifest manifest
而在tomcat裏面的配置則以下:
在 tomcat根目錄 -> conf -> web.xml 中的<web-app>內添加html5
<
extension
>manifest</
extension
>
<
mime-type
>text/cache-manifest</
mime-type
>
</
mime-mapping
>
在指定資源文件的時候,能夠把資源文件分爲三類:分別是CACHE、NETWORK、FALLBACK。在CHACHE類別中指定須要被緩存在本地的資源文件。NETWORK類別爲顯示指定不進行本地緩存的資源文件。「*」爲通配符,表示沒有在本manifest文件中指定的資源文件都不進行本地緩存。FALLBACK類別中的每行中指定兩個資源文件,第一個資源文件爲可以在線訪問時使用的文件,第二個爲爲不能聯網時使用的資源文件。
容許在同一個manifest文件中重複書寫同一個類別。
爲了讓瀏覽器可以正常閱讀該文本文件,須要在Web應用程序頁面上的html標籤的manifest屬性由指定manifest文件的URL地址。指定方法以下:
<html manifest="hello.manifest">
...
</html>
瀏覽器在與服務器交互時,會檢查manifest文件是否更改,若是更改,則會根據manifest的要求把資源文件緩存。緩存以後,會觸發applicationCache
對象的updateready事件:
applicationCache.addEventListener( "updateready",function(){
alert("本地緩存已經更新,請刷新頁面查看最新應用!");
});
PS:
資源文件修改了,若是manifest文件沒有修改,緩存頁面是不會更新的,也就是用戶不會看到最新的應用,若是你對緩存的要求沒有修改,那麼能夠經過
修改manifest文件的version版本號來提示瀏覽器更新緩存
另外能夠經過applicationCache對象的swapCache手工執行本地緩存的更新,它只能在applicationCache對象的updateReady事件被觸發時調用。
updateReady就是服務器manifest有更新,而且已經把緩存的文件都已經下載到本地了。以後就能夠執行swapCache更新。這樣就能夠控制頁面是否當即更新緩存,由於可能用戶正在作一些重要的操做,不想當即更新緩存。可使用confirm方法讓用戶選擇更新的時機。
applicationCache.addEventListener(
"updateready",function(){
alert("正在更新本地緩存,請稍等....");
applicationCache.swapCache();
alert("本地緩存已被更新,您能夠刷新頁面來獲得本程序的最新版本");
});
applicationCache對象的另外一個方法applicationCache.update,該方法的做用是檢查服務器上的manifest文件是否有更新。
applicationCache除了一些方法以外固然也有一些事件監聽,
詳細。
7、通訊API
一、跨文檔消息傳輸
HTML 5提供了網頁文檔之間互相接受和發送消息的功能。接受消息的網頁須要作監聽:
window.addEventListener("message", function{...}, false);
發送消息的頁面傳輸消息的方法:
window.postMessage(message, targetOrigin);
targetOrigin爲接受消息的網頁URL地址
早期作過的一個
Demo,如文所述,IE8的監聽不是message,而是onmessage。
二、Web Sockets
Web Sockets是HTML 5提供的Web應用中客戶端和服務器端
非HTTP 的通訊機制。能夠實現HTTP不易實現的功能,好比消息推送。這個連接是雙向的,實時且永久的,除非顯示關閉。
var websocket = new WebSockets("ws://localhost:8080/socket");
將URL字符串做爲參數傳入,經過調用WebSockets對象的構造器實現與服務器端創建通訊。 URL字符串必須以「ws」或「wss」(加密通訊時)文字做爲開頭。
websocket.send(data);
經過send方法發送信息
websocket.onmessage = function(event){
var data = event.data;
...
}
經過onmessage屬性接收服務器傳來的信息
websocket.onopen = function(event){
//開統統信時處理
}
監聽socket打開事件
websocket.onclose = function(event){
//開統統信時處理
}
監聽socket關閉事件
websocket.close();
切斷通訊
另外能夠經過readyState的屬性值來獲取WebSocket對象的狀態:
CONNECTING(數值爲0):表示正在鏈接
OPEN(數字值爲1):表示已創建鏈接
CLOSING(數字值爲2):表示正在關閉
CLOSED(數字值爲3):表示已經關閉
<!DOCTYPE HTML>
<html>
<head>
<title>Web Socket Demo -- EchoClient</title>
<meta charset="utf-8">
</head>
<script type="text/javascript">
var websocket = null;
function connect(){
var msg = document.getElementById("msg");
try{
var readyState = new Array("正在鏈接", "已創建鏈接", "正在關閉鏈接"
, "已關閉鏈接");
var host = "ws://localhost:8000";
websocket = new WebSocket(host);
websocket.onopen = function(){
msg.innerHTML += "<p>Socket狀態: " + readyState[websocket.readyState] + "</p>";
}
websocket.onmessage = function(event){
msg.innerHTML += "<p>接收信息: " + event.data + "</p>";
}
websocket.onclose = function(){
msg.innerHTML += "<p>Socket狀態: " + readyState[websocket.readyState] + "</p>";
}
msg = document.getElementById("msg");
msg.innerHTML += "<p>Socket狀態: " + readyState[websocket.readyState] + "</p>";
}catch(exception){
msg.innerHTML += "<p>有錯誤發生</p>";
}
}
function send(){
var msg = document.getElementById("msg");
var text = document.getElementById("text").value;
if(text == ""){
msg.innerHTML += "<p>請輸入一些文字</p>";
return;
}
try{
websocket.send(text);
msg.innerHTML += "<p>發送數據: " + text + "</p>";
}catch(exception){
msg.innerHTML += "<p>發送數據出錯</p>";
}
document.getElementById("text").value = "";
}
function disconnect(){
websocket.close();
}
</script>
<body>
<h1>WebSocket客戶端實例</h1>
<div id="msg" style="height: 300px;"></div>
<p>請輸入一些文字</p>
<input type="text" id="text"/>
<button id="connect" onclick="connect();">創建鏈接</button>
<button id="send" onclick="send();">發送數據</button>
<button id="disconnect" onclick="disconnect();">斷開鏈接</button>
</body>
</html>
服務端:
package socket;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.security.MessageDigest;
public class EchoServer {
private int port = 8000;
private ServerSocket serverSocket;
public EchoServer() throws IOException {
serverSocket = new ServerSocket(port);
System.out.println("服務器啓動");
}
private void service() {
Socket socket = null;
while (true) {
try {
socket = serverSocket.accept();
Thread workThread = new Thread(new Handler(socket));
workThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Handler implements Runnable {
private Socket socket;
private boolean hasHandshake = false;
Charset charset = Charset.forName("UTF-8");
public Handler(Socket socket) {
this.socket = socket;
}
private PrintWriter getWriter(Socket socket) throws IOException {
OutputStream socketOut = socket.getOutputStream();
return new PrintWriter(socketOut, true);
}
public String echo(String msg) {
return "echo:" + msg;
}
public void run() {
try {
System.out.println("New connection accepted"
+ socket.getInetAddress() + ":" + socket.getPort());
InputStream in = socket.getInputStream();
PrintWriter pw = getWriter(socket);
//讀入緩存
byte[] buf = new byte[1024];
//讀到字節
int len = in.read(buf, 0, 1024);
//讀到字節數組
byte[] res = new byte[len];
System.arraycopy(buf, 0, res, 0, len);
String key = new String(res);
if(!hasHandshake && key.indexOf("Key") > 0){
key = key.substring(0, key.indexOf("==") + 2);
key = key.substring(key.indexOf("Key") + 4, key.length()).trim();
key+= "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(key.getBytes("utf-8"), 0, key.length());
byte[] sha1Hash = md.digest();
sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
key = encoder.encode(sha1Hash);
pw.println("HTTP/1.1 101 Switching Protocols");
pw.println("Upgrade: websocket");
pw.println("Connection: Upgrade");
pw.println("Sec-WebSocket-Accept: " + key);
pw.println();
pw.flush();
hasHandshake = true;
//接收數據
byte[] first = new byte[1];
int read = in.read(first, 0, 1);
while(read > 0){
int b = first[0] & 0xFF;
//boolean fin = (b & 0x80) > 0;
// int rsv = (b & 0x70) >>> 4;
byte opCode = (byte) (b & 0x0F);
if(opCode == 8){
socket.getOutputStream().close();
break;
}
b = in.read();
// Client data must be masked
if ((b & 0x80) == 0) {
//NO-DO
}
int payloadLength = b & 0x7F;
if (payloadLength == 126) {
byte[] extended = new byte[2];
in.read(extended, 0, 2);
int shift = 0;
payloadLength = 0;
for (int i = extended.length - 1; i >= 0; i--) {
payloadLength = payloadLength + ((extended[i] & 0xFF) << shift);
shift += 8;
}
} else if (payloadLength == 127) {
byte[] extended = new byte[8];
in.read(extended, 0, 8);
int shift = 0;
payloadLength = 0;
for (int i = extended.length - 1; i >= 0; i--) {
payloadLength = payloadLength + ((extended[i] & 0xFF) << shift);
shift += 8;
}
}
//掩碼
byte[] mask = new byte[4];
in.read(mask, 0, 4);
int readThisFragment = 1;
ByteBuffer byteBuf = ByteBuffer.allocate(payloadLength + 10);
byteBuf.put("echo: ".getBytes("UTF-8"));
while(payloadLength > 0){
int masked = in.read();
masked = masked ^ (mask[(int) ((readThisFragment - 1) % 4)] & 0xFF);
byteBuf.put((byte) masked);
payloadLength--;
readThisFragment++;
}
byteBuf.flip();
responseClient(byteBuf, true);
printRes(byteBuf.array());
in.read(first, 0, 1);
}
}
in.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 方法說明:
* @開發:linrb
* @建立時間:2012-8-14
* @param byteBuf
* @throws IOException
*/
private void responseClient(ByteBuffer byteBuf, boolean finalFragment) throws IOException {
OutputStream out = socket.getOutputStream();
int first = 0x00;
//是不是輸出最後的WebSocket響應片斷,默認
if (finalFragment) {
first = first + 0x80;
first = first + 0x1;
}
out.write(first);
if (byteBuf.limit() < 126) {
out.write(byteBuf.limit());
} else if (byteBuf.limit() < 65536) {
out.write(126);
out.write(byteBuf.limit() >>> 8);
out.write(byteBuf.limit() & 0xFF);
} else {
// Will never be more than 2^31-1
out.write(127);
out.write(0);
out.write(0);
out.write(0);
out.write(0);
out.write(byteBuf.limit() >>> 24);
out.write(byteBuf.limit() >>> 16);
out.write(byteBuf.limit() >>> 8);
out.write(byteBuf.limit() & 0xFF);
}
// Write the content
out.write(byteBuf.array(), 0, byteBuf.limit());
out.flush();
}
/**
* 方法說明:
* @開發:linrb
* @建立時間:2012-8-14
* @param array
*/
private void printRes(byte[] array) {
ByteArrayInputStream byteIn = new ByteArrayInputStream(array);
InputStreamReader reader = new InputStreamReader(byteIn, charset.newDecoder());
int b = 0;
String res = "";
try {
while((b = reader.read()) > 0){
res += (char)b;
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(res);
}
}
public static void main(String[] args) throws IOException {
new EchoServer().service();
}
}
8、Web Workers
Web Worker是HTML 5提供的一種後臺線程,線程下面能夠有子線程。可是線程不能調用document和頁面的元素。可是,頁面交互其實可讓前臺處理。而且先後能夠進行數據交互。這樣能夠避免,猶豫前臺JS處理時間過長致使頁面奔潰。
一、數據交互
建立對象:
var worker = new Worker("腳本路徑");
能夠在前臺裏面持有worker對象,而後經過:
worker.onmessage = function(event){
//處理後臺線程傳過來的數據
}
worker.postMessage(message);
進行數據交互,固然若是要傳對象的話,把對象經過JSON對象的stringify方法轉成文本傳入就行。後臺的js腳本里面也經過調用onmessage 和 postMessage與前臺交互。
<!DOCTYPE HTML>
<html>
<head>
<title>Worker Demo 1 ###1</title>
<meta charset="utf-8">
</head>
<script type="text/javascript">
var worker = new Worker("js/SumCalculate.js");
worker.onmessage = function(event){
alert("結果爲:" + event.data);
}
function calculate(){
var val = document.getElementById("inputVal").value;
if(val != null && !isNaN(val) && parseInt(val) > 1){
worker.postMessage(parseInt(val));
}else{
alert("請輸入大於1的整數!!");
}
}
</script>
<body>
<hgroup>
<h1>Worker Demo 1</h1>
<h2>運算1到輸入指定數字遞增數列的值</h2>
</hgroup>
<section>
<input type="text" id="inputVal" placeholder="請輸入大於1的整數"/>
<button onclick="calculate();">提交</button>
</section>
</body>
</html>
JS:
onmessage = function(event){
var data = event.data;
var result = 0;
for(var i=0; i <= data; i++){
result += i;
}
postMessage(result);
}
PS: Chrome須要服務器才能運行,Opera和FF則不用
固然也可使用線程嵌套,主線程下面建立子線程。只是
Chrome,WebKit內核的目前不支持,線程下面建立子線程。
二、線程可用變量、函數與類
2.1 self
self關鍵詞用來表示本線程範圍內的做用域
2.2 postMessage(message)
向線程的源窗口發送消息
2.3 onmessage
獲取接受消息的事件句柄
2.4 importScripts(url)
導入其餘JavaScript腳本文件,需保證同域同端口。
2.5 navigator對象
與window.navigator對象相似,具備appName、platform、userAgent、appVersion這些屬性。
2.6 sessionStorage/localStorage
能夠在線程中使用Web Storage
2.7 XMLHttpRequest
能夠在線程中處理Ajax請求
2.8 setTimeout()/setInterval()
能夠在線程中實現定時處理
2.9 close
能夠結束本線程
2.10 eval()、isNaN()、escape()等
可使用全部JS核心函數
2.11 object
能夠建立和使用本地對象
2.12 WebSocket
可使用WebSocket API來想服務器發送和接受信息
9、Geolocation API
PS: 這章不怎麼詳記,限制比較多,使用起來諸多問題
在HTML 5中,提供了Geolocation API,不過經過《HTML 5 揭祕》這本書瞭解到。獲取地理位置,PC主要是經過你使用的運營商分給的IP地址,手機是經過信號基站和GPS,另外
PC獲取地址仍是得須要用戶受權。HHTML 5 中,爲window.navigator對象新增了一個geolocation屬性,可使用Geolocation API來對該屬性進行訪問。
一、取得當前位置
navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
第一個參數爲獲取當前位置信息成功時所執行的回調函數,第二個是失敗的回調函數,第三個是可選屬性的列表,第2、三個參數是可選的。可選屬性有(列舉部分):
- enableHighAccuracy: 是否要求高級毒的地理位置(不少設備沒有)
- timeout: 獲取地址超時限制
- maximumage: 獲取地理信息進行緩存下來的有效時間
二、持續監視
navigator.geolocation.watchCurrentPosition(onSuccess, onError, options);
該方法有點相似JS的setInterval方法,能夠經過clearWatch方法中止當前位置監視。
demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5 Geolocation</title>
<style>
body {background-color:#fff;}
</style>
</head>
<body>
<p id="geo_loc"><p>
<script>
function getElem(id) {
return typeof id === 'string' ? document.getElementById(id) : id;
}
function show_it(lat, lon) {
var str = '您當前的位置,緯度:' + lat + ',經度:' + lon;
getElem('geo_loc').innerHTML = str;
}
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
show_it(position.coords.latitude, position.coords.longitude);
}, function(err) {
getElem('geo_loc').innerHTML = err.code + "\n" + err.message;
});
} else {
getElem('geo_loc').innerHTML = "您當前使用的瀏覽器不支持Geolocation服務";
}
</script>
</body>
</html>
google Map:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>HTML5 Geolocation</title> <style> body {background-color:#fff;} </style> </head> <body> <p id="map_canvas"><p> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script> function getElem(id) { return typeof id === 'string' ? document.getElementById(id) : id; } function success(position) { var mapcanvas = document.createElement('div'); mapcanvas.id = 'mapcanvas'; mapcanvas.style.height = '400px'; mapcanvas.style.width = '560px'; getElem("map_canvas").appendChild(mapcanvas); var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); var myOptions = { zoom: 15, center: latlng, mapTypeControl: false, navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL}, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions); var marker = new google.maps.Marker({ position: latlng, map: map, title:"你在這裏!" }); } if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(success); } else { alert("您當前使用的瀏覽器不支持geolocation服務"); } </script> </body> </html>