イベント処理(ボタンが押されたら実行等)について解説 ~Javascript超初心者入門
Javascriptのイベントとは
HTML(ウェブページ)で発生する動作のことです。
ユーザーの操作によるイベントは、例えばマウスの移動やクリック、タップ、セレクトボックスの選択肢の変更などがあります。
操作には関係のないイベントには、ページの読み込み完了、画像の読み込み完了、タイマー(今から1秒後、1秒間隔毎)などがあります。
特に「要素がクリックやタップされたタイミング = clickイベント」でJavascriptを実行したい場合は多いと思います。
下記は「click」イベントが発生したタイミングで関数myfuncを呼び出しています。
<button onclick="myfunc()">クリックやタップされたら関数「myfunc」を実行</button>
下記は「click」イベントが発生したタイミングで「alert('ボタンを押しましたね')」が実行され「ボタンを押しましたね」と表示されます。
<button onclick="alert('ボタンを押しましたね')">クリックやタップされたらJavascriptが実行</button>
このように、イベント(動作)に応答してプログラムが実行されることを「イベント駆動」又は「イベントドリブン」と呼ばれます。
要素の属性にイベントドリブンを記述する場合は属性名の先頭に「on」を付けます。
よって「click」イベントのイベントドリブンの属性名は「onclick」となります。
「mousemove」イベントのイベントドリブンの属性名は「onmousemove」となります。
JavascriptのからaddEventListener()メソッドでイベントドリブンを追加する
上記では、要素の属性としてイベントに応答しましたが、
要素.addEventListener("イベント", イベント発生時に実行したい関数名);
でイベントに応答することもできます。
<div id="test1" style="border:1px solid #666;background:#EEF;cursor:pointer;" >クリックでイベント発生</div> <script> //属性「id」が「test1」の要素を取得して変数「elm」に入れる let elm = document.querySelector("#test1"); //要素に「click」イベントが発生したら「test1」関数を呼ぶように設定する elm.addEventListener("click", test1); function test1(){ alert("divタグをクリックしましたね"); } </script>
【要注意】
以下の例のように<script>タグが上で<div>タグが下の場合はエラーになります。
HTMLのタグ構造は上から順に処理されます。よって<script>タグが処理されるタイミングで<div>タグ要素は未だ生成されてないのでエラーになります。
<script> //属性「id」が「test1」の要素を取得したいが要素が生成されていないのでエラー let elm = document.querySelector("#test1"); //要素に「click」イベントが発生したら「test1」関数を呼ぶように設定する elm.addEventListener("click", test1); function test1(){ alert("divタグをクリックしましたね"); } </script> <div id="test1" style="border:1px solid #666;background:#EEF;cursor:pointer;" >これはエラーの例</div>
上記は<script>タグ要素の位置によってはエラーになるということを示しています。
例えば<script>タグを</body>の下に配置すればエラーになることは少なくなります。
しかし、できれば<head>~</head>内に入れたかったりします。
解決策としてwindow要素の「DOMContentLoaded」イベントを利用すればエラー無く処理できるようになります。
window.addEventListener("DOMContentLoaded", イベント発生時に実行したい関数名));
window要素の「DOMContentLoaded」イベントは「全ての要素が読み込み完了(imgタグの画像などは未だ読み込んでない)」というイベントです。
ちなみにwindow要素の「load」イベントは「全ての要素も画像も読み込み完了」というイベントです。
ここから少し難しいのですが「無名関数」というものを使います。
通常、関数には名前を付けますが1度しか使わない関数なんだから、本来「関数名」を記述する箇所に名前のない関数をそのまま記述してしまえ、ということです。
<script> window.addEventListener( //window要素に全て要素が読み込まれたら関数を実行 "DOMContentLoaded", function(){ //無名関数 let elm = document.querySelector("#test2"); //id="test2"の要素を取得 elm.addEventListener( //elm要素がクリックされたら関数を実行 "click", function(){ //無名関数 alert("divタグをクリックしましたね"); } ); } ); </script> <div id="test2" style="border:1px solid #666;background:#EEF;cursor:pointer;" >test2</div>
このように記述すると、上から下に見るだけでソースコードを追いやすくなります。
いろいろなイベントを試す
inputイベント
inputイベントは、<input type="text">で文字を入力したときに発生するイベントです。
要素.addEventListener("input", function(){処理});
でイベントに応答します。
<div id="test3-2">入力した文字が表示されます</div> <input type="text" id="test3-1" placeholder="何か文字を入れてください"> <script> window.addEventListener( //window要素に全て要素が読み込まれたら関数を実行 "DOMContentLoaded", function(){ //無名関数 let elm = document.querySelector("#test3-1"); //id="test3-1"の要素を取得 elm.addEventListener( //elm要素に入力されたら関数を実行 "input", function(){ //無名関数 //イベントが発生したターゲット(input type="text")要素のvalueプロパティを表示する document.querySelector("#test3-2").innerHTML = event.target.value; } ); } ); </script>
mousemoveイベント
mousemoveイベントは要素上でマウスカーソルが移動したときに発生するイベントです。
要素.addEventListener("mousemove", function(){処理});
でイベントに応答します。
<div id="test4-1" style="background:#F0FFFF;padding:8px;"> ここは親要素です。この上でマウスを移動してください。 <p id="test4-2" style="background:#FFF0FF;padding:8px;"> ここは子要素です。この上で<span id="test4-3">マウスを移動</span>してください。 </p> </div> <div id="test4-1e">親要素でイベントが発生したら表示します</div> <div id="test4-2e">子要素でイベントが発生したら表示します</div> <script> window.addEventListener( //window要素に全て要素が読み込まれたら関数を実行 "DOMContentLoaded", function(){ //無名関数 //親要素内(id="test4-1")でマウスが移動したときのイベント document.querySelector("#test4-1").addEventListener( "mousemove", function(){ //無名関数 //イベントが発生したターゲット要素のvalueプロパティを表示する document.querySelector("#test4-1e").innerHTML = "親要素で発生したイベント<br>"+ " ターゲットは「"+event.target.tagName+"タグでidは"+event.target.id+"」で"+ "この要素内座標は "+event.offsetX+","+event.offsetY+"<br>"+ " ページ座標は "+event.pageX+","+event.pageY+"<br>"+ " クライアント座標は "+event.clientX+","+event.clientY; } ); //子要素内(id="test4-2")でマウスが移動したときのイベント document.querySelector("#test4-2").addEventListener( "mousemove", function(){ //無名関数 //イベントが発生したターゲット(input type="text")要素のvalueプロパティを表示する document.querySelector("#test4-2e").innerHTML = "子要素で発生したイベント<br>"+ " ターゲットは「"+ event.target.tagName +"タグでidは"+ event.target.id +"」で"+ "この要素内座標は "+ event.offsetX +","+ event.offsetY +"<br>"+ " ページ座標は "+ event.pageX +","+ event.pageY +"<br>"+ " クライアント座標は "+ event.clientX +","+ event.clientY ; } ); } ); </script>
ここは子要素です。この上でマウスを移動してください。
親要素は子要素を含んでいますので、子要素で発生したイベントは、親要素にも伝播します。
これを「イベントバブル」と呼ぶそうです。
プロパティ | 説明 |
---|---|
event.target |
実際にイベントが発生している要素です。 よって「event.target.tagName」でイベントが発生した要素のタグの名前(DIV とか P とか SPAN など)を取得できます。 |
event.offsetX event.offsetY |
ターゲット要素(event.target)内での左上を(0,0)とする座標を示します。 |
event.pageX event.pageY |
ページ全体で(スクロールして隠れた領域を含んだ)左上を(0,0)とする座標を示します。 |
event.clientX event.clientY |
見えている領域(スクロールして隠れた領域は含まない)の左上を(0,0)とする座標を示します。 |
changeイベント
チェックボックス<input type="checkbox">やラジオボタン<input type="radio">、<select>要素などで
チェックされたり解除されたり値が変わったときに発生するイベントです。
<label><input type="checkbox" id="test5-1">チェックを入れたり外したりしてください</label><br> <div id="test5-2"></div> <script> window.addEventListener( //window要素に全て要素が読み込まれたら関数を実行 "DOMContentLoaded", function(){ //無名関数 //チェックボックス要素(id="test5-1")でチェックを入れたり外したりしたら発生するイベント document.querySelector("#test5-1").addEventListener( "change", function(){ //無名関数 //イベントが発生したターゲット要素のチェック状態を調べる if( event.target.checked ){ document.querySelector("#test5-2").innerHTML="<span style='color:red;'>チェックしましたね</span>"; }else{ document.querySelector("#test5-2").innerHTML="<span style='color:blue;'>チェック外しましたね</span>"; } } ); } ); </script>