LoginSignup
2
0

More than 3 years have passed since last update.

【備忘録】Javascript : 基本的なDOM操作

Posted at

DOMとは

DOMとはDocument Object Modelの略でマークアップ言語で書かれている文書にアクセスする為の仕組み。
DOMは文書内のタグや属性、要素がツリー(階層)構造で出来ていると捉えている。またDOMはそれらの構成要素をオブジェクトと見なしノードと呼んでいる。(要素ノード属性ノードテキストノードといった具合に。)

例)
・html,head,title,body,p... : 要素ノード
・carset,id,name,lang... : 属性ノード

頻出の要素の取得方法

1. getElementById

指定されたid値を持つ要素をElementオブジェクトとして返します。

sample.html

<span id="result"></span>
javascript.js
let current = new Date(); // 実行日時取得
let result = document.getElementById('result');
// id値が'result'の要素を取得し、変数resultに代入
result.textContent = current.toLocaleString();
// toLocaleStringメソッドにより文字列化し、'result'要素にテキストとして埋め込み

2. getElementsByTagName

指定されたタグ名を持つ要素をHTMLCollectionとして返します。
今の段階ではHTMLCollectionは配列と考えてもらって構わないと思います。注意すべきはタグ名の場合はid値と異なって複数の要素が取得出来る為、メソッド名もElementが複数形になっています。

sample.html

<ul>
    <li><a href="https://www.google.com/" name="google" >google</a></li>
    <li><a href="https://www.firefox.com/" name="firefox" >firefox</a></li>
    <li><a href="https://www.yahoo.co.jp/" name="yahoo" >Yahoo!</a></li>
    <li><a href="https://www.twitter.com/" name="twitter" >twitter</a></li>
    <li><a href="https://www.amazon.com/" name="amazon" >amazon</a></li>
</ul>
javascript.js
let list = document.getElementsByTagName('a'); // aタグを全て取得 => htmlコレクションを取得
      let firefox = list.namedItem('firefox'); // name属性が'firefox'のものを取得

      for (let i = 0; i < list.length; i++) {
        console.log(list.item(i).text); // collection.item => 要素
        // google,firefox,Yahoo!,twitter,amazon
      }

console.log('name=f : ' + firefox); // name=f : https://www.firefox.com/
console.log(list); 
// HTMLCollection(5) [a, a, a, a, a, google: a, firefox: a, yahoo: a, twitter: a, amazon: a]

返り値のHTMLCollectionをfor文で回し、要素を一つずつ、ログ出力している箇所に注目してください。list.item(i).textを見てもらうとlistに対してitemメソッドとその順番を指定して取得しています。これはそういうもんだと割り切って覚えてしまうのが良いでしょう。その後のtextメソッドは取得した要素のテキストを取得しています。ちなみに別の取得の仕方もありますので試してみてください。

3. getElementsByName

name属性を指定して要素を取得します。結果、NodeListオブジェクトを返してくれます。個人の感覚ですがあまりHTMLCollectionと大差ありません。参考書にも載っていましたがnamedItemメソッドが使えないくらいみたいです。ラジオボタンやチェックボックスなど、同じname属性をもつ要素群を取得するのに使用するみたいです。

sample.html

<form>
    <div>
      好きな食べ物は? :
      <label><input type="checkbox" name="food" value="ラーメン">ラーメン</label>
      <label><input type="checkbox" name="food" value="餃子">餃子</label>
      <label><input type="checkbox" name="food" value="焼肉">焼肉</label>
      <input type="button" id="btn" value="送信">
    </div>
  </form>
javascript.js

document.getElementById('btn').addEventListener('click',function(){
  let result = []; // 空の配列を準備
  let foods = document.getElementsByName("food");
  // name="food"の物を全て取得

  for (let i = 0; i < foods.length; i++){
    // 取得したものを全てチェックする
    let food = foods.item(i);
    if(food.checked){
      // 各要素のfoodのcheckedがtrueの場合、空の配列にvalueをpushする
      result.push(food.value);
    }
  }

  window.alert(result.toString());
},false)

上記の例をみてもらうとname属性で指定して同じ要素群を取得し、checkedがtrueの要素のみvalueを取得しています。チェックボックスの判定の例ですが基本、ラジオボタンも同様の取得の方法です。

4. getsElementsByClassName

クラス属性を指定して取得します。name属性やタグ属性と同じようにelementが複数形になっている所に注意してください。

sample.html
<ul>
  <li><a href="#" class="language">Javascript</a></li>
  <li><a href="#" class="language">Java</a></li>
  <li><a href="#" class="language">Ruby</a></li>
</ul>
javascript.js

let list = document.getElementsByClassName('language'); // class属性が'language'の要素取得
for (let i = 0; i<list.length; i++){
  console.log(list.item(i).text);
  /**
   * Javascript,Java,Ruby
   */
}

5. querySelector, querySelectorAll

cssと同じようにセレクター式で要素を指定し取得することが可能です。これにより今まで紹介してきた取得方法と比べてより複雑な条件で要素を指定することが出来るようになりました。
ただ注意点としては今までの方法( getElement~By~ )の方法と比べるとパフォーマンス速度が低速になってしまうので使い所を弁えましょう。

下記のコードはリストの要素全てとJavaScript関連の言語、フレームワークなどのみに絞って取得したものです。

sample.html

