htmlcss HTML5 の機能検出

2014年10月25日

HTML5 の機能を検出する方法の個人的なメモ。

参考:「入門 HTML5(オライリー)」

目次

Modernizr

Modernizr は HTML5 と CSS3 の機能のサポートを検出してくれる JavaScript ライブラリ。(これを利用するのが一番簡単だと思う)

Modernizr は読み込まれると、Modernizr という名前の JavaScript オブジェクトを作成し、そのプロパティにテストの検出結果(true/false)を格納するので、それを利用する。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>HTML5 Test</title>
  <!-- Modernizr の読み込み -->
  <script src="js/modernizr.custom.46727.js" type="text/javascript"></script>
</head>
<body>

<script>
if(Modernizr.canvas){
  //Canvas API がサポートされている場合の処理(描画の処理)
}else{
  //そうでない場合の処理
}
</script>
</body>
</html>

関連ページ:「ブラウザの HTML5, CSS3 の機能を検出してくれる Modernizr

個々の機能を検出するには以下のような方法がある。

基本的な検出方法

  1. グローバルオブジェクト(window や navigator 等)に特定のプロパティがあるかどうかをチェック。
  2. 要素を作成しその要素に特定のプロパティがあるかどうかをチェック。
  3. 要素を作成しその要素に特定のメソッドがあるかどうかをチェックし、そのメソッドを呼び出して戻り値をチェック。
  4. 要素を作成しプロパティを特定の値に設定し、そのプロパティが設定した値を保持しているかをチェック。

Canvas

  • Canvas は矩形の領域に JavaScript を使って好きなものを描画することができる。
  • HTML5 では一連の関数(Canvas API)が定義されている。

ブラウザが Canvas API をサポートしているかどうかは、基本的な検出方法の2番目の方法(要素を作成しその要素に特定のプロパティがあるかどうかをチェック。)を利用。

以下の関数を使って Canvas API がサポートされているかどうかをチェックできる(サポートされていれば true が返る)。

<script>
function is_canvas_supported() {
  return !!document.createElement('canvas').getContext;
}
</script>
  • ダミーの <canvas> 要素を作成:document.createElement(‘canvas’)(この作成された要素はメモリの中にだけ存在し、何もしない)
  • 作成した要素に対し、getContext() メソッドが存在するかをテストする。(このメソッドはブラウザが Canvas API をサポートしている場合にのみ存在する)
  • 二重否定を使って結果を論理値(true/false)として返す。

二重否定

“undefined” や object が返る可能性がある値を二重否定を行うことで真偽値(Boolean)として取得するイディオムのようなもの。

getContext() メソッドが存在しない場合、document.createElement(‘canvas’).getContext は未定義(undefined)と評価されるが、未定義は JavaScript では「偽」の値になるので、この値の前に否定を 1 つ置くと真と評価され、二重否定は偽と評価される。

var foo = undefined;
console.log(foo);    //undefined
console.log(!foo);    //true
console.log(!!foo);    //false

var bar = {};
console.log(bar);    // Object {}
console.log(!bar);    //false
console.log(!!bar);    //true

Canvas Text

ブラウザが Canvas API をサポートしていても、Canvas Text API をサポートしているとは限らないとのこと。

Canvas API のサポートをチェックするには2番目の方法(要素を作成しその要素に特定のプロパティがあるかどうかをチェック。)を利用。

次の関数を使って Canvas Text API のサポートをチェックできる。

function is_canvas_text_supported() {
  if(!is_canvas_supported()) { return false; } //前述の関数を利用
  var context = document.createElement('canvas').getContext('2d');
  return typeof context.fillText == 'function';
}
  • 前述の関数を利用して、Canvas のサポートをチェック。
  • ダミーの <canvas> 要素を作成し、その描画コンテキストを取得。
  • 描画コンテキストが fillText() 関数を持っているかをチェック。

Modernizr を使えば以下のようにして、Canvas Text API のサポートをチェックできる。

