デザイナーにも分かりやすいjQuery入門講座|jQueryの使い方

このエントリーをはてなブックマークに追加
索引
Core:コアとなる仕組み
Selectors:セレクタ
Attributes:属性
Traversing:対象の変更
Manipulation:操作
CSS:スタイルシート
Events:イベント
Effects:演出効果
Ajax:xml等との連携
Utilities:ユーティリティ
Data:データ
Miscellaneous:諸々
Deferred:処理管理
Callbacks:コールバック
Internals:内部処理

.ajaxSend( )ajax通信の前に実行する処理を設定

構文

ajax通信の前に実行する処理を設定返値:jQueryオブジェクト
$(document).ajaxSend( function )ver1.0〜
引数に設定するfunctionは以下の引数を受け取ります
・第1引数:イベントオブジェクト
・第2引数:jqXHRオブジェクト
・第3引数:ajaxのセッティング情報

機能

ajaxSendはページ内で発生したajax通信のリクエストを送る前に実行するfunctionを設定します。ページ内全てのajax通信に反応するため「グローバルイベントハンドラ」と呼ばれ、セレクタにはdocumentを利用します(v1.8以前はdocument以外も設定できますがdocumentにしておきましょう)。

グローバルイベントはjQuery.ajaxSetupメソッドのglobalプロパティがtrueの時にしか利用できません(デフォルトはtrueです)。

解説

ajax通信の前に実行する処理を設定する

サンプル(ajaxSend/01.html)を開いてbody内にdiv要素とbutton要素があることを確認して下さい。jQueryでは、まず以下の部分を確認して下さい。ajaxSendによってページ内のajax通信を開始する前にsendFuncを実行するようにしています。

$(document).ajaxSend(sendFunc);;

sendFuncは以下の様に記述され、div要素内に「ajaxSend」と表示するようにしています。

function sendFunc(){
	$("div").text("ajaxSend");
};

次にajax通信を開始する部分を確認します。以下の様にbuttonをクリックしたらjQuery.getメソッドを利用してデータを読み込むようにしています。このサンプルではajax通信が成功した時の処理は必要ないので、jQuery.getメソッドにはfunctionを設定していません。

$("button").click(function(){
	$.get("../data/simple.txt");
});

