IORI online School

JavaScript、html、css の無料学習サイト

【JavaScript 中級講座】DOMのイベントに関数を登録する

[JavaScript 中級講座]DOMのイベントに関数を登録する

本講座では、イベントと関数の関係を学習する。 学習のメインは関数である。関数を自由に利用する事が主たる目的である。 関数を学習するために、イベントを例として活用する。

HTMLタグの操作のタイミング

001<html><head>
002<script>
003
004//[li]タグを取得
005const items =
006  document.getElementsByTagName ( "li" ) ;
007
008//[0]
009alert ( items.length ) ;
010</script>
011</head>
012<body>
013  <ol id = "list" >
014    <li>お茶</li>
015    <li>コーヒー</li>
016    <li>水</li>
017  </ol>
018</body>
019</html>
プログラムを実行すると、「0」と表示する。

このプログラムは、プログラマーが想定した結果にはならない。
プログラムを解説する。6行目で、「li」タグを全て取得して、 変数itemsへ代入する。

document.getElementsByTagName()関数
タグ名を指定してタグのオブジェクトを取得する
document.getElementsByTagName()関数の使用方法
const collection =
   document.getElementsByTagName( [タグ名] )

Web画面の特定のタグを操作したい場合がある。 その場合、タグ名を引数に渡して、documentオブジェクトのgetElementsByTagName()関数を実行すると、 引数で指定したタグ名に一致するタグのオブジェクトを戻してくれる。 戻り値は「 HTMLCollection 」である。 HTMLCollection は配列に似ている。配列ではないが配列に似ている。

004//[li]タグを取得
005const items =
006  document.getElementsByTagName ( "li" ) ;
007
008//[0]
009alert ( items.length ) ;
010</script>
011</head>
012<body>
013  <ol id = "list" >
014    <li>お茶</li>
015    <li>コーヒー</li>
016    <li>水</li>
017  </ol>

6行目で、documentオブジェクトのgetElementsByTagName ()関数を利用して、 liタグを取得する。getElementsByTagName ()関数の戻り値を変数itemsへ代入する。 HTMLファイルの部分に、liタグが3つ記載されている。 「お茶」「コーヒー」「水」の3つである。 変数itemsには、この3つのliタグが代入されている・・・と思われる。 しかし実際は違う。 9行目で、変数itemsの中に入った要素数を確認する。

HTMLCollection.length
素数

HTMLCollectionのlengthプロパティを利用すると、要素数を取得できる。 こんかい、liタグは「お茶」「コーヒー」「水」の3つである。 9行目で「3」と表示されると思ったのだが、「0」と表示した。 原因はなんだろうか?

DOM操作のタイミング
HTMLのタグが利用可能になる前に、HTMLのタグを操作できない。 HTMLのタグが利用可能になった後、タグを操作する

Webブラウザを開くと、HTMLファイルに記載されたタグがWebブラウザに読み込まれる。 HTMLタグを操作する場合、 HTMLタグが読み込まれた後に操作する必要がある。 HTMLタグが読み込まれる前に、HTMLタグは操作できない。

001<html><head>
002<script>
003
004//[ol]タグを取得
005const ol =
006  document.getElementById ( "list" ) ;
007
008//[null]
009alert ( ol ) ;
010</script>
011</head>
012<body>
013  <ol id = "list" >
014    <li>お茶</li>
015    <li>コーヒー</li>
016    <li>水</li>
017  </ol>
018</body>
019</html>
プログラムを実行すると「null」と表示する。

6行目で、documentオブジェクトのgetElementById()関数を実行してタグを取得する。 関数の引数に文字列「list」を指定する。 idが「list」のタグは、13行目のolタグである。 olタグを取得して5行目の変数olへ代入する。 9行目で変数olを表示する。ここで、olタグが表示する予定だったが、 「null」と表示する。つまり、6行目のgetElementById()関数が上手く機能しなかったという事だ。 理由は、前回のプログラムと同じである。 HTMLタグが作られる前に、HTMLタグを利用した事である。

window.onloadに関数を登録する

window.load()関数に関数を登録するプログラムを見る。

001<script>
002//ロード完了後、実行
003window.onload = function () {
004    alert ( "IORI" ) ;
005}
006</script>
プログラムを実行すると「IORI」と表示する。
windowオブジェクト
Webブラウザ全体を管理するオブジェクト

JavaScriptWebブラウザ上で実行すると、windowオブジェクトを利用できる。 windowオブジェクトは、Webブラウザ全体を管理するオブジェクトである。 オブジェクトとは、プロパティや便利な関数が入った箱である。 つまり、windowオブジェクトの中には、Webブラウザを管理するための便利な プロパティや関数が入っている。

window.onload() 関数
window.onload()関数は、Webブラウザ読み込み後に実行する