if(Modernizr.canvastext) {
  //Canvas Text API がサポートされている場合の処理
}else{
  //そうでない場合の処理
}

ビデオ

HTML5 ではビデオを埋め込むための <video> という要素が定義されている。

HTML5 をサポートしていないブラウザは <video> を完全に無視するので、これを利用してプラグインなどを使ってビデオを再生(フォールバック)することができる。

ビデオのサポートをチェックするには2番目の方法(要素を作成しその要素に特定のプロパティがあるかどうかをチェック。)を利用。

ブラウザが HTML5 ビデオをサポートしていれば、<video> として作成された DOM オブジェクトは canPlayType() メソッドを持っているので次の関数を使ってビデオのサポートをチェックできる。

function is_video_supported() {
  return !!document.createElement('video').canPlayType;
}

Modernizr を使えば以下のようにして、HTML5 ビデオのサポートをチェックできる。

if(Modernizr.video) {
  //HTML5 ビデオがサポートされている場合の処理(ビデオ再生)
}else{
  //そうでない場合の処理(QuickTime か Flash が代わりに使えるかをチェックする等)
}

ビデオフォーマット

ビデオフォーマットのサポートをチェックするには、3番目の検出方法(要素を作成しその要素に特定のメソッドがあるかどうかをチェックし、そのメソッドを呼び出して戻り値をチェック)を使う。

戻り値は真偽値ではなく以下の文字列を返す。

  • “probably” : このフォーマットを再生できることがかなり確実な場合
  • “maybe” : このフォーマットを再生できるかもしれない場合
  • “” (空文字列): このフォーマットを再生できないことが確実な場合

以下は、MPEG4コンテナ中の H.264 ベースラインプロファイルのビデオと AAC LC オーディオ再生が可能かをチェックする関数。

function is_h264_baseline_video_supported() {
  if(!is_video_supported()) {return false; } //前述の関数を利用
  var v = document.createElement('video');
  return v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
}

以下は、Ogg コンテナ中の Theora ビデオと Vorbis オーディオを再生できるかチェックする関数。

function is_ogg_theora_video_supported() {
  if(!is_video_supported()) {return false; }
  var v = document.createElement('video');
  return v.canPlayType('video/ogg; codecs="theora, vorbis"');
}

以下は、オープン WebM ビデオのサポートを検出する関数。

function is_webm_video_supported() {
  if(!is_video_supported()) {return false; }
  var v = document.createElement('video');
  return v.canPlayType('video/webm; codecs="vp8, vorbis"');
}

以下は、Modernizr を使ったビデオフォーマットのサポートの検出。

if(Modernizr.video) {
  if(Modernizr.video.webm){
    //webm
  }else if(Modernizr.video.ogg) {
    //ogg
  }else if(Modernizr.video.h264) {
    //h264
  }
}else{
  //HTML5 ビデオがサポートされていない場合
}

ローカルストレージ

ローカルストレージはクッキーに代わるデータ保存の仕組みのようなもので、Web アプリケーション利用者のブラウザ(PC)内にデータを保存するストレージ。

ローカルストレージのサポートをチェックするには1番目の検出方法(グローバルオブジェクトに特定のプロパティがあるかどうかをチェック)を使う。

ブラウザがローカルストレージをサポートしていれば、window オブジェクトに localStorage プロパティが存在し、サポートしていなければ localStorage プロパティは未定義になる。

次の関数を使ってローカルストレージのサポートをチェックできる。

function is_localStorage_supported() {
  try {
    return ('localStorage' in window) && window['localStorage'] !== null;
  }catch(e){
    return false;
  }
}

未対応なブラウザでは localStorage と記述するとエラーがが返ってしまうので例外処理を行っているみたい。(他は大丈夫なのか?)

