為了更好地為移動設備服務,HTML 5推出了一系列針對移動設備的API。
[TOC]
## Viewport
Viewport指的是網頁的顯示區域,也就是不借助滾動條的情況下,用戶可以看到的部分網頁大小,中文譯為“視口”。正常情況下,viewport和瀏覽器的顯示窗口是一樣大小的。但是,在移動設備上,兩者可能不是一樣大小。
比如,手機瀏覽器的窗口寬度可能是640像素,這時viewport寬度就是640像素,但是網頁寬度有950像素,正常情況下,瀏覽器會提供橫向滾動條,讓用戶查看窗口容納不下的310個像素。另一種方法則是,將viewport設成950像素,也就是說,瀏覽器的顯示寬度還是640像素,但是網頁的顯示區域達到950像素,整個網頁縮小了,在瀏覽器中可以看清楚全貌。這樣一來,手機瀏覽器就可以看到網頁在桌面瀏覽器上的顯示效果。
viewport縮放規則,需要在HTML網頁的head部分指定。
~~~
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
</head>
~~~
上面代碼指定,viewport的縮放規則是,縮放到當前設備的屏幕寬度(device-width),初始縮放比例(initial-scale)為1倍,禁止用戶縮放(user-scalable)。
viewport 全部屬性如下。
* width: viewport寬度
* height: viewport高度
* initial-scale: 初始縮放比例
* maximum-scale: 最大縮放比例
* minimum-scale: 最小縮放比例
* user-scalable: 是否允許用戶縮放
其他的例子如下。
~~~
<meta name = "viewport" content = "width = 320,
initial-scale = 2.3, user-scalable = no">
~~~
## Geolocation API
Geolocation接口用于獲取用戶的地理位置。它使用的方法基于GPS或者其他機制(比如IP地址、Wifi熱點、手機基站等)。
下面的方法,可以檢查瀏覽器是否支持這個接口。
~~~
if(navigator.geolocation) {
// 支持
} else {
// 不支持
}
~~~
這個API的支持情況非常好,所有瀏覽器都支持(包括IE 9+),所以上面的代碼不是很必要。
### getCurrentPosition方法
getCurrentPosition方法,用來獲取用戶的地理位置。使用它需要得到用戶的授權,瀏覽器會跳出一個對話框,詢問用戶是否許可當前頁面獲取他的地理位置。必須考慮兩種情況的回調函數:一種是同意授權,另一種是拒絕授權。如果用戶拒絕授權,會拋出一個錯誤。
~~~
navigator.geolocation.getCurrentPosition(geoSuccess,geoError);
~~~
上面代碼指定了處理當前地理位置的兩個回調函數。
(1)同意授權
如果用戶同意授權,就會調用geoSuccess。
~~~
function geoSuccess(event) {
console.log(event.coords.latitude + ', ' + event.coords.longitude);
}
~~~
geoSuccess的參數是一個event對象。event有兩個屬性:timestamp和coords。timestamp屬性是一個時間戳,返回獲得位置信息的具體時間。coords屬性指向一個對象,包含了用戶的位置信息,主要是以下幾個值:
* coords.latitude:緯度
* coords.longitude:經度
* coords.accuracy:精度
* coords.altitude:海拔
* coords.altitudeAccuracy:海拔精度(單位:米)
* coords.heading:以360度表示的方向
* coords.speed:每秒的速度(單位:米)
大多數桌面瀏覽器不提供上面列表的后四個值。
(2)拒絕授權
如果用戶拒絕授權,就會調用getCurrentPosition方法指定的第二個回調函數geoError。
~~~
function geoError(event) {
console.log("Error code " + event.code + ". " + event.message);
}
~~~
geoError的參數也是一個event對象。event.code屬性表示錯誤類型,有四個值:
* 0:未知錯誤,瀏覽器沒有提示出錯的原因,相當于常量event.UNKNOWN_ERROR。
* 1:用戶拒絕授權,相當于常量event.PERMISSION_DENIED。
* 2:沒有得到位置,GPS或其他定位機制無法定位,相當于常量event.POSITION_UNAVAILABLE。
* 3:超時,GPS沒有在指定時間內返回結果,相當于常量event.TIMEOUT。
(3)設置定位行為
getCurrentPosition方法還可以接受一個對象作為第三個參數,用來設置定位行為。
~~~
var option = {
enableHighAccuracy : true,
timeout : Infinity,
maximumAge : 0
};
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, option);
~~~
這個參數對象有三個成員:
* enableHighAccuracy:如果設為true,就要求客戶端提供更精確的位置信息,這會導致更長的定位時間和更大的耗電,默認設為false。
* Timeout:等待客戶端做出回應的最大毫秒數,默認值為Infinity(無限)。
* maximumAge:客戶端可以使用緩存數據的最大毫秒數。如果設為0,客戶端不讀取緩存;如果設為infinity,客戶端只讀取緩存。
### watchPosition方法和clearWatch方法
watchPosition方法可以用來監聽用戶位置的持續改變,使用方法與getCurrentPosition方法一樣。
~~~
var watchID = navigator.geolocation.watchPosition(geoSuccess,geoError, option);
~~~
一旦用戶位置發生變化,就會調用回調函數geoSuccess。這個回調函數的事件對象,也包含timestamp和coords屬性。
watchPosition和getCurrentPosition方法的不同之處在于,前者返回一個表示符,后者什么都不返回。watchPosition方法返回的標識符,用于供clearWatch方法取消監聽。
~~~
navigator.geolocation.clearWatch(watchID);
~~~
## Vibration API
Vibration接口用于在瀏覽器中發出命令,使得設備振動。顯然,這個API主要針對手機,適用場合是向用戶發出提示或警告,游戲中尤其會大量使用。由于振動操作很耗電,在低電量時最好取消該操作。
使用下面的代碼檢查該接口是否可用。目前,只有Chrome和Firefox的Android平臺最新版本支持它。
~~~
navigator.vibrate = navigator.vibrate
|| navigator.webkitVibrate
|| navigator.mozVibrate
|| navigator.msVibrate;
if (navigator.vibrate) {
// 支持
}
~~~
vibrate方法可以使得設備振動,它的參數就是振動持續的毫秒數。
~~~
navigator.vibrate(1000);
~~~
上面的代碼使得設備振動1秒鐘。
vibrate方法還可以接受一個數組作為參數,表示振動的模式。偶數位置的數組成員表示振動的毫秒數,奇數位置的數組成員表示等待的毫秒數。
~~~
navigator.vibrate([500, 300, 100]);
~~~
上面代碼表示,設備先振動500毫秒,然后等待300毫秒,再接著振動500毫秒。
vibrate是一個非阻塞式的操作,即手機振動的同時,JavaScript代碼繼續向下運行。要停止振動,只有將0毫秒或者一個空數組傳入vibrate方法。
~~~
navigator.vibrate(0);
navigator.vibrate([]);
~~~
如果要讓振動一直持續,可以使用setInterval不斷調用vibrate。
~~~
var vibrateInterval;
function startVibrate(duration) {
navigator.vibrate(duration);
}
function stopVibrate() {
if(vibrateInterval) clearInterval(vibrateInterval);
navigator.vibrate(0);
}
function startPeristentVibrate(duration, interval) {
vibrateInterval = setInterval(function() {
startVibrate(duration);
}, interval);
}
~~~
## Luminosity API
Luminosity API用于屏幕亮度調節,當移動設備的亮度傳感器感知外部亮度發生顯著變化時,會觸發devicelight事件。目前,只有Firefox部署了這個API。
~~~
window.addEventListener('devicelight', function(event) {
console.log(event.value + 'lux');
});
~~~
上面代碼表示,devicelight事件的回調函數,接受一個事件對象作為參數。該對象的value屬性就是亮度的流明值。
這個API的一種應用是,如果亮度變強,網頁可以顯示黑底白字,如果亮度變弱,網頁可以顯示白底黑字。
~~~
window.addEventListener('devicelight', function(e) {
var lux = e.value;
if(lux < 50) {
document.body.className = 'dim';
}
if(lux >= 50 && lux <= 1000) {
document.body.className = 'normal';
}
if(lux > 1000) {
document.body.className = 'bright';
}
});
~~~
CSS下一個版本的Media Query可以單獨設置亮度,一旦瀏覽器支持,就可以用來取代Luminosity API。
~~~
@media (light-level: dim) {
/* 暗光環境 */
}
@media (light-level: normal) {
/* 正常光環境 */
}
@media (light-level: washed) {
/* 明亮環境 */
}
~~~
## Orientation API
Orientation API用于檢測手機的擺放方向(豎放或橫放)。
使用下面的代碼檢測瀏覽器是否支持該API。
~~~
if (window.DeviceOrientationEvent) {
// 支持
} else {
// 不支持
}
~~~
一旦設備的方向發生變化,會觸發deviceorientation事件,可以對該事件指定回調函數。
~~~
window.addEventListener("deviceorientation", callback);
~~~
回調函數接受一個event對象作為參數。
~~~
function callback(event){
console.log(event.alpha);
console.log(event.beta);
console.log(event.gamma);
}
~~~
上面代碼中,event事件對象有alpha、beta和gamma三個屬性,它們分別對應手機擺放的三維傾角變化。要理解它們,就要理解手機的方向模型。當手機水平擺放時,使用三個軸標示它的空間位置:x軸代表橫軸、y軸代表豎軸、z軸代表垂直軸。event對象的三個屬性就對應這三根軸的旋轉角度。
* alpha:表示圍繞z軸的旋轉,從0到360度。當設備水平擺放時,頂部指向地球的北極,alpha此時為0。
* beta:表示圍繞x軸的旋轉,從-180度到180度。當設備水平擺放時,beta此時為0。
* gramma:表示圍繞y軸的選擇,從-90到90度。當設備水平擺放時,gramma此時為0。
## 參考鏈接
* Ryan Stewart,?[Using the Geolocation API](http://www.adobe.com/devnet/html5/articles/using-geolocation-api.html)
* Rathnakanya K. Srinivasan,?[HTML5 Geolocation](http://www.sitepoint.com/html5-geolocation/)
* Craig Buckler,?[How to Use the HTML5 Vibration API](http://www.sitepoint.com/use-html5-vibration-api/)
* Tomomi Imura,?[Responsive UI with Luminosity Level](http://girliemac.com/blog/2014/01/12/luminosity/)
* Aurelio De Rosa,?[An Introduction to the Geolocation API](http://code.tutsplus.com/tutorials/an-introduction-to-the-geolocation-api--cms-20071)
* David Walsh,?[Vibration API](http://davidwalsh.name/vibration-api)
* Ahmet Mermerkaya,?[Using Device Orientation in HTML5](http://www.sitepoint.com/using-device-orientation-html5/)
- 第一章 導論
- 1.1 前言
- 1.2 為什么學習JavaScript?
- 1.3 JavaScript的歷史
- 第二章 基本語法
- 2.1 語法概述
- 2.2 數值
- 2.3 字符串
- 2.4 對象
- 2.5 數組
- 2.6 函數
- 2.7 運算符
- 2.8 數據類型轉換
- 2.9 錯誤處理機制
- 2.10 JavaScript 編程風格
- 第三章 標準庫
- 3.1 Object對象
- 3.2 Array 對象
- 3.3 包裝對象和Boolean對象
- 3.4 Number對象
- 3.5 String對象
- 3.6 Math對象
- 3.7 Date對象
- 3.8 RegExp對象
- 3.9 JSON對象
- 3.10 ArrayBuffer:類型化數組
- 第四章 面向對象編程
- 4.1 概述
- 4.2 封裝
- 4.3 繼承
- 4.4 模塊化編程
- 第五章 DOM
- 5.1 Node節點
- 5.2 document節點
- 5.3 Element對象
- 5.4 Text節點和DocumentFragment節點
- 5.5 Event對象
- 5.6 CSS操作
- 5.7 Mutation Observer
- 第六章 瀏覽器對象
- 6.1 瀏覽器的JavaScript引擎
- 6.2 定時器
- 6.3 window對象
- 6.4 history對象
- 6.5 Ajax
- 6.6 同域限制和window.postMessage方法
- 6.7 Web Storage:瀏覽器端數據儲存機制
- 6.8 IndexedDB:瀏覽器端數據庫
- 6.9 Web Notifications API
- 6.10 Performance API
- 6.11 移動設備API
- 第七章 HTML網頁的API
- 7.1 HTML網頁元素
- 7.2 Canvas API
- 7.3 SVG 圖像
- 7.4 表單
- 7.5 文件和二進制數據的操作
- 7.6 Web Worker
- 7.7 SSE:服務器發送事件
- 7.8 Page Visibility API
- 7.9 Fullscreen API:全屏操作
- 7.10 Web Speech
- 7.11 requestAnimationFrame
- 7.12 WebSocket
- 7.13 WebRTC
- 7.14 Web Components
- 第八章 開發工具
- 8.1 console對象
- 8.2 PhantomJS
- 8.3 Bower:客戶端庫管理工具
- 8.4 Grunt:任務自動管理工具
- 8.5 Gulp:任務自動管理工具
- 8.6 Browserify:瀏覽器加載Node.js模塊
- 8.7 RequireJS和AMD規范
- 8.8 Source Map
- 8.9 JavaScript 程序測試
- 第九章 JavaScript高級語法
- 9.1 Promise對象
- 9.2 有限狀態機
- 9.3 MVC框架與Backbone.js
- 9.4 嚴格模式
- 9.5 ECMAScript 6 介紹
- 附錄
- 10.1 JavaScript API列表
- 草稿一:函數庫
- 11.1 Underscore.js
- 11.2 Modernizr
- 11.3 Datejs
- 11.4 D3.js
- 11.5 設計模式
- 11.6 排序算法
- 草稿二:jQuery
- 12.1 jQuery概述
- 12.2 jQuery工具方法
- 12.3 jQuery插件開發
- 12.4 jQuery.Deferred對象
- 12.5 如何做到 jQuery-free?
- 草稿三:Node.js
- 13.1 Node.js 概述
- 13.2 CommonJS規范
- 13.3 package.json文件
- 13.4 npm模塊管理器
- 13.5 fs 模塊
- 13.6 Path模塊
- 13.7 process對象
- 13.8 Buffer對象
- 13.9 Events模塊
- 13.10 stream接口
- 13.11 Child Process模塊
- 13.12 Http模塊
- 13.13 assert 模塊
- 13.14 Cluster模塊
- 13.15 os模塊
- 13.16 Net模塊和DNS模塊
- 13.17 Express框架
- 13.18 Koa 框架