Dive Into HTML5:检测 HTML5 特性(续三)

地理位置

地理位置 geolocation 用于获取你在这个世界上的位置信息,并且可以将这个信息分享给你所信任的人。现在有很多方法可以获取位置信息:IP 地址、无线网络连接(通过查看你的手机实际是与哪一个基站通讯)或者是 GPS 硬件设备等。

FAQ

Q: 地理位置是 HTML5 的一部分吗?为什么要谈论这个问题?

A: 地理信息现在已经被加入到浏览器中,作为 HTML5 的一种新特性。严格说来,地理位置是由 Geolocation Working Group 进行标准化的,请注意这个工作组与 HTML5 Working Group 是相互独立的。但是我们也会在后面的内容中详细讨论这个问题,因为地理位置的出现相当于是现代 web 的一种革命。

我们使用第一种技术来检测地理位置的支持。如果浏览器支持地理位置 API,那么在全局的navigator对象中会有一个geolocation属性;如果不支持则该属性将设置为undefined。下面就是我们的检测代码:

function supports_geolocation() {
    return !!navigator.geolocation;
}

如果你不愿意自己编写代码,当然也可以使用 Modernizr:

if (Modernizr.geolocation) {
    // let's find out where you are!
} else {
    // no native geolocation support available 🙁
    // maybe try Gears or another third-party solution
}

如果你的浏览器不是原生支持地理位置 API,还有另外的希望。Gears 是由 Google 开发的,能够在 Windows、Mac、Linux、Windows Mobile 和 Android 上面运行的开源的浏览器插件。它可以让那些不支持新功能的老版本浏览器支持这些新功能。Gears 所能提供的一个特性就是地理位置 API。它同 navigator.geolocation API 并不一致,但是目的是一致的。在老式手机平台上,也有一些与设备相关的 geolocation API,包括 BlackBerry、Nokia、Palm 和 OMTP BONDI。

我们会在后面的章节中详细讨论如何使用这么多不同的 API。

Input Types

现在我们经常使用 HTML form。我们可以创建一个<form>标签,添加一些<input type="text">元素,可能还有<input type="password">,最后再有一个<input type="submit">按钮。

事实上,HTML5 为 form 定义了很多新的类型:

  • <input type="search">创建一个搜索框
  • <input type="number">创建 spin box
  • <input type="range">创建滑块
  • <input type="color">创建颜色选择框
  • <input type="tel">创建电话号码输入框
  • <input type="url">创建 web 地址输入框
  • <input type="email">创建 email 输入框
  • <input type="date">创建日期选择器
  • <input type="month">创建月份选择器
  • <input type="week">创建星期选择器
  • <input type="time">创建时间选择器
  • <input type="datetime">创建精确的日期时间选择器
  • <input type="datetime-local">创建本地化的日期时间选择器

我们使用前面所说的第四种技术检测 HTML5 input type。首先,在内存中创建一个临时的<input>元素,所有<input>的默认 type 都是text。记住这一点是相当重要的。

var i = document.createElement("input");

下一步,设置你所需要检测的 type,例如:

i.setAttribute("type", "color");

如果浏览器支持这种类型,则 type 就会是你设置的这个,否则的话,浏览器就会忽略你的设置,type 仍然是 text。

return i.type !== "text";

我们最好使用 Modernizr,这样的话就不需要自己去写那 13 种检测代码了。Modernizr 重用一个<input>来检测所有 13 种 input type,结果则放在名为Modernizr.inputtypes的哈希表中,其键是 13 种 HTML5 的 input type 属性,值则是Boolean类型,true是支持,false是不支持。

if (!Modernizr.inputtypes.date) {
    // no native support for <input type="date" /> 🙁
    // maybe build one yourself with Dojo or jQueryUI
}

Placeholder Text

除了新的 input type,HTML5 还包含了对 form 的细节改进。其中一个很重要的部分就是添加了 input 输入框的placeholder文本。所谓 placeholder 就是占位符,通常在输入框还是空白,并且没有焦点的时候用于提示用户信息。只要你点击了输入框,占位符就会消失。

我们使用第二种技术检测 placeholder。如果浏览器支持 placeholder,表示<input>标签的 DOM 对象就会有一个placeholder属性(即使你并没有在 HTML 里面添加 placeholder),否则的话就没有这个属性。

function supports_input_placeholder() {
    var i = document.createElement('input');
    return 'placeholder' in i;
}