<ul id="languageList">
    <li><a href="#" class="Javascript">Javascript</a></li>
    <li><a href="#" class="Java">Java</a></li>
    <li><a href="#" class="Ruby">Ruby</a></li>
    <li><a href="#" class="python">python</a></li>
    <li><a href="#" class="Javascript">Vue.js</a></li>
    <li><a href="#" class="Javascript">Typescript</a></li>
    <li><a href="#" class="golang">golang</a></li>
    <li><a href="#" class="Javascript">Angular.js</a></li>
    <li><a href="#" class="Javascript">React.js</a></li>
    <li><a href="#" class="Javascript">JQuery</a></li>
  </ul>
javascript.js

let languageList = document.querySelectorAll('li'); // liタグの要素全取得
let javascriptList = document.querySelectorAll('#languageList .Javascript'); // idがlanguageList 且つ class名がjavascript の要素を全取得
// languageList,javascriptListも NodeListオブジェクト

for (let i = 0; i< languageList.length; i++){ 
  console.log(languageList.item(i).textContent); 
  /** Javascript,Java,Ruby,python,Vue.js,Typescript,golang,Angular.js,React.js,Jquery*/
}

for (let i = 0; i< javascriptList.length; i++){ 
  console.log(javascriptList.item(i).textContent); 
  /** Javascript,Vue.js,Typescript,Angular.js,React.js,Jquery*/
}

6. ノードウォーキング

要素を取得する際に度々、文書全体から要素を探すのはパフォーマンスの低下に繋がってしまうので、ある起点の要素を取得した際に、その相対関係を指定する事によって期待の要素を取得することができます。

位置関係を示すノード一覧
・起点ノード : currentNode
・親ノード : parentNode
・兄ノード : previousSibiling
・弟ノード : nextSibiling
・全子ノード : childNodes
・最初の子ノード : firstChild
・最後の子ノード : lastChild

sample.html
<form>
    <label for="food">一番好きな食べ物は?</label>
    <select name="food" id="food">
      <option value="ラーメン">ラーメン</option>
      <option value="餃子">餃子</option>
      <option value="焼肉">焼肉</option>
    </select>
    <input type="submit" value="送信">
  </form>
javascript.js
let food = document.getElementById('food'); // selectを取得
let opts = food.childNodes; // foodの子要素を取得
console.log(opts); // NodeList(7) [text, option, text, option, text, option, text]

for(let i = 0; i<opts.length; i++){
  let opt = opts.item(i);
  if(opt.nodeType === 1){ 
    // 子ノードが要素ノードの時のみ、値を出力
    console.log(opt.value); // => ラーメン、餃子、焼肉
  }else{
    // TEXT_NODEの時
    console.log(opt); // => #text
  }
}

id属性foodを持つselectタグを取得し、childNodesを使用して子要素を全て取得します。注意点がこの子要素の中にはvalue値以外の要素が入っているため、nodeType === 1の場合のみ、取得するものです。nodeTypeが1のものとは要素ノードを指します。

javascript.js

/**
 * firstElementChild : 子要素で子要素の中の兄要素
 * nextElementSibling : 弟要素
 * 要素オブジェクトしか取得しないのでnodeTypeを気にする必要がなくて済む
 */
let childOpts = food.firstElementChild; //最初の子要素を取得
while(childOpts){
  // 要素が存在する間、ずっとループする
  console.log(childOpts.value);// => ラーメン、餃子、焼肉
  childOpts = childOpts.nextElementSibling; // 弟要素をchildOpts自身に代入、最後の要素に弟要素はないのでループが終わる
}

let lastChildOpts = food.lastElementChild; //最後の子要素を取得
while(lastChildOpts){
  // 要素が存在する間、ずっとループする
  console.log(lastChildOpts.value);// => 焼肉、餃子、ラーメン => 逆順
  lastChildOpts = lastChildOpts.previousElementSibling; // 兄要素をlastChildOpts自身に代入、最後の要素には兄要素がないのでループが終わる
}

7. getAttribute, setAttribute

属性にアクセスできます。

【使用方法】
・getAttribute:要素.getAttribure(属性)
・setAttribute:要素.setAttribute(属性,値)

sample.html
  <p id="beforechange"></p>
  <input type="submit" value="送信" id="btn">

  <style>
    #beforechange{
      color: red;
    }
    #afterchange{
      color:blue;
    }
  </style>
javascript.js
let btn = document.getElementById('btn');
let word = document.getElementById('beforechange');

btn.addEventListener('click',function(){      
  word.setAttribute('id','afterchange');// id属性に'afterchange'をセット
  word.innerHTML='';
},false);

8. attributes

全ての属性情報が取得できます。
HTMLCollectionに似て個別のノードに名前、もしくはindexでアクセスすることができます。

sample.html
<img src="スクリーンショット 2020-06-05 14.52.32.png" 
  alt="デスクトップ" height="67" width="215" id="picture">
javadscript.js
  let pic = document.getElementById('picture');
  let attrs = pic.attributes; // 属性とその値を全て取得

  console.log(attrs["id"]); // 名前でアクセス => id="picture"
  for(let i = 0; i<attrs.length; i++){
    let attr = attrs.item(i); // index でアクセス
    console.log(attr.name + ' : '+ attr.value)
    /**
     * src : スクリーンショット 2020-06-05 14.52.32.png
     * alt : デスクトップ
     * height : 67
     * width : 215
     * id : picture
     */
  }
})
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0