09 | 2017/10 |  11

  1. 無料サーバー

User forum-FC2BLOG-Info-Edit Template-Post-Edit-Upload-LogOut

CSSやJavascript自習の苦闘史を綴っていきたい。恐縮ですがJavascriptを有効にしてご覧ください。
2005年12月から社会問題も掲載!

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

 

jQuery()の挙動を解読する(18) $(args).trigger()、$(args).triggerHandler()、$.event.trigger() 解読 ──jQuery解読(29)

$(args).trigger()、$(args).triggerHandler()

これらのメソッドに該当するコードは jQuery.js ver1.2.2 の 2205-2215 行です。2214 行だけが1.2.1とことなる箇所で新規追加行になります。バグフィックスと言うところでしょう。

2205: trigger: function( type, data, fn ) {
2206:  return this.each(function(){
2207:   jQuery.event.trigger( type, data, this, true, fn );
2208:  });
2209: },
2210:
2211: triggerHandler: function( type, data, fn ) {
2212:  if ( this[0] )
2213:   return jQuery.event.trigger( type, data, this[0], false, fn );
2214:  return undefined;
2215: },

これらのインスタンスメソッドは、全く同様の引数をとり、共に対象要素に登録されている、type で指定されたイベントタイプに対応するイベントハンドラー関数を起動します。しかし、微妙に異なる引数(上のピンク色の2箇所)を $.event.trigger() に渡してこのクラスメソッドを起動し、このメソッドに全ての処理を委ねた上で処理結果を return します。したがってこれらの2つのインスタンスメソッドの挙動を知るには $.event.trigger メソッドを理解する必要があります。

しかしその前に、2つのメソッドの差異を外観しておきます。

  • trigger インスタンスメソッドはその対象要素の各々に対して、jQuery.event.trigger メソッドを適用し、各々の結果を返します。他方、triggerHandler インスタンスメソッドは、対象要素の最初の1つの要素に対してだけ作用し結果を返します。 return 値は全て jQuery インスタンスです。
    なお、何故対象ノードを複数( trigger )と1つだけ( triggerHandler )に分けたのか、その理由は分かりません。triggerHandler() メソッドでも trigger() メソッド同様に、複数の要素ノードを対象として作動するようにしても問題はないと思われるのですが..。
  • trigger インスタンスメソッドは、対象要素に登録され、type で指定されたイベントタイプに対応するイベントハンドラー関数を起動し、かつ jQuery.event.trigger メソッドに渡される4番目の引数を true とすることにより、当該イベント発生時のブラウザ固有の動きを抑制しません。
  • 他方、triggerHandler インスタンスメソッドは、対象要素に登録されているイベントタイプに対応するイベントハンドラー関数を起動させる点は trigger メソッドと同様ですが、jQuery.event.trigger メソッドに渡される4番目の引数を false とすることにより、type で指定されたイベントタイプに対応するブラウザ固有の動きを抑制します。

▲ToTop

$(args).trigger() と $(args).triggerHandler() の実例

更に、$.event.trigger() クラスメソッドの解読を行う前に、これらのインスタンスメソッドの実例を見ておきます。これらのメソッドが何を行うのか理解することが先決であり、本家 jQuery サイトにいくつかの例示がありますが、第三引数の fn を与えた例はなく、また例そのものが分かりやすいとは言えないからです。

独自に作成した $(args).trigger() メソッドの実例

例は、$(args).trigger() メソッドの引数が1つだけ、2つ及び3つの場合の各々の違いが分かるように3パターン作成し、更にtriggerされるイベントタイプも click、dblclick 及び mouseover の3種類とし、合計9つのパターンの例を作成しました。

複雑な挙動をするtrigger()インスタンスメソッドを十分に理解するには、これだけの例が必要でした。

