Rails Diary

プログラミングの学習記録です。

JSとDOM

DOM(Document Object Model)

ドキュメントを物として扱うモデル。 JSからHTMLにアクセスする仕組みのこと。この仕組みによって文書構造、スタイル、内容を変更することができる。DOMを操作して画面をちょこちょこ変えるのがJSの役割(ただし、ひと昔前の内容らしい)

https://www.w3schools.com/js/pic_htmltree.gif
DOMのツリー構造 JavaScript HTML DOM

DOMは、文書をノードとオブジェクトで表現する。ノードとは、上記画像における一つ一つの要素のことをそう呼ぶ。HTMLにおけるエレメントやタグのこと。

ウェブページは文書です。この文書はブラウザーのウィンドウに表示されるかHTMLソースとして表示することが可能です。しかし両方の場合においてもそれは同じ文書です。ドキュメントオブジェクトモデル(DOM)は、その同じ文書を表現、保存する方法です。DOMはウェブページの完全なオブジェクト指向の表現で、JavaScriptのようなスクリプト言語から変更できます。

ID名からノードを取得し、操作する

<button id="button-delete">削除ボタン</button>
<button id="button-update">更新ボタン</button>
コンソールに以下を打ち込む

document.getElementById("id名")

ID名から要素を取得するメソッド

https://i.gyazo.com/c31ea2c554e2578879034df97f7622ea.png

button-deleteというIDが振られた要素が取得されている。
単なる文字列ではなくこれがDOMであり、オブジェクト。

https://i.gyazo.com/0483e3e6edbf8597e322ef7c7249ac9e.png

https://i.gyazo.com/e6bc4e4cd025568099d938f46585aab6.png

削除ボタンだけ赤になった。

上記のような方法で取得したオブジェクトを介してメソッドを実行することができる。

https://i.gyazo.com/4697dced0afe428243edd730e353fd9b.png

document.getElementById('ID名')で取得した要素を定数に代入し、定義した定数に対してinnerTextメソッドを用いるとタグに囲まれたテキストが表示された。

https://i.gyazo.com/ed38480e9a0266e1df1a901d32ece6d3.png

上記のように新たに文字列を代入するとボタンの文字が変更された。

https://i.gyazo.com/2563cc55ec90814661bf83f381845156.png

このようにコンソールにJSを打ち込むことでDOM(ドキュメントオブジェクトモデル)の取得ができる。実際はイベントドリブンと呼ばれる「何かをしたら何かが起きる」という処理を追加することで動かす。

  • あるボタンをクリックしたらポップアップを出す
  • マウスポインターがある文字の上に乗ったらその文字を色付ける
  • あるテキストエリアの内容が変更されたらそれらの文字をプレビュー表示する

イベントは下記のように設定する

DOMに対してaddEventListenerを設定することでイベントを仕掛けられる

// 一番上の行は「ブラウザがDOMの解析をし終わったら〜」というような一種のイベント設定処理
// この記述がないと、DOMの解析がし終わる前に、削除ボタンのDOMを取得しようとするなど上手く動かないことがある
document.addEventListener('DOMContentLoaded', () => {
  console.log("DOMContentLoaded")

  // 削除ボタンのDOMを取得
  const buttonDelete = document.getElementById("button-delete")
  // 更新ボタンのDOMを取得
  const buttonUpdate = document.getElementById("button-update")
  
  // 削除ボタンにクリックイベントを仕掛ける
  buttonDelete.addEventListener('click', () => {
    // クリックされた時に動く処理
    alert("削除!")
  })

  // 更新ボタンにクリックイベントを仕掛ける
  buttonUpdate.addEventListener('click’, () => {
    // クリックされた時に動く処理
  })
});

https://i.gyazo.com/70b742cfd76215f7ec8d189e4be853bb.png

↑クリックイベントを仕掛けた後、実際にボタンをクリックすると、こんな感じで画面上部にポップアップが出現する。

演習の考え方まとめ

(なぜか画像が陰った・・・)

https://i.gyazo.com/d113b002035105bba0b6df03e89834ce.png

↑アラートボタンをクリックするとテキストエリア内に記載した文字がポップアップとして出現する

やってみたこと(失敗)

<p>テキストエリアの内容をアラートで出す</p>
<textarea id="textarea"></textarea>
<button id="button">アラート</button>
document.addEventListener('DOMContentLoaded', ()=>{
  console.log("DOMContentLoaded")
  
  const buttonAlert = document.getElementById('button')
  const textarea = document.getElementById('textarea').innerText

  buttonAlert.addEventListener('click', ()=>{
    alert(textarea)
  })
});

