前回は、要素を取得しイベントハンドラを登録するといったイベントの取り扱いについてまとめた。ここでは、スタイルの操作、AJAX、フォームの取り扱いについて解説する。
1 スタイル
スタイルの操作は、ページの内容とは別にページの見た目を操作するものである。見やすさやかっこよさはCSSの知識、わかりやすさはJavaScriptの知識によって強化できる。JavaScriptによる動的なスタイル変更の目的はユーザに対する視覚フィードバックである。
スタイル変更方法
スタイルの変更方法には以下の方法がある。
- classNameプロパティでclass名を変更する:変更前と変更後のclass名に対応するスタイルをあらかじめCSSで定義しておいて、JavaScriptでclass名を切り替える。class名を変更することでどの要素が影響を受けるのかを把握しておく必要がある
- classListプロパティでclass名を変更する:classNameプロパティを操作するよりもわかりやすくclass名を操作できる
- styleプロパティを変更する:スタイルの変更範囲は明確にその要素に限定される。機能とデザインの分離ができない
- スタイルシートそのものを変更する:有効・無効の設定も可能。link要素、style要素のdisabledプロパティをtrueにするとスタイルシートを無効にできる
位置の指定
位置を指定する上で重要なポイントはposition属性とマウスポイントの位置である。position属性は以下の4つのどれかの値が指定できる。
- static:デフォルト値
- fixed:ブラウザウィンドウを基準とした相対位置を指定
- absolute:その要素を含む要素からの相対位置を指定
- relative:HTMLに記述されたタグに従って配置された後、その位置を基準とした相対位置で配置できる
位置
マウスでクリックした位置の近くにボックスを表示させるという機能を実現するためには、クリックした位置を知る必要がある。MouseEventが発火した際のEventオブジェクトにはその位置を習得するためのいくつかのプロパティがある。このとき問題になるのが、クリックした位置がどの点を基準としたものかである。
- スクリーン座標:screenX、screenYプロパティでスクリーン座標が取得できる。スクリーン座標は、コンピュータのディスプレイの左上を原点とする座標系
- ウィンドウ座標:clientX、clientYプロパティでウィンドウ座標が取得できる。ウィンドウ座標は、ブラウザの表示領域の左上の原点とする座標系
- ドキュメント座標:pageX、pageYプロパティで文書内での位置が取得できる。ドキュメント座標は、ドキュメントの左上を原点とする座標系
- 特定の要素内での相対座標:layerX、layerYプロパティあるいはoffsetX、offsetYプロパティでイベントが発火した要素内での相対座標を取得できる
アニメーション
定期的にスタイルを少しずつ変化させることでアニメーションが実現できる。移動アニメーションならposition: absoluteが指定された要素でleftプロパティの値を少しずつ変更する。フェードイン・フェードアウトを実現するには要素の透明度(opacity)の値を少しずつ変更する。
2 AJAX
AJAXとはAsynchronous JavaScript + XMLの略称である。実際にはAJAXという言葉は「ページ遷移せずに、コンテンツを非同期にロードし、ページを書き換える技術」という意味で使われる。
非同期処理の利点
非同期処理に利点は、ユーザにムダな待ち時間を発生させないことである。
XMLHttpRequest
JavaScriptからサーバに対して動的にリクエストを送るにはXMLHttpRequestオブジェクトを利用する。
基本的な処理の流れ
XMLHttpRequestオブジェクトができたら、サーバのURLを指定してリクエストを送信する。onreadystatechangeイベントハンドラはXMLHttpRequestオブジェクトの状態が変化したときに呼び出されるイベントハンドラである。statusにはレスポンスのステータスコードが格納される。responseTextにはサーバからのレスポンスが文字列で格納されている。open()に渡している引数は、HTTPメソッドと通信先サーバのURLである。setRequestHeader()はリクエストヘッダを設定するメソッドである。実際にサーバへリクエストを送信するのがsend()である。
同期通信
同期通信を行う場合はonreadystatechangeイベントハンドラを設定する必要はない。send()を実行した時点で処理が待機されるので、send()の後に続けてレスポンスに対する処理を記述すればよい。
タイムアウト
リクエストのタイムアウトとは、一定時間でレスポンスが取得できなかった場合にリクエストをキャンセルすることである。同期通信の場合、通信に時間がかかるとsend()メソッドで待ちが発生することになり、他の処理が行えなくなるためである。
レスポンス
- 汎用的なレスポンス:responseTextプロパティで参照できる
- XMLによるレスポンス:responseXMLプロパティを使った方がよい。XMLを解析した結果を参照することができる
- JSONによるレスポンス:JSON.parse()メソッドを使う
クロスオリジン制限
クロスオリジン制限は異なるオリジンに対する通信が制限されているという意味である。オリジンとはURLのプロトコル(http: または https:)、ホスト名、ポート番号で構成される要素である。Webの世界ではセキュリティの観点からオリジンが同じ場合だけ通信が許可される。これを同一オリジンポリシーという。
クロスオリジン通信
クロスオリジンとは異なるオリジンに対してリクエストを発行することを意味する。JavaScriptでクロスオリジン通信を実現するための方法としては以下の4つの手法が確立されている。
- JSONP
- iframeハック
- window.postMessage()
- XMLHttpRequest level 2
JSONP
JSONP(JSON with Padding)とは、JSONデータに関数名を付加するということである。サーバからデータを取得して、関数の引数として渡してもらうところまでやってしまおうというのがJSONPのアイデアである。
iframeハック
iframeを利用したクロスオリジン通信は少し複雑である。登場する要素は以下の3つ。
- 親ページ(my.example.com)
- 子iframe(other.example.com)
- 孫iframe(my.example.com)
親ページと孫iframeが同じドメインであることが重要である。
- APIリクエスト:my.example.comのページからother.example.comにあるhtmlを指定してiframeを作成する。URLにハッシュフラグメントを含めることがポイント
- レスポンス:other.example.comのページでは、XMLHttpRequestを利用したりしてother.example.comの機能を呼び出してデータを取得する
- コールバック:孫iframeのonloadで親ページの関数を呼び出す
window.postMessage
HTML5で定義されているwindow.postMessageを使って安全にクロスオリジン通信を行うことができる。
XMLHttpRequest Level 2
XMLHttpRequest Level 2ではクロスオリジン通信が可能とする機能が追加されている。ただし、クロスオリジンを行うにはサーバ側の許可が必要で、”Access-Control-Allow-Origin”というHTTPヘッダをレスポンスに含めることでアクセス可能なドメインを指定することになる。
クロスオリジン通信のセキュリティ問題
異なるドメインとの通信にはセキュリティリスクがある。
3 フォーム
フォームは主にユーザ登録など、データをサーバに送信して登録する処理に利用される。フォームの制限として一番大きいのはsubmitするとページ遷移が発生することである。AJAXはページ遷移を発生させずにページを書き換える技術である。ここではフォームをJavaScriptを使ってより機能的にする方法を述べる。
フォーム要素
フォーム要素はHTMLFormElementというHTMLElementを継承したインターフェースを持つ。HTMLFormElementインターフェースで定義されているプロパティは以下の10個。
- elements:form内のinput要素一覧
- length:form内のinput要素の数
- name:formの名前。JavaScriptから参照するときに利用する
- acceptCharset:formがサポートする文字セット
- action:formのaction要素
- enctype:formのcontent type
- method:データを送信するときに使用するHTTPメソッド
- target:actionの結果を書き込む対象
- submit():データを送信する
- reset():formを初期状態に戻す
フォームコントロール要素
フォームコントロール要素とは、フォームで入力を受け付ける要素である。フォームコントロール要素としてよく使われるものはinput要素、select要素、button要素、textarea要素などがある。
内容の検証
- 内容の検証の必要性:サーバ通信によるタイムロスを防げる。最終的にはサーバサイドでデータをチェックすべき
- 内容の検証のタイミング:submitボタンを押されたときやデータが入力された直後
検証に利用できるイベント
- submit:submit()メソッドを呼び出したときは発火しない
- focus, blur:input要素にフォーカスが当たるタイミングでfocusイベントが発火する。blurイベントはフォーカスが外れたタイミングで発火する
- change:input要素の値が変更されたタイミングで発火する
- keydown, keyup, keypress:キーボード入力があるたびに発火する。keydownはキーが押されたとき、keyupは押されたキーが放されたとき、keypressはキーが押されて文字が入力されたときに発火する
- input:input要素に何か入力があった場合に発火する
フォームを使ってページ遷移を発生させない方法
form要素にはtargetプロパティがある。formはこのtargetプロパティに指定されたフレームやウィンドウにsubmitの結果のレスポンスを描画する。targetプロパティに値が設定されていなければそれは自分自身が属するフレームおよびウィンドウになるので、ページ遷移が発生する。
最後に
スタイルの操作は、ページの内容とは別にページの見た目を操作するものである。AJAXはページ遷移せずに、コンテンツを非同期にロードし、ページを書き換える技術である。フォームは主にユーザ登録など、データをサーバに送信して登録する処理に利用される。DOM操作、イベントの扱い、スタイルの操作、AJAX、フォームの取り扱いがWebアプリを作る上で必須となる知識である。
次回は、 機能だけをシンプルに実装できる jQueryを中心としたライブラリについて解説する。
![]() |