使い方

  • 下のカラーボックス上ではそれぞれの説明にあるマウスイベントタイプが発生します。この場合に起こることは、それぞれのボックスにバインドされたイベントハンドラーが、各々のイベント発生によって働いただけに過ぎません。
  • これらの3つのボックスには同じ class 名 "Box" が振ってあり、トリガーメソッドの対象としてこの class 名をもつ3つのボックスを指定してあります。つまり jQuery(".Box").trigger(・・・)です。trigger() メソッドはこれらの3つの要素ノードにバインドされた、異なるイベントタイプのイベントハンドラーを励起させ得ることになります。
  • カラーボックスの下にあるボタンが triggerメソッドを起動させる起動ボタンです。縦4行、横3列の10個のボタンがありますが、一番下のボタンは初期化ボタンで、他の各行は trigger メソッドの引数が異なり、各列はトリガーするイベントが異なります。各々はボタン名に書いてあるような設定となっており、各々のボタンに記されているような trigger() インスタンスメソッドがバインドされています。これらのボタンをクリックすると各々にバインドされた異なる trigger メソッドが呼び出され、trigger対象要素ノードにバインドされているイベントハンドラーをトリガー(励起)させます。
  • 1行目のボタンをクリックすると、3つの trigger メソッド対象要素ノードから、対象となるイベントタイプがバインドされている要素ノードだけのイベントがトリガーされます。当該イベントタイプがバインドされていない他の2つの要素ノードのイベントハンドラーは起動されません。
  • 2行目のボタンには第2引数が与えられています。ここでも対象となるイベントハンドラーがバインドされている要素ノードだけが反応します。第2引数はトリガー先のイベントに情報などを付加する働きをし、各々のボタンをクリックするとボックスの下に文字列が現れます。これが付加された情報です。なお、再びクリックすると付加された文字列が消えるような toggle() メソッドが設定されています。
  • 3行目のボタンは、3つの引数を与えた trigger メソッドをバインドしたものです。このボタンで初めて、triggerメソッドの対象要素ノードが3つのボタンであったことが明示的に明らかにされます。第3引数の fn 関数はイベントタイプに無関係に triggerメソッドの対象要素ノードの全てに作用するため、3行目のどのボタンをクリックしても、3つのボックスの背景色が同一色に変化します。
  • しかし、その場合であっても trigger メソッドは、第1引数で指定されたイベントタイプがバインドされた要素ノードのイベントハンドラー関数だけを起動させるので、当該イベントタイプがバインドされた要素ノードのイベントハンドラーしか起動されません。
    ここで興味深いことが確認できます。ブルーボックスには click イベントがバインドされており、3行のボタンの第1列に登録されている trigger メソッドは イベントタイプ click を起動します。
    この結果、clickイベントがバインドされているボックス、ブルーボックス及びレッドボックスのイベントハンドラーが反応します。(レッドボックスにはダブルクリックで付加される文字を消すためにクリックイベントがバインドされています。)
    従って、例えばレッドボックスをダブルクリックした後に、第1列目の3つのいずれかのボタンをクリックすると、ブルーとレッドの2つのボックスのクリックイベントが励起(トリガー)されます。レッドボックスのその他の場合によるダブルクリック後においても同様です。
Box A:このボックスを click すると一旦透明化され、その後元に戻ります。
Box B:このボックスを double click するとボックス内に文字が増え、その後このボックスをクリックすると増えた文字が消えます。

Box C:このボックスに mouseover し続けると透明度が変化しながら上下にスライドし続けます。
  

▲ToTop

$(args).triggerHandler() メソッドの実例

triggerHandler() メソッドは、後に $.event.trigger() メソッドの解読でその仕組みを明らかにしますが、trigger メソッドと異なるのは、ブラウザ既定の動作を停止させる点です。

ですから、既定の動作を持たないタイプのイベントがバインドされた要素ノードを対象として、このメソッドを適用しても何も意味がありません。

ここに既定の動作を持つイベントタイプには何があるのか、その点は不明です。分かっていることはfocus()、blur()、click()などの、a タグやinput、textarea タグなどが元々有しているメソッド名と一致するイベントタイプが「ブラウザ既定の動作を有する」ということが出来るであろうことです。

さて、実例を作ってみようとしたのですが、jQuery本家サイト以上のそれは作れませんでしたので、本家サイトの例を引用して解説しようと思います。

