JavaScriptでクリックするたびに文字を出現させる処理をおこないます。
Contents
クリックされたら文字を表示
以下は最初はなにも表示されていませんが、クリックすると「鳩」という文字が追加されていくサンプルプログラムです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>鳩でもわかるJavaScript</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <script> // クリックされたときにやりたいことを {}のなかに書けばOK document.onclick = (ev) => { document.body.innerHTML += '鳩'; // 最後に「鳩」を1文字追加する }; </script> </body> </html> |
クリックすると「鳩」が追加されます。
要素がクリックされたら文字を表示
divタグなどの要素のなかに文字を追加するときは以下のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>鳩でもわかるJavaScript</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="./style.css" type="text/css" media="all" /> </head> <body> <div id="rectangle"></div> <script src="./app.js"></script> </body> </html> |
style.css
1 2 3 4 5 |
#rectangle { width: 300px; height: 200px; border: 1px solid #000; } |
app.js
1 2 3 4 5 |
let $rectangle =document.getElementById('rectangle'); $rectangle.onclick = (ev) => { $rectangle.innerHTML += '鳩'; } |
枠のなかをクリックすると「鳩」が追加されます。枠の外をクリックしたときは反応しません。
イベントの伝搬
イベントは伝搬します。以下のコードを書いて矩形のなかをクリックするとコンソールには「内」「外」の両方が出力されます。
app.js
1 2 3 4 5 6 7 8 9 |
let $rectangle =document.getElementById('rectangle'); $rectangle.onclick = (ev) => { console.log('内'); } document.onclick = (ev) => { console.log('外'); }; |
innerHTMLの注意点
では以下のコードだとどうなるのでしょうか? 矩形のなかをクリックすると矩形の内側と外の両方に文字が追加されるのでしょうか?
app.js
1 2 3 4 5 6 7 8 9 |
let $rectangle =document.getElementById('rectangle'); $rectangle.onclick = (ev) => { $rectangle.innerHTML += '内'; } document.onclick = (ev) => { document.body.innerHTML += '外'; }; |
実際にやってみるとわかりますが、「内」が追加されるのは1回だけです。先に矩形の外側をクリックすると「内」は1回も追加されません。内側をクリックすると「外」の文字は追加されていきますが、「内」は追加されません。
innerHTMLの代わりにinsertAdjacentHTML関数を使う
これはinnerHTMLを使っているのが原因です。
innerHTML を使用して HTML 要素を追加すると、以前設定したイベントリスナーを取り除くことになります。つまり、$rectangle.innerHTML += ‘内’;は実行されなくなってしまうのです。
ではどうすればいいのでしょうか?
innerHTMLの代わりにinsertAdjacentHTML関数を使います。そうすれば上記の問題は発生しません。
これなら矩形の内側をクリックした場合は内側には「内」の文字が追加されると同時に矩形の外側にも「外」の文字が追加されます。
矩形の外側をクリックした場合は「外」だけが追加されます。
app.js
1 2 3 4 5 6 7 8 9 10 11 |
let $rectangle =document.getElementById('rectangle'); $rectangle.onclick = (ev) => { //$rectangle.innerHTML += '内'; $rectangle.insertAdjacentHTML('beforeend', '内'); } document.onclick = (ev) => { //document.body.innerHTML += '外'; document.body.insertAdjacentHTML('beforeend', '外'); }; |
枠のなかをクリックすると枠の内側と外側の両方に文字が追加されます。
イベントの伝搬を止めるには?
では矩形の内側をクリックした場合は内側にのみ文字が追加されるようにするにはどうすればいいのでしょうか?
HTML ページ内でイベントが発生した場合、イベントは親要素へと伝搬していきます。しかしそれでは不都合な場合、イベントの伝搬を停止する方法が存在します。それがstopPropagation関数です。
これだと矩形の内側をクリックした場合は内側にのみ文字が追加されるようになります。
1 2 3 4 5 6 7 8 9 10 |
let $rectangle =document.getElementById('rectangle'); $rectangle.onclick = (ev) => { $rectangle.insertAdjacentHTML('beforeend', '内'); ev.stopPropagation(); // 伝搬を止める } document.onclick = (ev) => { document.body.insertAdjacentHTML('beforeend', '外'); }; |