jQuery – イベント

ソース別イベント

個別イベントハンドラの一般形

要素に発生しうるイベントは下記一覧の通りで、イベントが発生した時、対応したハンドラが呼ばれる。

たとえばクリックイベントに対する処理の記述は以下の通り。

ただしこの形式のハンドラは、動的に追加された要素には対応していない。

マウスイベント

click クリック時
dblclick ダブルクリック時
mousedown マウスボタンを押した時
mouseup マウスボタンを離したとき
mouseover マウスカーソルが要素内に入った時(子要素を含む)
mouseout マウスカーソルが要素から出たとき(子要素を含む)
mouseenter マウスカーソルが要素に入った時(子要素は除く)
mouseleave マウスカーソルが要素から出た時(子要素は除く)
mousemove 要素内でマウスカーソルが移動した時
hover mouseenter / mouseleaveを一つにまとめたもの
toggle クリックの度に異なる処理を実行。v1.9以降廃止。

キーイベント

keydown キーを押した時
keypress キー入力があった時
keyup キーを離した時
focusin フォーカスされた時(子要素を含む)
focusout フォーカスが外れた時(子要素を含む)

フォームイベント

focus フォーカスされた時(子要素は除く)
blur フォーカスが外れた時(子要素は除く)
change 内容が変更された時
select 文字が選択された時
submit データ送信時

ブラウザイベント

resize リサイズした時
scroll スクロールした時
error エラーが発生した時

ロードイベント

load 読み込みが完了した時
unload ページから離れる時
ready DOMの読み込みが完了した時

イベントハンドラ・アタッチメント

イベントハンドラを要素にアタッチするメソッド。

たとえばon()メソッドの書き方の一つとして以下がある。

on()メソッドのハンドラとして、1つのイベントオブジェクトを引数に持つ関数を指定する。

探索範囲を限定してオブジェクトを探索する場合は以下の構文を用いる。

下表のbindoffまでのうち、現在はon/offメソッドのみ使えばよい。

また、on/offメソッドに指定できるイベントは、上記ソース別イベントの内、hoverとtoggle以外で指定する。

bind jQueryで最初に登場したアタッチメント。動的な要素に対応していないため、v1.3でliveが導入される。
unbind bindで設定された処理を解除。
live 動的な要素に対応したアタッチメント。処理負荷が高いため、v1.9で廃止された。
die liveで設定された処理を解除。v1.9で廃止。
delegate イベントの調査範囲を限定できるアタッチメント。v1.7で”on”に移行。
undelegate delegateで設定された処理を解除。
on イベントハンドラ・アタッチメントの最終形。
off onで設定されたイベント発生時の処理を解除。
one 1回だけ利用できるイベント発生時の処理を設定。構文はonと同じ。
triggerHandler 要素に指定したイベントを発生させるが、要素に対するブラウザ標準の機能は実行されない。
trigger 要素に指定したイベントを発生させ、ブラウザ標準の機能も実行させる。

イベントオブジェクト

概要

イベントオブジェクトはイベントハンドラに必ず渡されるobjectオブジェクト。イベント発生ごとに作成される。

基本形のコンストラクタでは、引数にイベント名を指定して作成する。たとえばclickイベントに対応するイベントオブジェクトは以下の様に作成される。

プロパティ

e.type イベントの種類
e.data イベントハンドラに渡された情報
e.pageX イベントが発生したX座標(ブラウザの座標系)
e.pageY イベントが発生したY座標(ブラウザの座標系)
e.timeStamp イベントが発生した時間(1970-01-01からのミリ秒)
e.which 正規化されたキーコード
e.result 直前に実行したイベントハンドラが返した値
e.namespace 名前空間に設定された名称
e.target イベントが発生したDOM要素
e.currentTarget 現在のDOM要素
e.delegateTarget デリゲート時の調査範囲のDOM要素
e.relatedTarget イベントの発生に関連したDOM要素

メソッド

e.stopPropagation()
バブリング(親要素方向へのイベントの伝播)を停止。
e.stopImmediatePropagation()
バブリングとイベントハンドラの実行を停止。
e.preventDefault()
ブラウザ標準の機能を停止。
e.isPropagationStopped()
stopPropagation()メソッドが実行されたかを調査。
e.isImmediatePropagationStopped()
stopImmediatePropagation()メソッドが実行されたかを調査。
e.isDefaultPrevented()
preventDefault()メソッドが実行されたかを調査。

 

jQuery – メソッド

値の取得

メソッドを通して、オブジェクトの持つプロパティなどを取得する。

※引数がない場合もある。

オブジェクトの操作

メソッドによりオブジェクトにプロパティを設定したり、動作させたりする。

※引数がない場合もある

イベント処理

構文1

オブジェクトに発生したイベントに対応して呼び出されるハンドラで、引数に処理を記述。

この構文では、後から動的に追加された要素には対応できない。

ハンドル用の関数を別に定義して引数に関数名を書いてもよいが、多くの場合無名関数が使われる。