結果として、buttonをクリックするとdiv要素内に「ajaxSend」と表示され、ajaxSendメソッドが機能していることを確認できます。ajaxSendの引数に設定したfunctionは無名関数で設定することが多いので、そのサンプルも用意しました。→サンプル(ajaxSend/01b.html

$(document).ajaxSend(function (){
	$("div").text("ajaxSend");
});

functionの引数を利用する

ajaxSendに設定するFunctionは以下の様な構文になっています。このfunctionは3つの引数を受け取るため、様々な情報を取得することができます。

ajaxSendに設定するFunctionの構文
function 任意の名前(イベントオブジェクト, jqXHRオブジェクト, ajaxのセッティング情報){
 ajax通信の前に実行したい処理
}

第1引数はイベントオブジェクトです。第2引数はjqXHRオブジェクトで、jQuery用に拡張されたXMLHttpRequestオブジェクトです(参考:wikipedia「XMLHttpRequest」)。第3引数は現在のajax通信に関する設定情報を持ったobjectオブジェクトです。詳しくはjQuery.ajaxメソッドの「設定可能なプロパティの紹介」を確認して下さい。

サンプル(ajaxSend/02.html)を開いてbody内構成がajaxSend/01b.htmlと同じ事を確認してください。jQueryもajaxSend/01b.htmlとほとんど同じで、異なるのは以下の様に設定したfunctionで引数を利用している点だけです。

$(document).ajaxSend(function(eo, myXHR, settings){
	$("div").html(myXHR.responseText);
	$("body").append("eventType = " + eo.type + "<br/>");
	$("body").append("url = " + settings.url);
});

まず2行目ではjqXHRオブジェクトのresponseTextプロパティを利用することで「受信データ」を取得しhtmlメソッドでdiv要素内に表示します。

3行目ではイベントオブジェクトのtypeプロパティを利用して発生したイベントの種類を取得し、appendメソッドを利用してbody内に追加しています。4行目ではajax通信の設定オブジェクトにurlプロパティを利用して、読み込んだデータのurlを取得しています。

結果として、buttonをクリックするとdiv要素の下にイベントのタイプ(ajaxSend)と読込データのurl(../data/simple.txt)が表示されますが、読込が完了する前なので受信データをdiv要素に表示することはできません

関連項目

成功/失敗にかかわらずajax通信が完了した時の処理を設定したい場合はajaxCompleteを利用して下さい。
ajax通信が成功した時の処理を設定したい場合はajaxSuccessを利用して下さい。
ajax通信が失敗した時の処理を設定したい場合はajaxErrorを利用して下さい。

メモ

通信前に通信の詳細をチェックする

ajaxStartメソッドとajaxStopメソッド以外のグローバルイベントハンドラは、引数に設定したfunctionの第3引数によって通信の詳細/セッティングを取得できます。ajaxSendメソッドの場合は他のグローバルイベントハンドラに比べて、これらの情報を利用することが多いような気がします。なので簡単なサンプルを作成しました。

サンプル(ajaxSend/test00.html)を開いてbody内に2つのbutton要素(idはinとout)があることを確認してください。

<button id="out">サイト外のデータにアクセス</button>
<button id="in">サイト内のデータにアクセス</button>

jQueryは、まず以下の部分を確認してください。id属性がoutの要素がクリックされたらgoogleのトップページ(つまり外部ドメイン)を読み込もうとします。id属性がinの要素の場合はajaxSend/01.htmlと同じようにsimple.txtを読み込もうとします。

$("#out").click(function(){
	$.get("https://www.google.co.jp");
});			
$("#in").click(function(){
	$.get("../data/simple.txt");
});

続いて以下の部分を確認してください。ajaxSendメソッドを利用して、通信を開始する前に通信の詳細(functionの第3引数「settings」)をチェックするようにしました。今回のサンプルではcrossDomainプロパティを利用して外部ドメインか否かをアラートで表示するようにしました。

$(document).ajaxSend(function(eo, myXHR, settings) {
	alert("crossDomain = " + settings.crossDomain);
});

結果として「サイト外のデータにアクセス」ボタンをクリックすると、アラートでcrossDomainがtrueであることが確認できます。「サイト内のデータにアクセス」ボタンではfalseが表示されます。

この結果を踏まえ外部ドメインのデータを読み込もうとしたら通信をキャンセルするサンプルを作成しようとしたのですが、javaScriptは元々外部ドメインのデータが利用できない仕様でした...(詳細は次項)。

状況によって通信をキャンセル

機能しないサンプルですが有用なのです

ローカル環境では機能したサンプルがサーバーにアップしたら機能しませんでした...。javaScriptはセキュリティの関係でクロスドメインのデータ読込ができないことを初めて知りました(今まで別ドメインのデータを読み込む必要に迫られたことがなかったので...)。なので削除しようとも思ったのですが、考え方としては有用だと思うので残すことにしました。

また関連項目としてajaxPrefilterも合わせて確認してください。これはページ全体の通信に対しての処理設定でき、さらにセッティングの内容も変更できる強力なメソッドです。

本家サイトには実用的なサンプルが無いのですが、これは結構便利なメソッドなのでは?と思いサンプルを作成しました。今回作成したサンプルは読み込むデータが外部(クロスドメイン)の場合は読込をキャンセルするものです。まずは外部だろうと何だろうと読み込んでしまうサンプルを確認します。

サンプル(ajaxSend/test01.html)を開いてbody内に2つのbutton要素(idはinとout)があることを確認してください。

<button id="out">サイト外のデータにアクセス</button>
<button id="in">サイト内のデータにアクセス</button>

jQueryは、まず以下の部分を確認してください。id属性がoutの要素がクリックされたらgoogleのトップページを読み込みます。id属性がinの要素の場合はajaxSend/01.htmlと同じようにsimple.txtを読み込みます。

$("#out").click(function(){
	$.get("https://www.google.co.jp");
});			
$("#in").click(function(){
	$.get("../data/simple.txt");
});

読込が完了した時の処理は以下の様に、ajaxSuccessを利用してbody要素内に内容を追加します。

$(document).ajaxSuccess(function(eo, myXHR, settings) {
	$("body").append(myXHR.responseText);
});

jQueryを確認したら、実際に2つのbuttonをクリックしてください(id属性inのbuttonからクリックした方が分かりやすいと思います)。2つとも情報が追加されると思います(googleのページはhtmlのみしか読み込まないため画像などは全てリンク切れになります)。

ではajaxSendメソッドを利用して、外部データの場合は通信をキャンセルするようにしましょう。サンプル(ajaxSend/test02.html)を開いてbody内の構成はajaxSend/test01.htmlと同じ事を確認してください。jQueryは以下の処理が追加されているだけです。

$(document).ajaxSend(function(eo, myXHR, settings){
	if (settings.crossDomain){
		myXHR.abort();
	};
});

まず2行目に着目してください。if文の条件式にある「settings」は第3引数のsettingsで、ajaxSend/02.htmlではurlの情報を取得しました。今回はcrossDomainの情報を取得しています。このsettingsで利用できるプロパティはajaxメソッドの設定可能なプロパティの紹介で確認できます。

crossDomainプロパティは外部にアクセスする場合は「true」となるため、外部にアクセスしようとした場合にif文の処理(3行目)が実行されます。3行目では第2引数にわたされたmyXHRに対してabortメソッドを利用して通信を中止しています。abortメソッドはjQueryのメソッドではなくXMLHttpRequestで利用できるメソッドです。wikipediaのXMLHttpRequest「オブジェクトの構成」に利用できるメソッドが一覧されています。

結果としてgoogleのデータを読み込もうとした場合は、ajaxSendメソッドによって読み込む前に通信がキャンセルされます。settingsで利用できるプロパティは色々あるので、このような仕組みは便利な気がします。

ajaxPrefilterメソッドとの違い

ajaxPrefilterも通信のセッティングを利用できますが、さらにセッティングの内容も変更できます。ajaxSendメソッドは変更できないそうなのですが、何となく試してみました(結果からいうと、やはりダメでした)。

サンプル(ajaxSend/test03.html)を開いてbody内の構成はajaxSend/test02.htmlと同じ事を確認してください。jQueryもほとんどajaxSend/test02.htmlと同じですが、以下の様にajaxSendメソッドで設定した処理内容を変更しています。

$(document).ajaxSend(function(eo, myXHR, settings){
	//設定の値としては変更されますが、読込は行われないようです。
	settings.url = "../data/simple.txt";
	alert(settings.url)
});

ポイントはurlの内容を「../data/simple.txt」に変更している点です。これでgoogleの読込も「../data/simple.txt」に変更されるのでは?と期待したのですが、「サイト外のデータにアクセス」のボタンをクリックしても変化はありませんでした。やはりajaxSendメソッドではセッティングの内容を変更することはできないようです。

しかしアラートの内容は変わっているので、通信内容の確定はajaxSendメソッドで設定された処理よりも前に行われていると考えられます。ですからajaxSendメソッドの時点で値を変更しても、通信には反映されないのだと思います。