in 演算子
オブジェクトにプロパティが存在するかどうかを判定する
“プロパティ名” in オブジェクト
存在しないプロパティから値を読み出すと未定義値(undefined)になる
連想配列としてのオブジェクト
オブジェクトのプロパティにアクセスするにはドット演算子を使用するか、配列演算子[]を使うことができる。
null値
「値がない」ことを表す特殊な値。nullはオブジェクト型で「オブジェクトがない」という意味を表す特別な値。
ある変数の値がnullであれば、その変数には、有効なオブジェクトや配列、数値、文字列は格納されていないことになる。
undefined(未定義)値
宣言されている値が、設定されていない変数や、存在しないオブジェクトプロパティを使おうとすると未定義値が返される。
null 値と未定義値は異なる値だが、== 等値演算子で比較した場合は同じ値とみなされる。
null と未定義値を区別しなければならない場合は、=== 同値演算子か typeof 演算子を使う。
try-catch 文
try 文のブロックの中で例外(エラー)が発生すると、catch 文のブロックが実行され、例外が捕捉される。try 文のブロックで例外が発生しなかった場合は、catch 文のブロックは実行されない。

以下は、Modernizr を使ったローカルストレージのサポートの検出。

if(Modernizr.localstorage) {
  //ローカルストレージがサポートされている場合の処理
}else{
  //そうでない場合の処理
}

※ Modernizr の属性は「localstorage」で全て小文字だが、DOM のプロパティは「localStorage」と S が大文字。

Web Worker

Web Worker を利用することで、JavaScript コードの処理を並行して実行できる。

Web Worker のサポートをチェックするには1番目の検出方法(グローバルオブジェクトに特定のプロパティがあるかどうかをチェック)を使う。

ブラウザが Web Worker をサポートしていれば、window オブジェクトに Worker プロパティが存在し、サポートしていなければ Worker プロパティは未定義になる。

次の関数を使って Web Worker のサポートをチェックできる。

function is_webWorker_supported() {
  return !!window.Worker;  //Worker の W は大文字
}

以下は、Modernizr を使った Web Worker のサポートの検出。(webworkers の w は小文字)

if(Modernizr.webworkers) {
  //Web Worker がサポートされている場合の処理
}else{
  //そうでない場合の処理
}

オフライン Web アプリケーション(アプリケーションキャッシュ)

オフライン Web アプリケーションの基本的な仕組みは、ユーザーがインターネットに接続してウェブアプリケーションを利用した際に、 HTML、CSS、JavaScript、画像等の ウェブアプリケーションに必要なファイルをユーザーのローカル環境に保存して、 次回からはオフラインでもウェブアプリケーションを利用できるようにするというもの。

アプリケーションキャッシュのサポートをチェックするには1番目の検出方法(グローバルオブジェクトに特定のプロパティがあるかどうかをチェック)を使う。

ブラウザがアプリケーションキャッシュをサポートしていれば、window オブジェクトに applicationCache プロパティが存在し、サポートしていなければ applicationCache プロパティは未定義になる。

次の関数を使ってアプリケーションキャッシュのサポートをチェックできる。

function is_applicationCache_supported() {
  return !!window.applicationCache;  //applicationCache の C は大文字
}

以下は、Modernizr を使ったアプリケーションキャッシュのサポートの検出。(applicationcache の c は小文字)

if(Modernizr.applicationcache) {
  //Web Worker がサポートされている場合の処理
}else{
  //そうでない場合の処理
}

Geolocation

Geolocation はどこにいるのかを検出する機能。

Geolocation のサポートをチェックするには1番目の検出方法(グローバルオブジェクトに特定のプロパティがあるかどうかをチェック)を使う。

ブラウザが Geolocation をサポートしていれば、navigator オブジェクトに geolocation プロパティが存在し、サポートしていなければ geolocation プロパティは未定義になる。

次の関数を使って Geolocation のサポートをチェックできる。

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

以下は、Modernizr を使った Geolocation のサポートの検出。

if(Modernizr.geolocation) {
  //Geolocation がサポートされている場合の処理
}else{
  //そうでない場合の処理
}

Input タイプ

