Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【JavaScript】addEventListener、ユーザーはどれをクリックした?

 どうも!LSSです!!

 

 ちょっとまたJavaScriptで作り始めたものがあって(完成までまだ少しかかりそう)、それを作ってる時に気づいた事があったので、ここに記しておきます。 

 

 

サンプル

以下のいずれかをクリックしてみてください。

c1
c2
c3
 

 

 

コード

<div id="c1">c1</div>
<div id="c2">c2</div>
<div id="c3">c3</div>
<div id="gamen"> </div>
<script>// <![CDATA[
c1.addEventListener('click',clk,false);
c2.addEventListener('click',clk,false);
c3.addEventListener('click',clk,false);
function clk(e){
gamen.innerHTML=e.srcElement.id+'をクリックしたでしょ?';
}
// ]]></script>

 

 

コード失敗例(動作しません)

<div id="c1">c1</div>
<div id="c2">c2</div>
<div id="c3">c3</div>
<div id="gamen"> </div>
<script>// <![CDATA[
c1.addEventListener('click',clk(1),false);
c2.addEventListener('click',clk(2),false);
c3.addEventListener('click',clk(3),false);
function clk(a){
gamen.innerHTML='c'+a+'をクリックしたでしょ?';
}
// ]]></script>

 

 

addEventListenerで呼び出す関数は引数を指定できません

c1.addEventListener('click',clk,false);

これは、
「c1というidを持つ要素に対し、クリックされた時にclkという関数を実行するようにします」
という意味のコードですが、JavaScriptで大抵、関数を呼び出す時、
関数名(引数)

という形なんですね。(引数を使わない場合でも関数名()という書き方になります)

 

それが、addEventListenerの時には何故か ( ) も書かない、という事になっています。

 

引数を使用して一つの関数を使いまわしたい時に、例えばクリックなら
「どれがクリックされたか?」を判別する方法にちょっと悩みました^^;

 

 

イベントオブジェクトから発生元要素のIDを取り出す

イベントリスナーなので、まず「ユーザーがクリックした」というイベントがあって初めて発動するわけです。

そこで呼び出される関数は、「イベントオブジェクト」を引数として取得できます。

 

function clk(e){
gamen.innerHTML=e.srcElement.id+'をクリックしたでしょ?';
}

の、
clk(e)

の部分ですね。

こう書くと、変数e(任意の名前)に発生したイベントオブジェクトが入ります。

 

…ああ!なるほど!!
だからイベントリスナーが呼び出す関数には引数がなくて、ないから ( ) も不要って事になってるんだ!
もし引数が使えたら、関数側で
「なんか貰ったけど、これは引数なのかイベントなのか?」
ってなっちゃいますもんねw

…と、書きながら納得したところで、次。

gamen.innerHTML=e.srcElement.id+'をクリックしたでしょ?';

の部分。

 

まず、

e.srcElement

これが、「イベントが発生した要素(HTMLの要素)」そのものを差す事になります。

 

で、 .id をつけた
e.srcElement.id
が「イベントが発生した要素のid」って事になるんですね^^
(文字列として取得できます)

 

 

あとがき

今まで、aタグonclickオプションをつけて、そこから関数発動させたりしていましたが、「HTML・CSSJavaScriptの役割分担」って意味では addEventListener
スクリプトの仕事はスクリプトで書くようにしたほうがいいのでは?」
って思い始め、そのようにしようとして引っかかったトラップと、その対策の記録ですw

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^