本家サイトからの引用サンプル

  
  1. input ボックスにはイベントタイプ focus のイベントハンドラーが登録されています。ハンドラー関数によりフォーカスが input ボックスに移ると Focused! という文字を表示してから、フェードアウトします。
    そのことを確認するには input ボックス内でマウスをクリックすれば分かります。その末尾に Focused! と表示され、その後1.5秒掛けてフェードアウトします。これが設定されている focus イベントの発生と実行です。
  2. 次に、マウスを input ボックス外でクリックしてフォーカスをはずしてから、Button1 をクリックします。すると inputタグ既定の focus イベントが起動して、 Focused! と表示し、かつ trigger されたイベントハンドラーが Focused! と表示します。つまり2つの Focused! が表示されます。そして共に1.5秒間でフェードアウトします。この時、input ボックスがフォーカスされ、マウスカーソルがその中で点滅していることを確認できます。
    ここでは、input タグに設定された focus イベントのデフォルト動作(=フォーカスすると言う動作)が trigger() メソッドによって行われ、同時に trigger() メソッドによってイベントハンドラー関数が起動されたため、2つの文字が表示されたことになります。
    なお、これまでのことはIEでの確認です。Firefox と Opera ではこの違いが出現せず、trigger() でも triggerHandler() でも結果は変わりませんでした。理由は不明です。
  3. 次に、念のために input ボックス外でクリックしてフォーカスをはずしてから、Button2 をクリックします。すると focus イベントハンドラーが起動して、Focused! と表示され1.5秒間でフェードアウトします。しかし、今度は input タグ内にフォーカスは当たっていません。input ボックス内でマウスカーソルは点滅していません。また表示される Focused! も1つだけです。
    これで triggerHandler() メソッドと trigger() メソッドとの効果の違いが確認出来ました。

▲ToTop

$.event.trigger()

愈々、trigger() 及び triggerHandler() がどのようにして作用しているのか、その挙動を探ります。これらの2つのメソッドから呼び出される $.event.trigger() を解読します。

$.event.trigger() の引数について

trigger() クラスメソッドは type、data、elem、donative 及び extra の5つの引数を取ります。

これらは順に、

  • tyoe: 励起させたいイベントタイプ
  • data: type イベント発生時のイベントオブジェクト並びに trigger により励起させるハンドラー関数で利用させる引数によって構成される配列オブジェクト
  • elem: type イベントを発生させる要素ノード(トリガー先とでも言うべきか)
  • donative: typeイベントによるブラウザのデフォルト動作を行わせるか(true)、行わせないか(false)を指定する真偽値
  • extra: trigger() メソッドによって type イベントを発生させた時に起動させる、イベントハンドラー関数とは別の、独自に指定する関数

を意味しています。

1. 第2引数 data の処理

data 引数を配列にし、data がなければ空の配列を作り data に代入する。data には trigger メソッドを起動させたイベントオブジェクトなどを記述する。