HTML5 ではフォームに使用できる input タイプが多数定義されている。

  • <input type=”search”> 検索ボックス
  • <input type=”number”> スピンボックス
  • <input type=”range”> スライダ
  • <input type=”color”> カラーピッカー
  • <input type=”tel”> 電話番号
  • <input type=”url”> URL
  • <input type=”email”> メールアドレス
  • <input type=”date”> カレンダーやデートピッカー
  • <input type=”month”> 月の入力
  • <input type=”week”> 週の入力
  • <input type=”time”> 時刻の入力
  • <input type=”datetime”> 詳細な日時や時刻
  • <input type=”datetime-local”> 自分のいる地域の日付と時刻

HTML5 の新しい input タイプがサポートされているかをチェックするには、4番目の検出方法(要素を作成しプロパティを特定の値に設定し、そのプロパティが設定した値を保持しているかをチェック)を使う。

  • 最初にメモリ中にダミーの<input>要素を作成(全ての<input>要素のデフォルトのタイプは”text”となる)。
  • そしてダミーの<input>要素の type 属性を検出したいタイプに設定。
  • ブラウザがそのタイプをサポートしていれば、type プロパティは設定した値を保持している。
  • サポートしていない場合は、設定された値は無視され、type プロパティは”text”のままになっている。

次の関数を使って検出したい Input タイプのサポートをチェックできる。

function is_input_color_supported() {
  var i = document.createElement("input");
  i.setAttribute("type", "color");
  return i.type !== "text";
}

13個の関数を書く代わりに、Modernizr を使って HTML5 で定義されたタイプのサポートを検出することができる。

作成される Modernizr.inputtypes という名前のハッシュには13個のキー(type 属性)と13個の論理値(true/false)が含まれる。

if(Modernizr.inputtypes.color) {
  //input タイプ type="color" がサポートされている場合の処理
}else{
  //そうでない場合の処理
}

プレースホルダ

入力フィールドのプレースホルダを設定できる機能で、プレースホルダはそのフィールドが空で、そこにフォーカスがない場合に表示される。

プレースホルダのサポートをチェックするには、2番目の方法(要素を作成しその要素に特定のプロパティがあるかどうかをチェック)を利用。

入力フィールドのプレースホルダをサポートしていれば、<input>要素として作成された DOM オブジェクトは placeholder プロパティを持っているが、サポートされていなければ placeholder プロパティを持っていない。

次の関数を使ってプレースホルダのサポートをチェックできる。

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

以下は、Modernizr を使ったプレースホルダのサポートの検出。

if(Modernizr.input.placeholder) {
  //プレースホルダがサポートされている場合の処理
}else{
  //そうでない場合の処理
}

プレースホルダを表示させるには、以下のように記述する。placeholder 属性をサポートしていないブラウザは、単純にそれを無視するので無害で安全とのこと。必要であれば前述の機能検出を使って対応することもできる。

<form>
    <input name="p" placeholder="プレースホルダ">
</form>

フォームのオートフォーカス

HTML5 は全てのフォームコントロールに autofocus 属性を導入している。

オートフォーカスのサポートをチェックするには、2番目の方法(要素を作成しその要素に特定のプロパティがあるかどうかをチェック)を利用。

オートフォーカスをサポートしていれば、<input>要素として作成された DOM オブジェクトは autofocus プロパティを持っているが、サポートされていなければ autofocus プロパティを持っていない。

次の関数を使ってオートフォーカスのサポートをチェックできる。

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

以下は、Modernizr を使ったオートフォーカスのサポートの検出。

if(Modernizr.input.autofocus) {
  //オートフォーカスがサポートされている場合の処理
}else{
  //そうでない場合の処理
}

マイクロデータ

マイクロデータのサポートをチェックするには1番目の検出方法(グローバルオブジェクトに特定のプロパティがあるかどうかをチェック)を使う。

ブラウザがマイクロデータをサポートしていれば、document オブジェクトに getItems() メソッドが存在し、サポートしていなければ getItems() メソッドは未定義になる。

次の関数を使ってマイクロデータのサポートをチェックできる。

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

Modernizr はまだマイクロデータ API のチェックをサポートしていないみたい。