windowオブジェクトのonload()関数は、 Webブラウザの読み込みが完了した時点で実行する。 では、プログラムを解説する。

001<script>
002//ロード完了後、実行
003window.onload = function () {
004    alert ( "IORI" ) ;
005}
006</script>

3行目のイコール記号の右側を見る。 functionキーワードで関数を定義している。 関数の処理は4行目である。 文字列「IORI」を表示する処理であるが、いまここで関数が実行する事は無い。 3行目は、関数の定義をしているだけである。実行はしない。
さて、3行目のイコール記号の左側を見る。

window.onload

これは、windowオブジェクトのonload()関数を意味する。 例を挙げる。

001<script>
002//オブジェクト生成
003const IORI = { } ;
004
005//関数を定義
006IORI.onload = function () {
007  alert ( "走る" ) ;
008}
009//[走る]
010IORI.onload ( ) ;
011
012//新しい関数を登録
013IORI.onload = function () {
014  alert ( "昼寝" ) ;
015}
016//[昼寝]
017IORI.onload ( ) ;
018</script>
プログラムを実行すると「走る」「昼寝」と表示する。

プログラムを解説する。3行目で空のオブジェクトを生成して、変数IORIへ代入する。 6行目で、IORIオブジェクトのonloadプロパティに関数を代入する。 IORIオブジェクトのonloadプロパティは、関数という事になる。 10行目で、onload()関数を実行すると「走る」と表示する。 13行目で、IORIオブジェクトのonlooad関数に新しい関数を代入する。 17行目で、onload()関数を実行すると、「昼寝」と表示する。
このプログラムのように、すでに存在する関数を新しい関数で上書きできる。 もういちど、今回のサンプルプログラムを見る。

001<script>
002//ロード完了後、実行
003window.onload = function () {
004    alert ( "IORI" ) ;
005}
006</script>

3行目でwindowオブジェクトのonloadへ、独自に作成した関数を代入する。 windowオブジェクトのonload()関数は、 Webブラウザ読み込み後に実行する。 今回、この関数に独自に作成した関数を代入した。 つまり、Webブラウザ読み込み完了後に、独自に作成した関数が実行する。

window.onloadに関数を登録してDOM操作を実行する

いま問題になっているのは、JavaScriptを動かす時に、HTMLタグが存在しないという事である。 では、HTMLタグが読み込まれた後にJavaScriptを動かせば良い。 それが、今回見るサンプルプログラムである。

001<html><head>
002<script>
003//ロード完了後、実行
004window.onload = function () {
005
006  //[ol]タグを取得
007  const ol =
008    document.getElementById ( "list" ) ;
009
010  //[3]
011  alert ( ol.children.length ) ;
012}
013</script>
014</head>
015<body>
016  <ol id = "list" >
017    <li>お茶</li>
018    <li>コーヒー</li>
019    <li>水</li>
020  </ol>
021</body>
022</html>
プログラムを実行すると、「3」と表示する。

今回のプログラムは、プログラムが想定した通りに動く。 いま、Webブラウザが読み込みを完了した後に、処理を実行したい。 windowオブジェクトのonload()関数へ、実行したい関数を代入すると、 読み込み完了後にその関数が実行する。
プログラムを解説する。

003//ロード完了後、実行
004window.onload = function () {
005
006  //[ol]タグを取得
007  const ol =
008    document.getElementById ( "list" ) ;
009
010  //[3]
011  alert ( ol.children.length ) ;
012}
015<body>
016  <ol id = "list" >
017    <li>お茶</li>
018    <li>コーヒー</li>
019    <li>水</li>
020  </ol>

4行目のイコールの右側に注目する。 functionキーワードを利用して、関数を定義している。 関数の処理は、7行目から11行目までである。 この関数は、今は実行しない。 windowオブジェクトのonloadプロパティへ代入しただけである。
では、時間を進める。WebブラウザがHTMLタグの読み込みを完了すると、 windowオブジェクトのonload()関数が実行する。 windowオブジェクトのonload()関数は、7行目から11行目までの関数である。 ここで、7行目が実行する。 まず、document.getElementById()関数が実行して、 idが「list」のタグを取得する。 idが「list」のタグはolタグである。 7行目の変数olにolタグのオブジェクトが代入する。 すでにHTMLタグの読み込みは完了しているので、 変数olには、確かにolタグのオブジェクトが入る。 11行目で、olタグの子要素の数を表示する。

子要素数の取得
タグオブジェクト.children.length

11行目が実行すると、「3」と表示してプログラムは終了する。
プログラムの解説は以上である。 「関数を登録する」という点をご理解頂ければと考える。

リストへonclickイベントを動的に登録する

リストがクリックされた時に、プログラムを実行する方法を学習する。

