2011年3月8日火曜日

HTML 5 を使って新しいビジュアル UI 機能を開発する

前提条件

この記事では、最新の Web 技術を使用して Web アプリケーションを作成します。ここで紹介するコードの大部分は単なる HTML と JavaScript、そして CSS であり、すべての Web 開発者にとってコアとなる技術です。記事の内容に従うために必要なもののうち、最も重要なものはテストを実行する際に使用するブラウザーです。この記事のコードの大部分は最新のデスクトップ・ブラウザーで実行しますが、いくつか明らかな例外があります。もちろん、モバイル・ブラウザーでもテストする必要があり、そのために iPhone と Android の最新 SDK が必要です。この記事では iPhone SDK 3.1.3 と Android SDK 2.1 を使用しました。リンクは「参考文献」セクションを参照してください。

Canvas を使ってグラフィカルにする

よく使われる頭字語

  • Ajax: Asynchronous JavaScript + XML
  • API: Application Programming Interface
  • CSS: Cascading stylesheet
  • DOM: Document Object Model
  • HTML: HyperText Markup Language
  • SDK: Software Developer Kit
  • UI: User Interface
  • XML: Extensible Markup Language

Web 開発者は長年、Canvas に関して不満を抱いていました。では、ブラウザーに元々備わっている描画 API に関して誰もが不満を言うのはなぜでしょう。確かに、そうした API を使用すると、何らかのブラウザー・プラグインを使わない限り不可能な種類のグラフィカル・インターフェースを作成することができます (しかしモバイル Web の開発者なら誰もが知っているように、最もよく使われるモバイル・ブラウザーに利用できるプラグインは存在しない場合が多いのです)。Web 開発者が Canvas に不満を抱いてきた理由は、長年 Firefox と Safari では Canvas を利用できたものの、最もよく使われるデスクトップ・ブラウザーである Microsoft® Internet Explorer® では Canvas がサポートされていなかったからです。Internet Explorer 9 の初期バージョンでさえ、Canvas をサポートしていません。つまり長年の間、Canvas は技術の笑いぐさの象徴だったのです。驚くような Canvas の例はインターネットの至る所で見られるにもかかわらず、Internet Explorer が Canvas をサポートしていないため、ほとんどの Web アプリケーションには Canvas を使うことができません。幸いモバイル Web 開発では、Canvas にそうした制約はありません。Web 開発のターゲットとなる Webkit ベースのブラウザーはすべて、Canvas を実装することができ、また Canvas のパフォーマンスを大幅に最適化することができます。

Canvas API は描画用の下位レベルの API です。Canvas API を利用することで、直線、曲線、ポリゴン、円を作成することができ、またそれらに色をつけたり、グラデーションをつけたりすることができます。Canvas 上では、テキストを作成することや、さまざまなタイプの幾何学的変換を行うことができます。容易に想像できるように、そうした API の用途は無数にあります。ここで、Canvas を使ってグラフィカルなレポートを作成するアプリケーションを調べてみましょう。図 1 は、毎年の成績を棒グラフで表現するアプリケーションのスクリーン・キャプチャーです。


図 1. Canvas ベースのレポート・アプリケーションを Android のブラウザーで実行した様子
このスクリーン・キャプチャーは Canvas ベースのレポート・アプリケーションが Android のブラウザーで実行されている様子を示しています。 

図 1 はブラウザーの中にある静的な画像を表示したものではありません。このレポートのグラフィックは Canvas API を使ってオンザフライで生成されています。リスト 1 は、このレポートを生成する HTML を示しています。


リスト 1. レポートの HTML
<!DOCTYPE html> <html> <head>     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">     <meta name="viewport" content="width=device-width; initial-scale=1.0;          maximum-scale=1.0; user-scalable=0;"/>     <meta name="apple-touch-fullscreen" content="YES" />     <title>HTML 5 Reports</title>     <script type="text/javascript">         function init(){             var data = [{year : "2007",sales : 49},                 {year : "2008",sales : 131},                 {year : "2009",sales : 294},                  {year : "2010",sales : 405}];             var report = {x : "year",                     y : "sales",                     values : data};             graph(report, 350, 300);         }     </script> </head> <body onload="init()">     <canvas id="graph"></canvas> </body> </html>     

