JavaScriptのイベント処理
イベントというのは、日常生活でいえば、電気のスイッチだったり、車のギアだったり、そういう動作や状態を切り替えるアクションのことを指します。
Webサイト上のイベントは、ボタンのクリックやマウスオーバーのようなアクションがそれになります。
- イベントハンドラ
- イベントリスナ
イベントハンドラ
イベントハンドラのメソッドでよく使われるものはonclickがありますが、それ以外にもonload、onchange、onmouseover、onsubmit・・・他多数あります。
onload
onloadではページが読み込まれた後に実行される命令を記述します。
window.onload = function(){ 処理 }
onclick
代表してonclickでイベントハンドラの指定方法を簡単に説明しようと思います。
onclickイベントハンドラの指定方法は、大きく2通りあります。1つがHTMLのタグ内に記述する方法です。
<button onclick="fun()">ボタン</button>
この例ですと、ボタンをクリックするとonclick内のfun()という関数が実行されます。もちろん関数でなくてもこの""の空間内はスクリプトを記述できる空間なのでvarなんとかからダラダラ書くのでも大丈夫です。
関数を書く場合は、それより前でその関数が定義されている必要があることに注意します。
もう一つの方法はスクリプト内で
<script> document.getElementById("button#a1").onclick = function(){ 処理 } </script>
のように処理する方法です。
DOMで要素をいじるためにはその要素が読み込まる前は呼び出すことができないため、どうしても要素が出現した後にスクリプトを呼び出す必要があります。なのでonloadイベントと組み合わせたり、/body直前に書いたり、scriptのanysc属性を指定したりしてスクリプトの読み込みのタイミングを調整する必要があります。
aタグにイベントを指定した際は、リンクを無効化するために、return falseを記述します。inputのtypeがsubmitの要素にイベントを指定して、かつページを移動させたくないときは、親のform要素にonsubmit="return false"と記述しておきましょう。
<script> document.getElementById("a#a1").onclick = function(){ 処理 return false } </script>
<form id="form1" name="form1" action="rese2.php" onsubmit="return false" method="post"> <input type="text" name="x4" id="x4" value="" size="40" /> <input type="submit" name="search" value="検索" onclick="formSubmit(this.form)" /> </form>
イベントハンドラの問題点は、同じ要素に対して同じイベントハンドラを定義できないことで、もし定義してしまうと、前のイベントハンドラは後から指定したイベントハンドラに上書きされます。
javascriptでは2つのファイルを読み込んだときは、前のデータと後のデータ(特に変数とか)は後のデータが優先されますが、複数のライブラリの共存の際に特定の記号($)とかにそれぞれのライブラリが別々の関数を割り振っていたりしたときに衝突が起こる(コンフリクト)の問題が知られています。
a href="javascript:"
a要素のhref属性の中にjavascriptのスクリプトを書くことで、クリックした時にそのスクリプトを実行させることもできる。
onlickを使うかこいつを使うかは、この2つの挙動の差を知らないと判断できないわけだが、ご丁寧に解説しているサイトとかがないんで、void演算子を使う以外はonclickで良いかと思われる。
void演算子は、void()のカッコ内に対して問答無用にundefinedを返す演算子である。
<!--以下画面遷移をしないパターン例--> <a href="rese2.php" onclick="alert('error'); return false;">onclick型:return false</a> <a href="javascript:void(alert('error'))">javascript型:voidで()内をundefined</a> <a href="javascript:void(0)" onclick="alert('error')">javascript型:voidで()内をundefined</a>
イベントリスナ
イベントハンドラの問題点を解決して策定されたのがイベントリスナになります。
イベントリスナもイベントハンドラもやっていることと結果は根本的には同じです。タグ内に埋め込むことができないこと、記述方法が異なること、上書きの問題に適合しているか否かという点が異なります。
<script> document.getElementById("#a1").addEventListener("click",function(){処理},false); //idが#a1の要素にクリックイベントが起こったら、functionの処理を、バブリングフェーズで実行する </script>
addEventListenerの一番目の引数はイベントが入ります。イベントハンドラのようにonは入りませんので注意してください。
2番目の引数は処理(普通関数)が入ります。functionから記述してもいいし、あらかじめ定義済みの関数をfun()のような形で入れてもいいです。あ、fun()じゃ関数の返り値になってしまうので、ただのfunじゃなきゃダメですね。
3番目の引数はフェーズが入ります。trueがキャプチャーフェーズ、falseがバブリングフェーズです。イベントリスナのイベントはその要素だけにとどまらず伝搬していきます。その伝搬方法が子要素→親要素→html(バブリング)か、html→親要素→子要素(キャプチャー)かの違いとなります。なお、IEはキャプチャーフェーズが存在しません。
で、上書きの問題に適合の詳細ですが、イベントハンドラのonloadイベントを使って複数のjsファイルを読み込んだとすると、後から読み込むjsファイルの内容しか適用されませんが、イベントリスナで読み込めば前も後もすべて読み込んでくれます。
あくまで同じ要素で同じイベントである場合だけです。この場合は同じwindow要素で同じonloadイベントだからです。ボタンでも異なるidが振ってあるボタンに同じイベントを設定するのであればonclickイベントハンドラでOKです。
イベントリスナの問題点
イベントリスナの問題点は、先ほどのIEがキャプチャーフェーズに対応していないことと、IE8以前がaddEventListener自体に対応していないという大問題です。
なのでIE8以下に対しては、IE独自のattachEventで対応します。これを考慮して作られた関数が以下(引用元はページ下部)
<script> var addlistener = function(elm,type,func){ if(!elm) return false; if(elm.addEventListener){ //モダンブラウザ向け elm.addEventListener(type,func,false); }else if(elm.attachEvent){ //IE向け elm.attachEvent('on'+type,func); }else{ return false; } return ture; }; </script>
このaddlistener関数にelm(要素)、type(イベント)、func(処理)を記述するとaddEventListener未対応のブラウザであってもうまく処理してくれるというものです。(例:addlistener(document.getElementById("div"),"click",fun);)
- 参考・引用元
コメントor補足情報orご指摘あればをお願いします。
- << 前のページ
- 次のページ >>