05 | 2017/06 |  07

  1. 無料サーバー

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

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

スポンサーサイト

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

 

メモ──Javascriptにおけるイベントの取得

コンテンツ改訂履歴
  • 初稿:2006/12/26
  • 第1回改訂:2008/02/26……続きが書いてなかったので加筆した。
    またイベントバインド方法に関する視点を抜本的に改訂し、DOM レベル2 で推奨された「面妖な」方法を王道的手法として位置づけ、逆に簡易な方法として自らも好んで使用してきた DOM レベル0 による2つの方法の推奨度を低下させた。

WEB上での様々なイベント発生をJavascriptに「認識させ」、認識した当該イベントに対応して、WEB上で何らかの処置を行う───これはクライアントサイドJavascript(※)の基本中の基本だ。

「クライアントサイドJavascript」とはWebブラウザに組み込まれたJavascriptインタプリタのことを指すらしい(←「JavaScript」第3版:David Flanagan著)

ところがイベントの諸情報(イベントの種類、発生位置、発生要素等)を Javascript に認識させる方法が大変複雑で、それで結構「疲れてしまう」のである。

イベントハンドラ関数を HTML タグの属性として記述する方法が最も早くから行われている(上記書籍より)とのことだが、その場合に関数の記述はたやすいことだが、当該イベントの発生元要素を Javascript に認識させるには、ちょっとしたコツが要る。

例えば、マウスクリックが発生した時に、今そのイベントが発生した要素を Javascript が認識するには、単にマウスクリック時に起動する関数を記述するだけでは用を為さない。よく知られているように this キーワードを用いることが一般的になっているが、その場合であっても、発生したイベントそのものを Javascript に知らせることはブラウザ毎に方法が異なり結構面倒だ。

オブジェクトとしてのイベント

そこでまず、果たしてブラウザは、Javascriptは一体イベントをどう処理しているのか? それをしっかり抑えておく必要が生じる。

Javascript ではイベントを抽象的なオブジェクトして位置づけ、イベント発生時にブラウザに組み込まれた Javascript インタープリタにそれを認識させるようにした。例えば、Mozilla系ではイベントハンドラー関数の引数に、暗黙かつ自動的にイベントオブジェクトを渡し、IEでは当該イベントオブジェクトを window のプロパティとして(window.event)補足する。

イベントハンドラーのバインド

次に、作者は意図した要素に意図したイベントを結びつけねばならない。つまりイベントのバインド対象を設定する必要がある。そこで、W3Cでは addEventListener()メソッドによってイベントを「監視する」ことにした。こうすることにより、或るイベントとイベントハンドラーを、或る要素に緊結(バインド)させ、かつ当該イベントにより呼び出されるイベントハンドラー関数には、その唯一の引数としてイベントオブジェクトを自動的に渡すようにした。

よく知られているように、windowオブジェクト上でマウスクリックイベントが発生したときに、anyfunction 関数を起動させる場合には、Mozilla系、Opera、safariなどでは、targetElement.addEventListener("click",anyfunction,false) メソッドにより、targetElement にクリックイベントをバインドする。

他方、常に W3C 勧告に逆らうことが使命と思い込んでいるとしか思えない MS 社の IE においては、attachEvent メソッドでほぼ同様の処理を行う( targetElement.attachEvent("onclick",anyfunction) )

ところで、W3C 勧告及び IE におけるこの面妖で「厳格な」手法より遥か以前から、次の2つの方法によってイベントのバインドが行われてきた。

その1つは、バインド対象要素オブジェクトの、イベントタイプ名のプロパティに、イベントハンドラー関数をメソッドとして登録することにってバインドさせる方法(「プロパティとしてのイベントハンドラー」)であり、もうひとつは、最も古くからある古典的手法─── HTML タグ内にその属性としてイベントタイプとハンドラー関数を登録する方法(「属性としてのイベントハンドラー」)である。

前者の、要素オブジェクトのプロパティとして設定する方法は、例えば「document.body.onclick=anyfunction;」とscript文内で設定する。

一方後者のタグ要素の属性としてイベントハンドラー関数を設定する方法はこうなる。<p onclick="anyfunction(argument1,argument2,・・・・)">。

そして後者の方法こそが、最も古く(※ この方法は Javascript 誕生時にイベントをバインドする方法として用意された手法である)からあり、故にまた一般的であって、最も頻繁に見かけるものであり、Javascript 初心者が見よう見まねで容易に利用できる方法でもある。

但し、DOM レベル2 で推奨された方法( IEのattachEventメソッドによる登録も含む )以外でイベントを登録する場合、1つの要素オブジェクトの同一タイプのイベントに対して、異なる複数のハンドラー関数を登録できない欠点がある。またバブリングや伝搬の制御も出来ない。

イベント発生要素と this キーワード

バインド対象の設定方法に次いで、第三にイベント発生要素と発生したイベントそのものをいかにしてJavascript に知らせるか、それが問題とならざるを得ない。何故ならばどんなイベントが何処で発生したのか、Javascript がそれを知ることによって初めて、Web サイトをより良く制御しうるからである。

まず、イベント発生要素は Mozilla 系とIEとで全く異なるプロパティによって「取得」される。Mozilla系は evt.targetであり、IEは evt.srcElement である(ここに evt は発生したイベントオブジェクト。eと略されることが多いが別に表記方法はどうでも良い)。

なお、これらのプロパティはHTML内にはまず登場せず、専ら script コード内に記述されるのに対して、this キーワードを利用すると、HTML タグ内にイベントハンドラーを記述して、Javascript にイベント発生要素を知らせることが出来る。具体的には this キーワードをイベントハンドラー関数の1つの引数として記述することにより、Javascriptにイベント発生要素を明示的に「通知」するのだ。