001<html><head>
002<script>
003//ロード終了後に呼ばれる
004window.onload = function ( ) {
005
006  //[li]タグを取得
007  const items =
008    document.getElementsByTagName("li");
009
010  for ( var i = 0 ; i < items.length ; i ++ ) {
011  
012    //liタグを取得
013    const li = items [ i ] ;
014    
015    //liタグにイベント追加
016    li.onclick = function ( evt ) {
017    
018        //liタグを取得
019        const tag = evt.target ;
020        
021        //タグのラベルを表示
022        alert ( tag.textContent ) ;
023    }
024  }
025}
026</script>
027</head>
028<body>
029  <ol>
030    <li>お茶</li>
031    <li>コーヒー</li>
032    <li>水</li>
033  </ol>
034</body>
035</html>
[画面]
  • お茶
  • コーヒー
Webブラウザでファイルを開くと、文字列が3つ表示する。 それぞれの文字列をクリックすると ダイアログが開いて、クリックした文字列が表示する。

文字列をクリックすると、クリックした文字列がダイアログに表示するプログラムである。 では、解説する。

003//ロード終了後に呼ばれる
004window.onload = function ( ) {
005
006  //[li]タグを取得
007  const items =
008    document.getElementsByTagName("li");

4行目で、window.onloadプロパティに関数を代入する。 ここで代入した関数は、Web画面のロードか完了したタイミングで実行する。 では、Web画面のロードが完了したと仮定する。 まず、8行目で「li」タグを全て取得して、変数itemsへ代入する。 変数itemsには、HTMLで記載されているliタグのHTMLCollection(配列のようなもの)が代入される。 こんかい、「お茶」「コーヒー」「水」の3つのliタグが代入される。 変数itemsの状態は次の通りである。

インデックス
0 お茶
1 コーヒー
2
010  for ( var i = 0 ; i < items.length ; i ++ ) {
011  
012    //liタグを取得
013    const li = items [ i ] ;
014    
015    //liタグにイベント追加
016    li.onclick = function ( evt ) {
017    
018        //liタグを取得
019        const tag = evt.target ;
020        
021        //タグのラベルを表示
022        alert ( tag.textContent ) ;
023    }

10行目でfor文を利用して、itemsの中身を取り出す。 for文はitemsの要素数、すなわち「3」回実行する。 for文1回目。13行目で「お茶」のliタグが取り出される。 16行目でそのliタグのonclickプロパティに値を代入する。

onclick
タグがクリックされた時に実行する関数

タグをクリックした時に何か処理をしたい場合、 onclickプロパティに関数を代入する。
こんかい、liタグがクリックされた時に、liタグに表示している文字列を、 ダイアログに表示したい。
まず、16行目でliタグのonclickプロパティに関数を代入する。 liタグがクリックされると、代入した関数が実行する。 では、関数の処理を見る。

015    //liタグにイベント追加
016    li.onclick = function ( evt ) {
017    
018        //liタグを取得
019        const tag = evt.target ;
020        
021        //タグのラベルを表示
022        alert ( tag.textContent ) ;
023    }

「お茶」のliタグをクリックすると、19行目と22行目が実行する。 まず19行目で、引数evtのtargetプロパティを変数tagへ代入する。

MouseEventオブジェクト.target
ユーザーがクリックしたタグが入っている

ユーザーが「お茶」のliタグをクリックすると、 16行目の引数evtにMouseEventオブジェクトが渡されて関数が実行する。 MouseEventオブジェクトのtargetタグに、ユーザーがクリックしたタグが入っている。 つまり、「お茶」のliタグが、変数evtのtargetプロパティに入っている。 そのliタグを変数tagで受け取る。 こんかい、liタグの文字列を表示する。 22行目で、変数tagが参照するオブジェクト、すなわちliタグの textContentプロパティを表示する。

タグ.textContent
タグに表示している文字列

プログラムが実行すると、「お茶」と表示する。
さて、こんかい「お茶」のliタグを例にして解説した。 ほかの「コーヒー」も「水」も同様である。

textareaに入力した文字数をカウントする

最後に、少しツールっぽいものを作成する。 textareaに文字を入力するたびに、文字数をカウントして表示するプログラムである。

001<html><head>
002<script>
003//読み込み完了後に呼ばれる
004window.onload = function ( ) {
005
006  //[textarea]タグを取得
007  const txt =
008    document.getElementById("txt");
009  
010  //[p]タグを取得
011  const p =
012    document.getElementById("count");
013  
014  //キーが上がったイベントを追加
015  txt.onkeyup = function ( evt ) {
016  
017    //キーが上がった場合、文字数を取得する
018    const len = evt.target.value.length
019    
020    //[p]タグへ表示
021    p.textContent = len ;
022  }
023}
024</script>
025</head>
026<body>
027  <textarea id="txt" rows="15" cols="50" ></textarea>
028  <p id="count" ></p>
029</body>
030</html>
[画面]
 
Webブラウザでファイルを開くと、テキストエリアが表示する。
[画面]
IORI 
4
テキストエリアに文字を文字を入力するたびに、文字数が表示する。

では、解説する。まずHTMLファイルを見る。

026<body>
027  <textarea id="txt" rows="15" cols="50" ></textarea>
028  <p id="count" ></p>
029</body>

27行目でtextareaタグを記述して、id属性の値を「txt」とする。 28行目でpタグを記述して、id属性の値を「count」とする。 こんかい、textareaに文字を入力するたびに文字数をカウントして、 pタグへ表示する処理を書く。

  1. textareaに文字を入力するタイミングで、関数を実行する
  2. 関数内でtextareaの文字をカウントする
  3. 文字数をpタグへ表示する

この手順でプログラムを書く。では、プログラムを見る。

003//読み込み完了後に呼ばれる
004window.onload = function ( ) {
005
006  //[textarea]タグを取得
007  const txt =
008    document.getElementById("txt");
009  
010  //[p]タグを取得
011  const p =
012    document.getElementById("count");
013  
014  //キーが上がったイベントを追加
015  txt.onkeyup = function ( evt ) {
016  
017    //キーが上がった場合、文字数を取得する
018    const len = evt.target.value.length
019    
020    //[p]タグへ表示
021    p.textContent = len ;
022  }
023}

4行目で、windowオブジェクトのonloadプロパティに関数を代入する。 HTMLの読み込みが完了した時点で、関数が実行する。 7行目で、textareaタグのオブジェクトを取得して変数txtへ代入する。 11行目で、pタグのオブジェクトを取得して、変数pへ代入する。 15行目で、textareaオブジェクトのonkeyupプロパティに関数を代入する。

onkeyup
ユーザーがキーボードのキーを押して上げたタイミングで、 実行する関数

いま、ユーザーがキーを入力するたびに何か処理をしたい。 ユーザーがキーを入力するたびに実行する関数は、 onkeyupプロパティに入っている関数である。 つまり、onkeyupプロパティに関数を代入すると、 キーが上がるたびに関数が実行する。 では、キーが上がるたびに何をするのだろうか?

013  
014  //キーが上がったイベントを追加
015  txt.onkeyup = function ( evt ) {
016  
017    //キーが上がった場合、文字数を取得する
018    const len = evt.target.value.length
019    
020    //[p]タグへ表示
021    p.textContent = len ;
022  }

ユーザーが文字を入力して、キーを持ち上げたタイミングで、 18行目と21行目が実行する。 まず18行目で、・・・、多くの処理を1行で実行している。

プログラム 置換え 解説
evt.target KeyboardEvent.target textareaオブジェクトを取得
evt.target.value textarea.value テキストエリアの文字を取得
evt.target.value.length textareaの文字.length テキストエリアの文字数を取得

15行目のfunctionの引数evtのtargetプロパティには、 onkeyupの関数が実行した、そのタグが入っている。 こんかい、textareaタグのonkeyupが実行した。 つまり、functionの引数evtのtargetプロパティには、textareaタグが入っている。 一般的には、イベント発生元のタグが targetプロパティに入っている、と言う。

イベントが発生
ユーザーが何かアクションを起こす事を「イベントが発生した」と言う。

こんかい、ユーザーがテキストエリアに文字を入力する。 それがイベントである。文字を入力するたびにイベントが発生する。 イベント発生元は、テキストエリアとなる。

013  
014  //キーが上がったイベントを追加
015  txt.onkeyup = function ( evt ) {
016  
017    //キーが上がった場合、文字数を取得する
018    const len = evt.target.value.length
019    
020    //[p]タグへ表示
021    p.textContent = len ;
022  }

18行目で、テキストエリアの文字数を変数lenへ代入する。 21行目で、pタグのtextContentプロパティに変数lenの値を代入する。 以上にて、ユーザーが文字を入力するたびに、テキストエリアの文字数が、pタグに記載される。

まとめ

document.getElementsByTagName()関数
タグ名を指定してタグのオブジェクトを取得する
document.getElementsByTagName()関数の使用方法
const collection =
   document.getElementsByTagName( [タグ名] )
windowオブジェクト
Webブラウザ全体を管理するオブジェクト
window.onload() 関数
window.onload()関数は、Webブラウザ読み込み後に実行する
子要素数の取得
タグオブジェクト.children.length
onclick
タグがクリックされた時に実行する関数
イベントが発生
ユーザーが何かアクションを起こす事を「イベントが発生した」と言う。