1962: trigger: function(type, data, elem, donative, extra) {
1963:  // Clone the incoming data, if any
1964:  data = jQuery.makeArray(data || []);
1965:
2. トリガー対象 (elem) が指定されていない場合の処理

第3引数の elem がない場合の処理です。この場合において、当該頁にイベントが登録されていれば、全てのノードを対象としてtrigger()メソッドを再帰呼び出しし、イベントが全く登録されていなければ何もしません。

1966:  // Handle a global trigger
1967:  if ( !elem ) { //elem が指定されていなければ
1968:   // Only trigger if we've ever bound an event for it
1969:   if ( this.global[type] ) //typeイベントが登録されていれば
      // 全てのノードを対象として trigger クラスメソッドを再帰呼び出しする。
1970:    jQuery("*").add([window, document]).trigger(type, data);
1971:
3. 1つの対象ノードに対する処理 (1) イベントハンドラー起動前の処理
1972:  // Handle triggering a single element
    // 1の要素ノードを trigger 対象とする。
1973:  } else {

 /* elem がテキストやコメントだった場合
  * 何もせずに undefined を返す。
  */ 
1974: // don't do events on text and comment nodes
1975: if ( elem.nodeType == 3 || elem.nodeType == 8 )
1976: return undefined;
1977:
 /* elem[type] が関数ならば fn = true、違えば fn = false とする。
  * この elem[type] は突然登場し、このメソッド以外では使われていない。
  * これはブラウザ固有の type メソッドが elem に指定されている場合に
  * 部分であり、2010-2017 行に連動する。
  */
1978:   var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),

 /* data 配列が空ならば、あるいは data 配列の最初の要素に preventDefault
  * プロパティがなければ(つまりそれがイベントオブジェクトでなければ)
  * evt = true とする。その他の場合には evt = false とする。
  * こうすることにより、イベントオブジェクトが第一引数にない場合において
  * var evt = true としてダミーイベントを用意する準備をしている。
  */
1979:   // Check to see if we need to provide a fake event, or not
1980:   evt = !data[0] || !data[0].preventDefault;
1981:

 // ダミーのイベントオブジェクトを作って data 配列の先頭要素とする。
 // その type プロパティは type、target プロパティは elem とする。
1982:   // Pass along a fake event
1983:   if ( evt )
1984:    data.unshift( this.fix({ type: type, target: elem }) );
1985:

 /* data の最初の要素としてユーザーが指示したイベントオブジェクト、
  * 又は 1721 行で作ったダミーのイベントオブジェクトの、type 
  * プロパティを type とする。
  * これは専らダミーイベントへの対応策であって、イベントオブジェクトの
  * type プロパティを与える目的のための行である。そうしないとダミーイベ
  * ントとして用を為さないから。
  */
1986:   // Enforce the right trigger type
1987:   data[0].type = type;
1988:
4. 1つの対象ノードに対する処理 (2) イベントハンドラー関数の起動その1

elem に対応する cache.id オブジェクトの "handle" プロパティ値が存在し、それが関数であれば、data を引数とする関数を elem のメソッドとして実行する。ここに data[0] はこれまでの処理でイベントオブジェクトとなっている。

これにより指定した type イベントに対応して登録されているイベントハンドラー関数が呼び出され、実行される。なお、当該関数の返値がvalに代入される。

1989:   // Trigger the event
1990:   if ( jQuery.isFunction( jQuery.data(elem, "handle") ) )
1991:    val = jQuery.data(elem, "handle").apply( elem, data );
1992:
5. 1つの対象ノードに対する処理 (3) イベントハンドラー関数の起動その2

(1)fn が存在せず、(2)elemに "on"+type 属性があり、(3)その属性値である関数を data を引数として実行して return 値が false ならばval に false を代入する。

これにより"on"+type 属性値である関数が励起・実行される。しかし、この行の起動を確認することは出来なかった。

1993:   // Handle triggering native .onfoo handlers
1994:   if ( !fn && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
1995:   val = false;
1996:
6. 1つの対象ノードに対する処理 (4) 固有に指定した関数 extra の起動
 // まずダミーイベントが設定されていれば、それを data 配列から削除する。
1997:   // Extra functions don't get the custom event object
1998:   if ( evt )
1999:    data.shift();
2000:

 /* 次の部分は ver 1.2.2で大きく変わった箇所です。
  * extra が既述されていてそれが関数の場合に、 val の値があれば data 配列に
  * その値を結合し、なければ data のままで、その配列を引数として当該関数を実
  * 行し、retに実行結果を返す。
  * この場合、1998-1999 行によりダミーイベントは削除されている一方、最初に
  * data にイベントオブジェクトが記述されていれば、それが引数として使われる。
  */
2001:   // Handle triggering of extra function
2002:   if ( extra && jQuery.isFunction( extra ) ) {
2003:    // call the extra function and tack the current return value on the end for possible inspection
2004:    ret = extra.apply( elem, val == null ? data : data.concat( val ) );

 /* もし何かが返されれば、それを優先的に val に代入してvalを上書きする。
2005:    // if anything is returned, give it precedence and have it overwrite the previous value
2006:    if (ret !== undefined)
2007:     val = ret;
2008:   }
7. 1つの対象ノードに対する処理 (5) ブラウザ固有のメソッドの扱い

(1)fn が存在し、(2)donative が trueで、(3)val も true で、(4)elem が a 要素でなく、(5)type が click でないならば、triggerd の値を true としてから、elem[type]()メソッドを実行する。

この部分は donative に関わる部分、つまりブラウザ固有の動きをさせるか、させないかを決める部分である。

trigger() インスタンスメソッドの場合には donative = true として jQuery.event.trigger() メソッドが起動されるので、elem[type]() が実行される。しかし、triggerHandler() メソッドの場合には donative = false として jQuery.event.trigger() メソッドが起動されるため、ブラウザ固有のメソッドすなわち elem[ type ]() は起動されない。

2010:   // Trigger the native events (except for clicks on links)
2011:    if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
      //次の行は1843行(in add() クラスメソッド)に関わる。
2012:     this.triggered = true;
2013:     try {
2014:	    elem[ type ]();
2015      // prevent IE from throwing an error for some hidden elements
2016      } catch (e) {}
2017:    }
2018:
2019:    this.triggered = false;
2020:  }
8. 1つの対象ノードに対する処理 (6) 終了処理
2021:
2022:  return val;
2023: },
2024:

 

■ コメントの投稿 ■

管理者にだけ表示を許可する

●トラックバック●

■トラックバックURLはこちら■
http://hkom.blog1.fc2.com/tb.php/611-ecd30e28

●参照元一覧●

<provided Fc2>
<provided i2i>

▲ToTop

 90%近いシェアを握っているインターネットエクスプローラの描画エンジンを利用したタブbrowser。沢山のタブbrowserがあるが、多機能、カスタマイズフリー、スクリプト利用等で一日の長がある。Gekkoエンジンへの対応も行われ、IEからの自立独立の方向に向かっている。2005年7月にはIE7が登場する見通しの中で、今後の発展が望まれる。

 多様なCSS作成支援機能を備えた、タグ入力式 HTML&CSS作成支援エディタ。スキンデザインもすっきりしている。テキストエディター上で作成するよりも確実で安全にタグ打ちが出来る。
文字コードを選べないのが欠点。

 StyleNote同様のタグ入力式 HTML&CSS 作成支援エディタ。長年使用してきたが現在StyleNoteに乗り換えつつある。

 クリップボード履歴情報を活用する為のソフト。画像まで履歴を取ってくれるのが嬉しい。このソフトを使わない日は絶対ない程に重宝し、愛用している。

 起動中のウィンドウの「コピーできない」説明文などの文字列を取得し、コピー可能な文字データにするツール。何かと便利。

 ストリーミングデータを保存することが出来るソフト。動画利用には不可欠なソフトだ。

 無料ながらレイヤー機能を有し、スクリプトによる拡張も可能な、sleipnir作者が提供している優れもの画像編集ソフト。

 画面キャプチャソフトと言えばこれに勝るものなし、ではないだろうか? 様々な取得方法を有しており、ブログ作成にもHomepage作成に不可欠だ。Jtrimと並んでWoodyBellsの作品。

 複数ファイルの同時編集は出来ないが、透過pngも作れる画像編集ソフト。
(以下当該サイトから抜粋)初心者にも簡単に操作が出来るフォトレタッチソフトです。多くの加工機能で画像に様々な効果を与えることができます。非常に軽快に動作するため、ストレスなく操作できます。

 Animation Gifファイルを作れる無料ソフト。

 キャプチャソフト。画面内にサイト全体が表示しきれない場合でも、これを使えば全体をキャプチャすることが出来る。

 画像処理。画像のフォーマット変換のみならず、色数やサイズ、圧縮率の変更まで一括処理できてしまう『BatchGOO!』は、大量の画像をまとめて処理したいときに大変便利なソフト。BMP, TIFF, JPEG, PCX, PNG の相互変換をはじめ、色数・サイズ・解像度の統一、JPEG圧縮率の調節など、ホームページ用の画像や携帯電話用の壁紙を揃えるのに抜群の相性を見せる。(Vectorの当該ソフト紹介頁より抜粋引用)

 名前から直ぐに想像が付くように画像のサイズを測るためのソフトだ。Homepage作成には欠かせない。2カラム、3カラムのレイアウトを行う場合に大変重宝する。

 ランチャーソフトは沢山あるが、中でもこれが一押しだ。2年以上使ってきたがその操作性には毎日満足している。これを使い始めてからデスクトップには一切のアイコンを表示することをやめてしまった。

 AdobeReader7によって、起動時間が長すぎるという長年のユーザーの不満はある程度解消した。そのためこの高速化ソフトは存在価値が低下してしまったかもしれない。AdobeReader6迄はこのソフトによる起動高速化で恩恵を受けてきた。

 IE専用が難点だが、様々なサイト内でIDやパスワードを入力するのに重宝するソフト。コンテキストメニューから簡単に起動できるのがGood! sleipnir等のIEの描画エンジンを利用しているブラウザでも使える。

 利用しているパソコンの諸元値を取得するには、このソフトがベストだ。インストール済みソフトの一覧が取得できるのも嬉しい。

 WMPは機能が豊富なだけ重い。RealPlayerも同様だ。そこでMedia Player Classicを使いたい。動作が軽快なだけではなく、対応しているファイル形式もすこぶる多く、これひとつで、wmvもrmも表示できてしまうのだから凄い! 数多あるMedia Playerの王様と言えるだろう。

 自宅でPCを起動しているときには必ず起動しているメディアプレーヤー。何かと過剰なWinampよりも、起動も速くスキンはシンプルだ。

 DivX, Xvid, Mov, Vob, Mpeg, Mpeg4, avi, wmv, dv, などの動画をDVD-Video形式に変換できるフリーソフト。クリックするとDVD関連ソフト紹介サイト=「DVDなToolたち」なるHomepageが開きます。

----------
200801150142
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。