このリストは HTML の基本的な構造を示しています。この文書の本体には canvas タグが 1 つあります。この文書の本体がロードされると呼び出される init 関数の中で、静的なデータ (レポート・データ) を定義し、そのデータを graph 関数に渡しています。ここではこのレポートを静的なデータとして定義しましたが、容易に想像できるように、レポートのデータをネットワーク経由で Ajax を使って動的にダウンロードすることもできます。report 関数には、ありとあらゆる興味深いコードが含まれています。そこで、そうしたコードを調べてみましょう (リスト 2)。


リスト 2. graph 関数
function graph(report, maxWidth, maxHeight){     var data = report.values;     var canvas = document.getElementById("graph");     var axisBuffer = 20;     canvas.height = maxHeight + 100;     canvas.width = maxWidth;     var ctx = canvas.getContext("2d");      var width = 50;     var buffer = 20;     var i = 0;     var x = buffer + axisBuffer;     ctx.font = "bold 12px sans-serif";     ctx.textAlign = "start";     for (i=0;i<data.length;i++){         ctx.fillStyle = "rgba(0, 0, 200, 0.9)";         ctx.fillRect(x, maxHeight - (data[i][report.y] / 2),                   width, (data[i][report.y] / 2));         ctx.fillStyle = "rgba(0, 0, 0, 0.9)";         ctx.fillText(data[i][report.x], x + (width / 4), maxHeight + 15);         x += width + buffer;     }      // draw the horizontal axis     ctx.moveTo(axisBuffer, maxHeight);     ctx.lineTo(axisBuffer+maxWidth, maxHeight);     ctx.strokeStyle = "black";     ctx.stroke();      // draw the vertical axis     ctx.moveTo(axisBuffer,0);     ctx.lineTo(axisBuffer,maxHeight);     ctx.stroke();      // draw gridlines     var lineSpacing = 50;     var numLines = maxHeight/lineSpacing;     var y = lineSpacing;     ctx.font = "10px sans-serif";     ctx.textBaseline = "middle";     for (i=0;i<numLines;i++){         ctx.strokeStyle = "rgba(0,0,0,0.25)";         ctx.moveTo(axisBuffer, y);         ctx.lineTo(axisBuffer + maxWidth,y);         ctx.stroke();         ctx.fillStyle = "rgba(0,0,0, 0.75)";         ctx.fillText(""+(2*(maxHeight -y)), 0, y);         y += lineSpacing;      } } 

この関数の最初の部分で、レポートの作成に必要なオブジェクト (キャンバスの幅と高さなど) とパディング変数を設定しています。またキャンバスのコンテキスト・オブジェクトも作成しています (このオブジェクトを使うことで、実際の描画をすべて行います)。次に、レポート・データを繰り返し処理し、図 1 に示す棒グラフを描画します。最初に fillStyle プロパティーを設定します。fillStyle プロパティーの設定は、色の設定を行うだけの単純なものであり、例えば CSS を使用する場合の設定と似たようなものです。この例では rgba 表現を使用し、単に色だけではなくアルファ値も設定しています。(アルファ値は色の透明度であり、これについては HTML 5 の CSS 3.0 機能を説明するセクションで再度説明します。) fillStyle プロパティーを設定した後、データ・ポイントに対する棒グラフを fillRect API を使って作成します。ここでは四角形の開始点 (x,y) と高さと幅を指定します。次に、fillStyle を再度定義します。これはレポートに何らかのテキストを出力する必要があるためです。fillText API を使ってキャンバス上にテキストを描画します。fillText API は開始点 (x,y) とテキストを引数に取ります。これを各データ・ポイントに対して行い、棒グラフを作成します。各棒グラフの下にはラベルがあります。

次に、このグラフの他の部分 (縦横軸とグリッド線) を描画する必要があります。まず、横軸と縦軸を描画します。それぞれの軸に対し、線の描画を開始するポイントを moveTo API を使って設定します。次に lineTo API を使用し、その開始点から、lineTo 呼び出しに渡された終了点まで、線を描画します。これらの命令によって実際に線が描画されるわけではなく、stroke API を呼び出すことで線を描画していることに注意してください。縦軸と横軸を描画した後、グリッド線と、グリッド線のラベルを描画します。そのために、グリッド線の間隔を等しく設定し、次に moveTolineTostroke という同じ組み合わせを使ってグリッド線を描画します。

レポートのグラフィックをプログラムによって作成するために必要なコードは、これがすべてです。この例では、最も重要で最もよく使われるキャンバスの API を数多く見てきましたが、他にもいくつか (例えば曲線の描画用の) API があります。これらの API を使うことで驚くほどのことができ、しかもそうしたことを、世の中にある Webkit ベースの任意のブラウザーで行うことができます。グラフィックスに関心がない人の場合にも、HTML 5 には数多くの魅力的なものが CSS 3.0 (Cascading Style Sheets) の形で用意されています。

CSS3 の素晴らしい世界

HTML 5 と言うと、すぐに HTML タグを思い浮かべる人がいるかもしれません。もちろん、HTML 5 には新しいタグが含まれており、次のセクションでは、そうしたタグのいくつかについて説明します。この前のセクションでは <canvas> タグを使って DOM の中にキャンバス・オブジェクトを作成する方法を説明しました。しかしほとんどのコードは JavaScript でした。HTML は HTML 5 全体の中の単なる一部にすぎず、HTML と同じくらい JavaScript と CSS が 重要な部分なのです。HTML 5 の新しいユーザー・インターフェース要素の大部分は、CSS 標準の最新版である CSS 3.0 によって提供されています。図 2 では、CSS 3.0 の新しい手法をいくつか使用した Web ページが Android ベースの携帯電話と iPhone に表示されています。


図 2. モバイル機器に表示された CSS の新機能
このスクリーン・キャプチャーでは CSS の新機能を Android ベースのモバイル機器と iPhone に表示した場合を比較しています。 

図 2 には、CSS の新機能の多くが Android ベースの機器と iPhone に表示されています。左側の画像は Android ベースの機器に表示した場合です。左側の画像の方が大きい理由は、(右側の画像用に使用した iPhone 3GS よりも画面の解像度が高い) Motorola の Droid を使用しているためです。そのため、表示されたページ内容も Droid に表示した場合の方が多くなっています。ただし、「The Gettysburg Address (ゲティスバーグ演説)」という見出しに鏡像があり、その鏡像が iPhone ではフェードアウトされていますが、Droid ではフェードアウトされず、次の見出しを覆ってしまっています。このことは、Android ベースの機器と iPhone にはいずれも Webkit ベースのブラウザーがインストールされていますが、両者の間には微妙な違いがあるため、十分なテストが必要であることを示唆しています。今度は、この素晴らしいページを生成したコードを見てください (リスト 3)。まずページの先頭部分から見ていきます。


リスト 3. ページの前半部分のコード
<!DOCTYPE html> <html> <head>     <script type="text/javascript">         function $(id){             return document.getElementById(id);         }         function init(){             var i=0;             var row = {};             var cell = {};             var topics = ["nth-child", "gradients", "alpha", "text effects",                            "reflections", "transformations"];             for (i=0;i<topics.length;i++){                 row = document.createElement("tr");                 cell = document.createElement("td");                 cell.appendChild(document.createTextNode(topics[i]));                 row.appendChild(cell);                 $("dtable").appendChild(row);             }         }     </script>     <style type="text/css">         header > h1{             color: yellow;             background: -webkit-gradient(linear, left top, left bottom,                               from(blue), to(white))         }         tr:nth-child(4n+1) { color: navy; }         tr:nth-child(4n+2) { color: green; }         tr:nth-child(4n+3) { color: maroon; }         tr:nth-child(4n+4) { color: purple; }          input[type="text"]{             background: rgba(150, 30, 30, 0.5);         }     </style> </head> <body onload="init()">     <header>         <h1>The World of CSS3</h1>         <div>What kind of CSS3 does your browser support?</div>     </header>     <table id="dtable"></table>     <div id="formSection">         <label for="name">What's your name?</label>         <input type="text" id="name"></input>         <button id="rtBtn" onclick="rotate()">Rotate</button>     </div> </body> </html> 

リスト 3 のコードにより、「Gettysburg Address」という見出しの上にあるすべての UI を描画します。このページの後半部分のコードについては、このすぐ後に説明します。

最初に注目する点は、このページのヘッダーでしょう。リストの最後の方にある、この HTML ページの本体部分を見ると、このヘッダーが文字どおり header タグの中にあることがわかります。header タグは HTML 5 における新しい HTML 要素の 1 つです。

今度は style 要素を見てください (リスト 3 で HTML 本体の上)。このテキストは CSS を使ってスタイル設定されており、header > h1 というセレクターが使われています。このセレクターに記述されたルールによって、テキストは黄色に、背景色は青色と白色になります。この背景にはグラデーションがつけられています。-webkit という接頭辞が付いた CSS 機能の例を皆さんが見るのは、これが初めてだと思います。ご想像のとおり、-webkit を付けることで、この CSS は Webkit ベースのブラウザー専用になります。しかしほとんどの場合、これらは CSS 3.0 標準の一部ではあるものの、まだ相変わらず標準が少し流動的な領域でもあります。ほとんどの場合、Webkit ベースのブラウザーも Mozilla Firefox ベースのブラウザーも、これらの機能を実装しています。Mozilla ブラウザー (Fennec と呼ばれる Firefox のモバイル版など。Fennec は Nokia のスマートフォンにインストールされており、ヨーロッパで急速に人気が高まりつつあります) をターゲットにする必要がある場合には、通常は接頭辞の -webkit  -moz に変更します。

次に、トピックのリストを dtable というテーブルを使って表示します。図 2 を見るとわかるように、このテーブルの内容を表示すると、行ごとに色が変わります。こうするためには、CSS で header > h1 セレクターの次のセクションにある tr:nth-child 宣言を使います。nth-child 宣言は、任意の繰り返し要素に使うことができます。述部として使用される公式を渡すことで、その公式がその要素に対して有効なルールかどうかを調べます。ここでは、行番号が 4n+1 で表される場合 (1、5、9 など) の行の色は濃紺色、行番号が 4n+2 で表される場合 (2、6、10 など) は緑色、そして同様に、栗色、紫色、としています。従来もテーブルやリストなどに同じような色付けが必要な場合があったと思いますが、そうした場合は通常、JavaScript を使って退屈な作業を行うしかありませんでした。

最後の視覚要素は赤色のテキスト・フィールドで、「What's your name? (あなたの名前は?)」というラベルと「Rotate (回転)」というボタンが付いています。テキスト・フィールドを赤色にするためには、型専用の入力セレクターを使います。つまりこれは、型がtext である入力要素のみに適用される CSS ルールです。では「Rotate (回転)」ボタンは何をするのか、と思う人がいるかもしれません。リスト 4 のコードを見るとわかるように、このボタンは rotate という関数を呼び出します。


リスト 4. CSS を使用した JavaScript 関数、rotate
function rotate(){     $("formSection").style["-webkit-transform"] = "rotateZ(-5deg)";     $("formSection").style["-webkit-transition"] =            "-webkit-transform 2s ease-in-out";     $("rtBtn").innerHTML = "Undo";     $("rtBtn").onclick = function() {         $("formSection").style["-webkit-transform"] = "";         $("rtBtn").innerHTML = "Rotate";         $("rtBtn").setAttribute("onclick", "rotate()");     } } 

この rotate 関数は JavaScript を使うことで、formSection という div 要素に適用される CSS を変更しています (注: $() document.getElementById() のエイリアスとして使っています)。この div 要素を回転させるためには、この div 要素の -webkit-transform スタイルを rotateZ(-5deg) に設定し、反時計回りに 5 度回転させます。次に、-webkit-transform スタイルを -webkit-transform 2s ease-in-out に設定します。こうすることで回転が 2 秒間で完了するようになり、最初はゆっくりと回転して次第に加速し、そして最後にまた遅くなります。図 3 の左側は、「What's your name? (あなたの名前は?)」フィールドがまだ回転されず、最初の位置にある状態を示しています。図 3 の右側は、このフィールドと「Undo (取り消し)」ボタンが途中まで回転された状態の視覚効果を示しています。


図 3. HTML 要素を回転する
このスクリーン・キャプチャーは、モバイル機器上で HTML 要素を回転した状態を示しています。 

この視覚効果が HTML 5 準拠のブラウザー (Chrome、Safari 4、Opera など) で実際にどう表示されるかについては、「参考文献」のリンクを参照してください。

では、図 2 に示したページの下半分に移りましょう。ここには、画像やテキストに対する効果やレイアウトの興味深い例がいくつかあります。このコードを示したものがリスト 5 です。


リスト 5. 図 2 の下半分のコード
<!DOCTYPE html> <html> <head>     <style type="text/css">         h2 {             -webkit-text-fill-color: blue;             -webkit-text-stroke-color: yellow;             -webkit-text-stroke-width: 1.5px;             background: -webkit-gradient(radial, 430 50, 0, 430 50, 200, from(red),  to(#000));             -webkit-box-reflect:below 5px -webkit-gradient(linear, left top, left  bottom, from(transparent), color-stop(0.5, transparent), to(white));         }         h3{             color: rgba(0,0,255,0.75);             background: rgba(255,255,0,0.5);         }         .xyz{             text-shadow: #6374AB 4px -4px 2px;             white-space: nowrap;             width: 14em;              height: 2em;              overflow: hidden;             text-overflow: ellipsis;              border: 1px solid #bbb;              border-radius: 9px;                          background-color: #fff;         }         .abc {             border: 1px solid #000;             border-radius: 9px;                     -webkit-column-count:4;             -webkit-column-rule: 1px solid #a00;             -webkit-column-gap: 0.75em;         }     </style> </head> <body onload="init()">     <h2>The Gettysburg Address</h2>     <h3>Abraham Lincoln, Gettysburg, PA. November 19, 1863</h3>     <div class="xyz">         Four score and seven years ago our fathers brought forth on this          continent a new nation, conceived in liberty, and dedicated to              the proposition that all men are created equal.     </div>     <div class="abc">         Now we are engaged in a great civil war, testing whether that              nation, or any nation, so conceived and so dedicated, can long              endure. We are met on a great battle-field of that war. We have              come to dedicate a portion of that field, as a final resting              place for those who here gave their lives that that nation might              live. It is altogether fitting and proper that we should do this.     </div> </body> </html> 

要素を 1 つ 1 つ調べながら、このコードを見てみましょう。まず、「The Gettysburg Address (ゲティスバーグ演説)」に対する見出しを作成し、この見出しをいくつかの方法でスタイル設定します。

  1. -webkit-text-fill-color-webkit-text-stroke-color-webkit-text-stroke-width というスタイルを使用して、「外側が黄色で中が青色」という効果を作成します。
  2. バックグラウンドのスタイルが -webkit-gradient に設定され、テキストの背後に赤と黒の背景が配置されます。これは放射型のグラデーションであり、先ほど説明したのは直線的なグラデーションであることに注意してください。スマートフォンではどちらも適切に動作します。
  3. 見出しに -webkit-box-reflect スタイルを設定することで、鏡像を適用します。このスタイルにより、見出しから 5 ピクセル下に見出しの鏡像が設定され、鏡像にはグラデーション効果が適用されます。このグラデーション効果により、鏡像がフェードアウトして見えるようになります。図 2 をもう 1 度見てみると、Android ブラウザーでサポートされていないのは、鏡像にグラデーションを適用するという組み合わせであることがわかります。Android はグラデーションをつけずに単純に鏡像を描画しています。

次の見出しに移ると、この見出しに非常に単純なスタイル設定をしています。このスタイル設定では、単にテキストに色を付け、背景にはテキストと別の色を付けているだけです。この 2 色はどちらも、rgba 関数を使って RGB の値とアルファ透明度を指定しています。アルファ透明度は、値が 1.0 の場合は完全に不透明、値が 0.0 の場合は透明です。

リスト 5 で次に登場するのは、この演説の最初の段落のコードです。このテキストは枠で囲まれており、また新しい border-radiusスタイルを使って枠の角は丸くされています。こうした丸みを帯びた角は現在も Web の至る所で使用されていますが、通常は画像を使って実現されています。CSS 3.0 を使えばそうしたスタイルを容易に実現できることに比較すると、従来の方法は非常に原始的に思えます。この段落のテキストに影をつけるためには、text-shadow スタイルを使います。最後に、この段落の領域が、親の divの幅と高さを設定することで制限されていること、またテキストが大きすぎることに注意してください。従来のブラウザーの場合のように単純にテキストを切り捨てるのではなく、text-overflow スタイルを設定することで、(...) という「以下省略」の効果を見事に実現しています。

最後に、テキストの最終セクションです。このセクションも枠で囲まれていますが、4 列で表示されており、各列は線で区切られています。こうするためには、-webkit-column-count スタイルを設定し、付随する -webkit-column-rule スタイルを設定することで列区切り線を表示します。CSS 3.0 のこうした新機能を使わずにテキストをフォーマット設定しようとすると、いかに面倒か、容易に想像できると思います。こうした機能は単純なヘッダーやフッターを作成する場合にも便利です (ヘッダーもフッターも HTML 5 の新機能です)。ヘッダーやフッターの他、HTML 5 で導入された他の新しいマークアップについても調べてみてください。

新しいセマンティクス

HTML 5 では、HTML のマークアップとして新しい要素が数多く追加されています。これらの要素のなかには、ブラウザーが新しい描画処理を行うものや、JavaScript で利用できるような機能を追加するものもあります。また、そのどちらにも該当しない要素もあります。どちらにも該当しない要素は、<span>、<div>、<p> などと同じように見え、また <span>、<div>、<p> などと同じプログラム・インターフェースを持っています。ただし、こうした要素によって新たなセマンティクスが追加されます。これらの新しいセマンティクスは、視覚に頼らずにページを利用するユーザー (スクリーン・リーダーなどのユーザー補助技術を使用する人達など) にとって重要ですが、検索エンジンのクローラーのようなコンピューター・プログラムにとっても需要です。また開発者にとって、これらの新しいタグは、より表現力の高い CSS セレクターを作成するための手がかりにもなります。図 4 は、そうした新しいセマンティック要素をいくつか使用した Web ページを示しています。


図 4. 新しい HTML 5 要素を iPhone で表示する
このスクリーン・キャプチャーは、HTML 5 の新要素である、header、nav、article、section、aside などの要素を iPhone で表示したものです。 

図 4 の例には header 要素の他、navarticlesectionaside 要素があります。これらの要素によって何か特別な描画が行われるわけではありません。これらの要素はセマンティックな値を追加するだけであり、これらの要素を使用することで、そうしたセマンティックな値と一致する視覚処理を提供する CSS を作成することができます。図 4 に示すページのコードを示したものがリスト 6 です。


リスト 6. HTML 5 の新しいセマンティック要素
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">     <meta name="viewport" content="width=device-width; initial-scale=1.0;          maximum-scale=1.0; user-scalable=0;"/>     <meta name="apple-touch-fullscreen" content="YES" /> <title>Get the latest markup</title> </head> <body>     <header style="border: 1px dotted #000;border-radius: 3px;">         <hgroup align="center">             <h1>Real documents have headers</h1>             <h2>Even if they don't say so</h2>         </hgroup>         <hgroup>         <nav style="-webkit-column-count:3;-webkit-column-rule: 1px solid #a00;">             <a href="new-css.html">CSS3</a><br/>             <a href="report.html">Canvas</a><br/>             <a href="elements.html">Markup</a>         </nav>         </hgroup>     </header>     <article>        <h1>There are a lot of new markup elements in HTML5</h1>        <time datetime="2010-05-16" pubdate>Sunday, May 16</time>        <section>Did you notice that we just had two H1's?         But it's cool!</section>        <aside style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" >             If this page was really popular, I'd put an ad here and make some             serious cash         </aside>     </article> </body> </html> 

これを見ると、先ほど触れた新しい要素がいくつか使われていることがわかります。また、新しい CSS スタイルもいくつか適用することで角の丸い四角形を header の周りに作成し、nav 用に区切り線を作成していることにも注意してください。また、aside にも text-overflow スタイル設定を使用しています。ここでのポイントは、スタイル設定を適用すれば、追加の作業をすることなく、より多くの意味を持つマークアップを作成することができ、しかもそうしたマークアップを、まるで <div> や <span> を使ったかのように表示できるという点です。視覚的なインパクトや、プログラミングにもたらす効果などが大きい HTML 5 の新要素の一例を図 5 に示してあります。(図 5 をテキストのみで表現したものを見るには、ここをクリックしてください。)


図 5. HTML 5 で作成されたフォームを iPhone で表示した場合
このスクリーン・キャプチャーは、iPhone 上に表示される、HTML 5 で作成したフォーム要素を示したものです。 

図 5 の画面には、HTML 5 で利用できるようになった多くの新しいフォーム要素が使われています。多くの場合、これらの要素は既存の要素と同じように見えますが、ブラウザーによって、これらのリッチなフォーム要素の優れた視覚表現が実現されるはずです。その一端を垣間見るために、このフォーム要素を Opera デスクトップ・ブラウザーで表示した、図 6 を見てください。(図 6 をテキストのみで表現したものを見るには、ここをクリックしてください。)


図 6. HTML 5 のフォーム要素を Opera で表示した場合
このスクリーン・キャプチャーは、Opera 上に表示される、HTML 5 で作成したフォーム要素を示したものです。 

Opera は HTML 5 の機能の実装において最先端を走ってきましたが、なかでも新しいフォーム要素に関してはなお一層のことです。ここで、リスト 4 リスト 5 を生成したコードを見てください。このコードを見ると、なぜ Opera ではさまざまな要素が図 6 のように描画されたのかをよく理解することができます。そのコードがリスト 7 です。


リスト 7. HTML 5 のフォーム要素を示すコード
<form id="settings"> <fieldset id="inputs" style="border: 1px solid #000;border-radius: 6px;">     <legend>Settings</legend>     <label for="name">Username</label>     <input id="name" name="name" type="text" required autofocus /><br/>     <label for="name">Name</label>     <input id="name" name="name" type="text"            placeholder="First and last name" required /><br/>     <label for="email">Email</label>     <input id="email" name="email" type="email"                       placeholder="example@domain.com" required /><br/>     <label for="phone">Phone</label>     <input id="phone" name="phone" type="tel"            placeholder="Eg. +447500000000" required /><br/>     <label for="dob">Date of birth</label>     <input id="dob" name="dob" type="date" required/>     <fieldset style="border: 1px dotted #000; border-radius: 6px">         <legend>Preferred Contact Method</legend>         <ol>             <li>                 <input id="emailMeth" name="contactMethod"                              type="radio">                 <label for="emailMeth">Email</label>             </li>             <li>                 <input id="phoneMeth" name="contactMethod"                              type="radio">                 <label for="phoneMeth">Phone</label>             </li>         </ol>     </fieldset>     <label for="climate">Preferred external temperature</label>     <input id="climate" name="climate" type="range" min="50"            max="100" step="5" value="70"/><br/>     <label for="color">Favorite color</label>     <input id="color" name="color" type="color"/><br/>     <label for="referrer">Where'd you hear about us?</label>     <input type="url" name="refUrl" id="referrer" list="urls"/>     <datalist id="urls">         <option label="TechCrunch" value="http://www.techcrunch.com/">         <option label="ReadWrite Web" value="http://www.readwriteweb.com/">         <option label="Engadget" value="http://www.engadget.com/">         <option label="Ajaxian" value="http://www.ajaxian.com/">     </datalist><br/>     <button type="button" onclick="checkInputs()">Save</button> </fieldset> </form> 

リスト 7 のフォーム要素は HTML 5 の新機能を数多く示しています。2 つの新しい属性、required  autofocus に注目してください。required 属性はフォームを検証する際に使われ (これについては後ほど説明します)、また autofocus 属性を使うと、ページ上のその要素が選択されてフォーカスされるようになります。さらに、いくつかの要素に placeholder テキストがあることに注意してください。これは多くの Web サイトで長年使われてきた、テキスト・ボックスの中に何らかの例や説明文を配置するためのパターンですが、開発者は従来、必ずコードに手を加えなければなりませんでした。これが iPhone でいかにうまく実装されているかを、図 4で見ることができます。

次に、入力要素に使用できる新しい型に注目する必要があります (email、phone、date、range、color、url など)。これらの型はすべて、現在は iPhone や Android のブラウザーでテキスト・フィールドとして描画されますが、それはセマンティクスの面で HTML 5.0 ほど適切ではない HTML 4.0を使って作成された場合の表示です。図 5 を見ると、それらの型が将来どのように表示されるかを理解することができます。日付の入力欄がフォーカスされると、新しい UI (ポップアップ・カレンダー) が Opera に表示されます。新しい UI が表示されるのは、図 7  url 入力の場合も同じですが、それは url 入力であるからではなく、この入力が list 属性を持っているからです。list 属性によって datalist 要素が参照され、datalist 要素の中には、そのフィールドに許可される値が含まれています。あるフィールドにフォーカスを移すと、そのフィールドが取り得る値 (この場合はいくつかの URL) が datalist から取得されて表示されます。これは、よく使われている Ajax スタイルの auto-suggest フィールドに似ています。図 7 では日付を入力する機能とデータリストから入力する機能の両方を見ることができます。


図 7. HTML 5 での日付の入力とデータリストからの入力
このスクリーン・キャプチャーは HTML 5 での日付の入力とデータリストからの入力の機能を示しています。 

Webkit が急速に進化し続けていることから、こうしたさまざまな入力タイプによって、さらに有用な視覚表現が可能になると思われます。Opera を見ることで、将来を的確に展望することができます。こうした入力フィールドの多くは検証機能も持っており、また HTML 5 には検証のための新しい API が非常に豊富に用意されています。これらの機能は iPhone や Android ベースの機器ではまだ動作しませんが、デスクトップ版のブラウザーでは動作するため、モバイル・ブラウザーにも間もなく登場するはずです。こうした新しい検証 API の使い方をリスト 8 で見てください。


リスト 8. HTML 5 の検証 API の実際
function checkInputs(){     var inputs = document.getElementById("inputs").childNodes;     var len = inputs.length;     var i = 0;     var input = null;     var errors = [];     for (i=0;i<len;i++){         input = inputs.item(i);         if (input.nodeName == "INPUT"){             if (input.validity){                 if (!input.checkValidity()){                     errors.push(input.validationMessage);                 }             }         }     }     var errMsg = "There are " + errors.length + " errors";     var notify = function(){         var notification =              webkitNotifications.createNotification(null, "Errors!", errMsg);         notification.show();     };     if (window.webkitNotifications){         if (webkitNotifications.checkPermission()){             webkitNotifications.requestPermission(notify);         } else {             notify();         }     } else {         alert(errMsg);     } } 

各入力要素には validity プロパティーがあります。このプロパティーを使うこともでき、あるいは checkValidity() 関数を使って true または false を返すこともできます。また validationMessage プロパティーを使うと、ローカライズされたエラー・メッセージを得ることができます。この記事の執筆時点では、最新のデスクトップ・ブラウザーでも validationMessage に対して一貫性のあるレスポンスや標準的なレスポンスは返しません。そのため、validationMessage の使い方は限定されています。検証オブジェクトを使うことで、様々なタイプのエラー (valueMissingrangeOverflowrangeUnderflowpatternMismatchtooLong など) を調べることができます。例えば、ある要素に必須の属性があり、ユーザーがその属性を空白のままにしたとすると、validity.valueMissing が真になります。

最後に、リスト 8 で検証エラーをすべて判断した後、webkitNotifications を使おうとしていることに注意してください。これはデスクトップ・コンピューターでのシステム通知と似ており、最新バージョンの Chrome で利用することができます。ということは、iPhone や Android のブラウザーにも webkitNotifications が間もなく登場すると期待することができます。この API の使い方は単純です。唯一注意が必要な点は、皆さんのサイトがこの API を使用することをユーザーが許可したかどうか、チェックする必要がある点です。許可されていない場合には使用許可を要求する必要があり、許可された場合の呼び出し対象となる関数を渡す必要があります。

まとめ

この記事では、UI に関連した HTML 5 の新機能の多くについて、新しい要素から新しいスタイルや描画キャンバスに至るまで、駆け足で説明しました。これらの機能はすべて (最後に説明した明らかな例外を除き)、iPhone や Android ベースの機器に見られる Webkit ベースのブラウザーで利用することができます。Blackberry や Nokia のスマートフォンなど、よく使われるプラットフォームには、この記事で説明した技術と同じ技術を活用した強力なブラウザーが搭載されつつあります。皆さんはモバイル Web 開発者として、多種多様なユーザーを対象に、これまで HTML や CSS、JavaScript などによってデスクトップ・ブラウザーで利用してきたどんな機能よりも強力な視覚機能を活用することができます。この連載の過去 4 回の記事では、こうした新しくて素晴らしい能力のモバイル・ブラウザーで利用可能な、他の新しい技術の数々 (ジオロケーションや Web ワーカーなど) についても学びました。もはやモバイル Web アプリケーションは、皆さんが長年プログラムを作成してきた Web アプリケーションのレベルを少し下げたものではありません。モバイル Web アプリケーションはあらゆる可能性を秘めた、強力なアプリケーションなのです。

0 件のコメント:

コメントを投稿