ボタンが反応しなかった・・・
原因はよく分からないけど、パソコン再起動で解決した

検証でコードを確認した

https://i.gyazo.com/2c48c5b42c1260669e1aa74252af56f6.png

innerTextメソッドを使ってしまったので、タグに囲まれた内容を表示しようとしているのが間違いだったのかも?

検証の内容を参考に下記のように書き換える(成功)

参考というか検証のカンニングです。

<textarea id="textarea"></textarea>
<button id="button">アラート</button> 
document.addEventListener('DOMContentLoaded', () => {
    console.log("DOMContentLoaded")
    const button = document.getElementById("button")
    button.addEventListener('click', () => {
      const text = document.getElementById('textarea')
      alert(text.value)
    })
});

https://i.gyazo.com/576803e82e7fe487c1e6a03b9a2b08a1.png

https://i.gyazo.com/9d99317c38474417384dbdad212c1ec7.png

できた!

考え方

  • テキストエリア内の内容を特定したいのでidを指定
  • ボタンも特定したいのでidを指定

  • アラートを押した時に何かしたい

  • まずアラートのDOMを取ってくる
    const buttonAlert = document.getElementById('button')

↑これに対してイベントを設定したい

const text = document.getElementById('textarea');
buttonAlert.addEventListener('click', ()=>{
  const value = text.value // 一々定数に入れなくてもOK
  alert(value)
});

最初からalert(text.value)でいい。

演習2

全く分からなかったので、検証で調べた。

https://i.gyazo.com/b695bfc5467caa4a498ca5a373097222.png

<label for="amount">数値</label>
<input type="number" name="amount" id="js-amount">
<button id="js-add-button">増やす</button>
<button id="js-minus-button">減らす</button>

<p>結果</p>
<p id="js-result">0</p>

まず、何はともあれDOMを取得しておく

const jsAddButton = document.getElementById('js-add-button')
const jsMinusButton = document.getElementById('js-minus-button')
const jsAmount = document.getElementById('js-amount')
const jsResult = document.getElementById('js-result')

jsAddButton.addEventListener('click', ()=>{
  // 試しにここでalert('jsAmount.value')など入れてみてちゃんと動くか、またどう表示されるのか確認する
  // 少しずつ少しずつ実装しよう◎
  // jsResultのinnerTextに対してjsAmountの値を入れている
  jsResult.innerText = jsAmount.value
})

この時点で、inputに入力した内容を結果に表示させることには成功

https://i.gyazo.com/a769ee62b6a2b218a10c2c77e1061572.mp4

const jsAddButton = document.getElementById('js-add-button')
const jsMinusButton = document.getElementById('js-minus-button')
const jsAmount = document.getElementById('js-amount')
const jsResult = document.getElementById('js-result')

// 現在値を取得。最初は0で設定する
var currentValue = 0

jsAddButton.addEventListener('click', ()=>{
  jsResult.innerText = currentValue + jsAmount.value
})

↑のようにしてみると・・・

https://i.gyazo.com/ceb18d08737aeb5c198d7a1523aee632.mp4

上手くいかない。
jsAmount.valueはあくまでも文字列として取得した値なので、文字列のまま足されてしまい、思う結果にならない。このため、文字列を数値に変換する作業が必要。

parseIntを使う

currentValue = currentValue + parseInt(jsAmount.value)
jsResult.innerText = currentValue

https://i.gyazo.com/cf6fd88f196ab22f0d32b17735e48600.mp4

できた!感動😳

減らすボタンは増やすボタンをコピペして、AddをMinusに、+をーに変更すればOK

https://i.gyazo.com/4460af2e2b31fe9aad50b447207e5b0d.mp4

演習3

何も分からない笑

https://i.gyazo.com/ce9f8167da9d585e5e6b4f5da5041584.png

<input type="text" placeholder="GitHubアカウント名" id="github-name">
<button onclick="fetchRepositories()">リポジトリ取得</button>
<ul id="repository-lists">
  <!-- 例 -->
  <!-- <li><a href="url************">repo-name</a></li> -->
</ul>

https://i.gyazo.com/37254cced380bb39bc2e549e9a7667de.png

const fetchRepositories = async () => {
  const githubName = document.querySelector("#github-name").value
  try}

感想

一気にやろうとすると死ぬので、まず一つ決めてどう記載すれば実現できるのか、細かく分けて考える。分からないことだらけなので、タスクを細分化するのがまず難しいです。慣れるしかなさそう。とはいえ、仕組みは解説動画を見て腑に落ちました👏