但し、明示的に通知されなくてもJavascriptインタープリタはイベント発生要素を this キーワードによって「認識」しているので、必ずしも明示的な伝達が不可欠な訳ではない。

さてお立ち会い!(苦笑)。(1) W3Cの面妖な「イベント監視」手法でもなく、(2) script文内でプロパティにメソッドを追記する方法でもなく、(3) 最も一般的に行われているところの、HTMLタグ要素内にイベントハンドラー関数を記述する方式を採用する場合、気をつけねばならないことがある。それはイベント発生そのものを Javascript に告知する必要があるということである。

一般的に使われている方法ではイベントハンドラー関数を呼び出す時に、その引数にイベントオブジェクトは入れない。引数はあるいは初期値であり、thisであり、既定値であり、あるいはない。イベントオブジェクトそのものは引数に記述しない場合が圧倒的である。

ところが、そうすると問題が生じる場合がある。すなわち、Javascript インタープリタは或るタグ内に記述されたイベント名とイベントハンドラー関数により、イベント発生時に当該関数を実行するものの、Mozilla系ブラウザでは発生したイベントそのものを取得できないのである。

Mozilla系ブラウザでは、(1)又は(2)の方法によってイベントをバインドさせた場合には、自動的・強制的にイベントハンドラー関数に、唯一の引数としてイベントオブジェクトを引き渡す。しかし、(3)の方法の場合には、HTMLからJavascriptへの自動的なイベント「通知」は行われないのだ。

そこで event キーワードの登場である。

event キーワード

ここで問題にしたいのは、呼び出された関数側ではなく、ハンドラー関数を呼び出す側の関数におけるイベントオブジェクトについてである。

ある解説書に拠れば、「W3C DOM イベントオブジェクトをハンドラ関数に渡すには、明示的に引数の1つとして event キーワードを記述しなければなりません。」(『JavaScript & DHTML クックブック』p.243)

つまり、起動される側の関数において、いつでも受け取れるように function(e){・・・}と待機していても、呼び出す側で event キーワードを使用しないと呼び出した関数に当該イベントオブジェクトを渡せないようなのだ。

つまり、呼び出す側の、HTML文の属性に記述されたイベントハンドラーの引数に function(event) のようにevent キーワードを記述する必要があるのである。

正確に言えば、Mozilla 系ブラウザの場合、呼び出す側の関数の引数に、明示的に event キーワード(オブジェクトではない!)を記述しないと、呼び出された関数側に W3C 仕様の当該イベントオブジェクトが渡されない場合があるようなのだ。ここに、断言を避けたのは「渡されることもある」からであり、絶対に event キーワードを必要とするわけでもないからである。上述の引用でも「W3C DOM イベント」とわざわざ断っているように、イベントオブジェクトの様々なプロパティやメソッドを利用しないのであれば、event キーワードを記述しなくても動作するようなのである。

以上の記述については、以下を参考にすべし!

DOM:event - MDC

 

● コメント ●

コメントありがとうございました。 (hkom)

コメントありがとうございました。僅かでも役に立てば幸いです。
さて、上に追記しましたが、仰せのことを実現するにはDOMのメソッドをいくつか組み合わせて、メモリ上で必要な処理をするのが最善かと思います。
数千タグに手打ちで onclick 属性を追記する手間よりも遙かに簡単に目的を達成できると思います。
例えば以下のような方法でいかがでしょうか?

/*-----------------------------------------------------
* これは全ての a タグにthis.blur()メソッドをオンメモリ
* で追加するために作成したコードです。重たいので今は使
* 用していませんが(;^_^A
* 何らかの参考になれば良いのですが・・・
*                 by hkom 2008/02/26
----------------------------------------------------*/

/* --0-------------------------------------------------
* 変数定義
*/
// 間違いのないように全文字列を小文字に変換
var agt=navigator.userAgent.toLowerCase();
//IEかどうか
var is_ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));

/* --1-------------------------------------------------
* 全ての a タグに onclick属性とその属性値である
* this.blur()を追加する関数。onLoadメソッドでサイト
* オープン時に起動する。
*/
function start(){
appendAttri("A","onclick","this.blur()");
}
//オンロードイベントで start 関数を起動
window.onLoad = start;

/* --2-------------------------------------------------
* tagName のタグを取得する関数
*/
function getTag(tagName) {
var objAll = [];
if (!tagName){
objAll = document.getElementsByTagName ? document.getElementsByTagName("*") : document.all;
} else {
objAll = document.getElementsByTagName ? document.getElementsByTagName(tagName) : null;
}
return objAll;
}

/* --3-------------------------------------------------
* 1. createAttributeで追加する属性名を作成し、戻り値
*  として当該属性への参照を得る。
* 2. setAttributeにて属性名と値を設定し、
* 3. 設定した属性をエレメントに追加する。
*/
function appendAttri(elementName,attriName,attriValue) {
var elementName = (elementName) ? elementName : null;
var attriName = (attriName) ? attriName : null;
var attriValue = (attriValue) ? attriValue : null;
var tagObj = getTag(elementName);
var appendAttri = document.createAttribute(attriName);
for (i = 0; i < tagObj.length; i++) {
(!is_ie) ? tagObj[i].setAttribute(attriName,attriValue) :
tagObj[i].setAttribute(attriName,new Function(attriName,attriValue));
}
}

● コメント ●

 (しん)

続きがみたくてたまりません。
(2)の方法だと数千タグにeventを追加しなくてはならない都合上、
サーバーサイドにて、タグにあらかじめonClick属性を
書かせることにしたんですけど、

これだとeventオブジェクト取得ができず、
結果としてstopPropagation()ができません。

続きがみたくてたまりません!どこですか?

■ コメントの投稿 ■

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

●トラックバック●

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

●参照元一覧●

<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が開きます。

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