現役エンジニアが教える!実践JavaScript入門 〜DOM操作とイベント処理の実践編〜

公開日:2022-09-05
JavaScript
DOM操作
イベント処理

https://youtu.be/VClASfpqq3M

今回の目的

実際の開発でDOM操作とイベント処理がどのように使われるのかをイメージできるようにしましょう。

実践内容

今回は前々回で紹介したMDNのDOM操作の記事から実践学習(動的な買い物リスト)を実際にやってみます。
作成するものは次の図のようなものであり、実装したい機能としては次の3つあります。

  • 入力フォームから商品を入力することでリストに追加される。
  • 商品を追加ボタンを押したら入力フォームに書いてあった商品名を消す。
  • リスト内でそれぞれの商品の横にあるdeleteボタンを押すと、商品の削除ができる。

完成図
完成図

https://developer.mozilla.org/ja/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documentshttps://developer.mozilla.org/ja/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents

実践手順

それではMDNの実践手順に沿って実装してみましょう。

  1. MDNにある次のhtmlファイルをダウンロードします。今回はコードを見やすくするためJavaScriptファイルを別で作り(index.js)、scriptタグから読み込ませます。

    index.html
    <!DOCTYPE html>
    <html lang="en-us">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Shopping list example</title>
        <style>
          li {
            margin-bottom: 10px;
          }
          li button {
            font-size: 8px;
            margin-left: 20px;
            color: #666;
          }
        </style>
      </head>
      <body>
        <h1>My shopping list</h1>
        <div>
          <label for="item">Enter a new item:</label>
          <input type="text" name="item" id="item">
          <button>Add item</button>
        </div>
        <ul>    
        </ul>
        <script src = "index.js"></script> <!--別ファイルでjsファイルを読み込む-->
      </body>
    </html>
    
  2. 1のhtml内で動的な動きをつけるulinputbuttonタグの参照を作成します。

    index.js
    const ulRef = document.querySelector("ul");
    const inputRef = document.querySelector("input");
    const buttonRef = document.querySelector("button")
    
  3. button要素がクリックされたときに応答として走らせる関数を指定します。関数の中身はまだ仮のものとして、クリックされたときに「click」とコンソールに表示させます。ここまでできたらbutton要素を押して「click」が表示されるか確認してみましょう。

    index.js
    buttonRef.addEventListener("click", ()=>{
       console.log("click");
    });
    
  4. 3で作ったbutton要素がクリックされた時に呼ばれる関数の中身を記述します。初めに、input要素に入力された値を変数に保持します。

    index.js
    buttonRef.addEventListener("click", ()=>{
       const value = inputRef.value; // inputRef.value: inputの情報を取得
    });
    
  5. 次に商品の追加ボタンを押したら入力フォームにある商品名を消すため、関数内でinput要素の情報に空文字を代入します。これでinputタグとbuttonタグの連携は完了です。

    index.js
    buttonRef.addEventListener("click", ()=>{
       const value = inputRef.value;
       inputRef.value = "";
    });
    
  6. 次は商品リストの作成に取り掛かります。初めに商品リストで必要なlispanbutton要素を作成します。

    index.js
    const liRef = document.createElement("li");
    const spanRef = document.createElement("span");
    const itemButtonRef = document.createElement("button");
    
  7. 作成したspanbutton要素をli要素の子に追加します。

    index.js
    liRef.appendChild(spanRef);
    liRef.appendChild(itemButtonRef);
    
  8. 次に作成したspanbutton要素のテキストコンテントをそれぞれinputの情報とdeleteにします。そのためbutton要素がクリックされたときに応答として走らせる関数に今まで書いたものを合わせて次のように書き換えます。

    index.js
    buttonRef.addEventListener("click", ()=>{
       const value = inputRef.value;
       inputRef.value = "";
    
       const liRef = document.createElement("li");
       const spanRef = document.createElement("span");
       const itemButtonRef = document.createElement("button");
    
       spanRef.textContent = value;            // spanタグのテキストコンテンツにvalueを追加
       itemButton.textContent = "delete";   // buttonタグのテキストコンテンツにdeleteを追加
    
       liRef.appendChild(spanRef);
       liRef.appendChild(itemButtonRef);
    });
    
  9. 作成したリスト項目であるliulの子に追加します。ここまでできたらinput要素から商品を追加することで商品リストに追加されるか確認しましょう。

    index.js
    buttonRef.addEventListener("click", ()=>{
       const value = inputRef.value;
       inputRef.value = "";
    
       const liRef = document.createElement("li");
       const spanRef = document.createElement("span");
       const itemButtonRef = document.createElement("button");
    
       spanRef.textContent = value;            
       itemButton.textContent = "delete";    
    
       liRef.appendChild(spanRef);
       liRef.appendChild(itemButtonRef);
       ulRef.appendChild(liRef);
    });
    
  10. 次に削除ボタンにイベントハンドラーを追加して、クリックをすると商品を削除できるようにします。そのため9で作成していた関数内に次を追記します。

    index.js
    itemButtonRef.addEventListener("click", ()=>{
       liRef.remove();   // liを削除
    })
    
  11. 最後に商品を追加した後に次の商品も追加しやすいよう、focusメソッドを使って図のようにカーソルを合わせるようにします。以上で動的な買い物リストの完成です。

    フォーカスしたinput

    index.js
      inputRef.focus();
    

追加機能: エンターキーで商品を追加する

追加機能としてinputに商品を書きエンターを押すだけで商品を追加する機能の実装をします。
特定のキーが押された終わった際には、keyupイベントが発生します。また複数箇所で記述が必要になる商品のリスト表示をhandleAddItemという関数で切り出すことによって記述が冗長になるのを防ぎました。最後にエンターのキーコードである13で場合分けを行うことで簡単に追加機能の実装ができます。

index.js
const handleAddItem = () => {   // 商品の追加をhandleAddItemという関数で切り出す
   const value = inputRef.value;
   inputRef.value = "";

   const liRef = document.createElement("li");
   const spanRef = document.createElement("span");
   const itemButtonRef = document.createElement("button");

   spanRef.textContent = value;            
   itemButton.textContent = "delete";    

   liRef.appendChild(spanRef);
   liRef.appendChild(itemButtonRef);

   itemButtonRef.addEventListener("click", ()=>{
      liRef.remove();   
   })
   inputRef.focus();

   ulRef.appendChild(liRef);
}

buttonRef.addEventListener("click", handleAddItem);  // handleAddItemを第2引数で呼び出す

inputRef.addEventListener("keyup", (e) = {
   if(e.keyCode === 13) {  // 押されたキーがエンターだったら
      e.preventDefault();  // 標準のイベントの伝達を防ぐ
      handleAddItem();
   }  
})

まとめ

今回はMDNのDOM操作の実践学習を解説しました。次回はブラウザのファイル操作について解説します。