我们也可以直接使用 Modernizr (1.1 或更新版本) 检测。

if (Modernizr.input.placeholder) {
    // your placeholder text should already be visible!
} else {
    // no placeholder support 🙁
    // fall back to a scripted solution
}

Form Autofocus

Web 站点可以使用 JavaScript 使得 form 中的第一个 input 自动获取焦点。例如,Google.com 的主页能够自动让输入框获得焦点,从而你可以在页面打开之后直接输入搜索词,无需使用鼠标在输入框上点一下。这一特性可以方便很多人,但是对于另外一些高级用户或者有特殊需要的用户来说却不那么友好。比如,你希望点击空格键可以向下滚动页面,结果页面不会滚动,因为焦点一直在输入框中,这样的话,按下空格只会在输入框中输入一个空格,而不是滚动页面。如果在页面仍在加载时让另外一个输入框聚焦,那么当页面加载完成之后,我们的自动聚焦的脚本会“帮助”我们把焦点重新回到第一个输入框上,这么一来就可能打乱你的流程,在错误的位置输入。由于自动聚焦使用 JavaScript 完成,对于处理这些异常情况就会很复杂。

为了解决这个问题,HTML5 为 form 的 input 引入了autofocus属性。autofocus属性同前面所说的行为是一样的:它将焦点移动到一个特定的输入组件上。但由于这是一个标签而不是脚本,所以它的行为对于所有站点都是一致的。并且浏览器也能够提供一种禁用这种 autofocus 行为的能力。

我们使用第二种技术来检测 autofocus。如果浏览器支持 form 组件的 autofocus,则其<input>DOM 对象就会有一个autofocus属性,否则则没有这个属性。

function supports_input_autofocus() {
    var i = document.createElement('input');
    return 'autofocus' in i;
}

我们也可以使用 Modernizr (1.1 或更新版本) 检测这一特性:

if (Modernizr.input.autofocus) {
    // autofocus works!
} else {
    // no autofocus support 🙁
    // fall back to a scripted solution
}

Microdata

Microdata 可以为你的 web 页面提供额外的语义。例如,你可以使用 microdata 来声明一张照片使用 Creative Commons 协议发布。在后面的章节中,我们还会介绍如何使用 microdata 标记“关于我”的页面。浏览器、浏览器扩展和搜索引擎将会把你的 HTML5 microdata 转换成 vCard 标记。这是一种分享联系信息的标准格式。你也可以定义你自己的 microdata 语义。

HTML5 microdata 标准包括 HTML 标签 (主要供搜索引擎使用) 和一组 DOM 函数 (主要供浏览器使用)。在你的页面上加入 microdata 标签并没有什么不妥。它只不过是一些属性集合。如果搜索引擎不理解 microdata 属性,就会简单地忽略它们。但是如果你需要通过 DOM 访问或者维护 microdata,就需要检测浏览器是否支持 microdata DOM API。

我们使用第一种技术检测 microdata API。如果浏览器支持 HTML5 microdata API,那么在全局的document对象中会有一个getItems()函数,否则则没有。

function supports_microdata_api() {
  return !!document.getItems;
}

Modernizr 目前版本还不支持 microdata API 的检测,所以我们现在只能使用上面的代码了。

History API

HTML5 history API 提供了一组标准函数,使得我们可以通过脚本维护浏览器历史。这个 API 的一部分——历史导航——在早期版本的 HTML 里面已经实现了。HTML5 新增加的部分是,增加浏览器历史的条目,响应用户使用后退按钮访问浏览器历史等等。这意味着 URL 现在仍然可以作为当前资源的唯一标识符,甚至在全部由脚本构成的应用程序中也是这样(这里是说,对于无需整页刷新的 AJAX 程序,URL 一般不能准确的标识出当前资源,因为你的页面不是整页刷新,URL 不会随着显示内容的不同而有不同。但是使用了 history API,我们就可以解决这一问题)。

我们使用第一种技术检测 HTML5 history API。如果浏览器支持HTML5 history API,则全局的history对象中会有一个pushState()函数,否则则没有。

function supports_history_api() {
    return !!(window.history && history.pushState);
}

我们可以使用 Modernizr (1.6 或更新版本) 来检测 HTML5 history API。

if (Modernizr.history) {
    // history management works!
} else {
    // no history support 🙁
    // fall back to a scripted solution like History.js
}

Leave a Reply