構文2

動的に追加された要素にも対応するため、イベントが発生するたびに指定された範囲内でセレクタで指定されたオブジェクトを探索する。

この場合のon()メソッドは”イベントハンドラ・アタッチメント”の一つで、特定のイベントとそれに対するハンドラを結び付ける機能を持つ。

イベント名とセレクタは文字列で指定。

以下の例では、body要素の中の任意の要素がクリックされるとalertが立ち上がる。この場合は、H1、H2のいずれをクリックしてもalertが立ち上がる

また、on()メソッドの引数を以下のようにすると、H1をクリックしても反応せず、H2をクリックした時だけalertが立ち上がる。

イベントの種類、イベントハンドラ・アタッチメントについては、jQueryのイベントを参照。

 

CoffeeScript – “$ ->”? 無名コールバック関数の記法について

概要

CoffeeScriptのコードには、jQueryの利用時を含めて以下のような無名のコールバック関数の記述が頻繁に現れる。

これについて、改めて整理してみた。

無名関数のクロージャ

CoffeeScriptの以下のコードを考える。

これをコンパイルしたJavaScriptのコードは以下のようになる。

“->”以下インデント部分が一つの関数とみなされ、無名関数として定義されている。

コールバックの登録

生真面目な書き方

無名関数をコールバック関数として、呼び出し元の関数の引数で登録するのに、生真面目に引数を()で括って書くと以下のようになる。

実行結果は意図したとおり、呼び出し元の中でコールバックが呼ばれている。

これをコンパイルしたJavaScriptコードは以下の通りで、無名関数が引数として渡されている。

()を省略した書き方

CoffeeScriptでは関数の引数を()で囲わずに書けるので、以下のように書ける。

実行結果は変わらず、これをコンパイルしたJavaScriptコードも上と全く同じ。

引数の改行~失敗

CoffeeScriptはかなり自由に改行することができるので、先のコードの引数を”->”の直後で改行してみる。

結果は想定外で、呼び出し元でコールバックが実行されていない。

JavaScriptへのコンパイル結果は、以下のように少し変化している。

想定外の動作の理由は、”caller ->”の次のconsole.log()の行が前の行と独立した命令として解釈されたため。

  • 呼び出し元に内容がない無名関数”->”が渡される
    • コールバック関数は内容がないため無反応
  • console.log()が実行される

引数の改行~インデントが必須

ここでconsole.log()の行をインデントすると、console.logの行が関数callerの内容と解釈されるため、console.log()は無名関数”->”の実行内容とみなされる。

JavaScriptコードも以下のように意図した結果になった。

引数の改行~別の想定外

コールバックを引数として()で括ったうえで改行した場合、また異なる結果となる。

コンパイル結果を見ると一目瞭然で、

先のCoffeeScriptコードと等価なコードは以下の通りで、上のJavaScriptと同じコードにコンパイルされる(“->”を()で括らないと”想定外のcomma”エラーになる)。

呼び出しの際に定義された引数の数より多く引数を渡しても過剰な引数は渡されないが、その引数が実行可能な文の場合には実行される。

この例ではcosole.log()は引数として渡されないが、呼び出し元の関数実行前にconsole.log()文として実行され、その後に内容なしの無名関数をコールバックとして呼び出し元が実行されるため、意図とは異なる結果になる。

なお()をつける場合でも、インデントによって意図した結果となる(最後の”)”はconsole.log()文の末尾につけてもok)。

複数行のコールバック

複数行のコールバックは、各行のインデントを揃えて書く(インデントのレベルが深いと、その行で”unexpected indentation”エラー)。

内容の一部だけを改行するとエラー。

引数を持つコールバック

コールバックが最後の引数の場合

以下のように、最後の引数のコールバック関数をインデント付で改行すればok。処理内容が複数行でもok。

この形は、jQueryのイベントハンドラ・アタッチメントに出てくる。

コールバックが最後以外の引数の場合

これは”unexpected ,”エラー。

無名関数を()で括ると意図通り実行。

これもok!

敢えてこう書けるが、段々ややこしくなる。

残念ながら()なしはだめ。

 

CoffeeScript – コールバックと無名関数

基本形

引数なしの場合

呼び出し元でコールバック関数を引数として、それが実行されるよう実装。

呼び出されるコールバック関数を定義し、その関数名を呼び出し元に引数として渡す。

引数ありの場合

コールバックが引数を取る場合、呼び出し元でコールバック関数と引数を受け取るよう実装。

コールバック関数を実装し、その関数名を引数とともに呼び出し元に渡す。

無名関数を使う方法

“無名関数の記法について”も参照。

引数なしの場合

コールバック関数を新たに定義せず、無名関数として定義して呼び出し元に渡す方法。

無名関数は、関数名を省略していきなり”->”で始める。

引数ありの場合

引数がある場合、関数名を省略して”(引数) ->”で始める。

このとき、無名コールバック関数全体を”()”で囲わないと、”unexpexted ,”(予想外のcomma)エラーになるので注意。

改行可能

複数行にわたる無名関数を引数として渡すとき、()内で改行して渡せる

より複雑な内容の関数もok。ただし無名関数が引数を持つ時には()で括らないといけない

即時関数のdoはエラー

引数にコールバックを渡すときにdoを付けてしまうと、その場で実行された上で、「関数ではない」とエラーになる。

 

coffee-script.js

概要

CoffeeScriptをコンパイルなしで、HTMLの<script>タグに直接書ける。

スクリプト指定は<script type=”text/coffeescript”></script>となる。

導入

CoffeeScriptからJavaScriptへのパースを行うファイルを公式サイト“text/coffeescript” Script Tagsからダウンロード。

このファイル(coffee-script.js)をサーバに配置に配置し、スクリプトを書くHTMLから呼び出す。

このほか、ネット上のcoffee-script.jsのURLを指定して取り込む方法もあり。

基本例

 

CoffeeScript – HTMLから外部スクリプトファイルを実行

HTMLファイル

test_htmml.html

外部スクリプトファイル

test_html.coffee

上記のCoffeeScriptファイルをコンパイル

コンパイル後のファイルは拡張子がjsになり、test_html.jsとなる。

このファイルを上のtest_html.htmlファイルのscript要素から読める場所に配置。

 

CoffeeScript – 関数

通常の関数

CoffeeScript特有の記法による。

関数は最後に演算された結果を戻り値とするようコンパイルされる。
戻り値を戻したくない場合は、引数なしのreturn文を明記する。

即時関数

引数の有無、値の渡し方などによって、以下から選択。

コールバック

 

CoffeeScript – 内包表記による配列の操作

配列の生成と要素の割り当て

内包表記によりリストを生成し、配列に代入することができる。

要素の取り出し

配列リストの要素を一つずつ列挙できる。

二次元配列の生成

ややこしいやり方

  • (content++ for c in [1..4])で要素数が4のリストを生成
  • そのリストをgridに3回加えている

シンプルなやり方

  • (content++ for c in [1..4])で要素数が4のリストを生成
  • そのリストを要素とする要素数が3の要素を生成

要素の参照

添字をパラメータとして内包表記で順次参照できる。

あるいは直接要素を指定し、入れ子で要素の配列を列挙参照することもできる。

要素の再設定

よくある要素の設定。

 

CoffeeScript – 配列

基本的な配列の扱い

配列リテラル

要素の参照と代入

先頭要素の添字は0

各種操作

要素の追加・削除

先頭要素の追加・抜き出し

末尾要素の追加・抜き出し

部分配列の抜き出し

元の配列は保持される。

要素の存在チェック

分割代入

個別要素を一括指定して取り出すことができる。

入れ替え作業も可能。

内包表記

内包表記による配列の操作を参照。

 

CoffeeScript – 演算

数値演算

四則演算

+ 加算
減算
* 乗算
** べき乗
/ 除算:小数の丸めはなし 11 / 4 → 2.75
// 除算の商 11 // 4 → 2
% 除算の剰余 11 % 4 → 3
%% %と同じ

CoffeeScriptからJavaScrioptへコンパイルした結果は以下のようになる。

11 / 4 11 / 4
11 // 4 Math.floor(11 / 4)
11 % 4 11 % 4
11 %% 4 modulo(11, 4)

インクリメント/デクリメント

インクリメント(++)、デクリメント(–)演算子は、前置・後置で使用可能で、後置は参照後に、前置は参照前に演算が行われる。

変数の値が小数部を持つと、演算誤差が発生する。

代入演算子

数値演算については、”+=”のような代入演算子が各四則演算子について使える。

丸め処理

Mathライブラリのクラスメソッドを使う。

小数点以下の処理
Math.floor() 切り捨て
Math.ceil() 切り上げ
Math.round() 四捨五入

文字列演算

結合

+演算子は二つの文字列を結合する。

片方が文字列でもう片方が数値の場合、数値が文字列に変換されて結合される。

演算 結果
“abc” + “def” “abcdef”
“abc” + 123 “abc123”
123 + “abc” “123abc”

代入演算子

代入演算子の場合、元の変数かオペランドのいずれか一方が文字数なら、文字列として結合される。

数値と文字列の変換

数値→文字列の変換

  • 12.34 + “deg”
  • String(12.34) + “deg”
  • 12.34.toString() + “deg”

文字列→数値の変換

  • Number(“34.56”)
  • parseInt(“34.56”, 10)
  • parseFloat(“34.56”)
  • parseInt(“ffff”, 10)→65535
    • parseInt(“0xffff”, 10)→65535
  • parseInt(“22”, 10)→18
    • parseInt(“0o22”, 10)→0
  • parseInt(“111”, 10)→7
    • parseInt(“0b111”, 10)→0
  • parseInt(“abc”)→NaN

存在演算子