JavaScript
jQuery

jQuery DOM操作あれこれ

TL;DR

・jQueryでのDOM操作チートシート的な何か

何故書いた

  • webシステム開発の場からは、徐々に姿を消しつつありますが、レガシーなシステム、プロジェクトではまだまだ現役なjQuery。リファクタ等で自分自身や同僚も苦しんだ事があったので、あえて今書いてみました

    • 技術的な制約等で、プロジェクトとしてjQueryを利用せざるを得ない環境に置かれて、開発やリファクタリングに苦しめられている方々の、ほんの僅かにでも、助けになれれば幸いです
  • 最低限、DOMの操作に関して、今より更に未熟だった頃の自分が「これは知れてよかった!」と感じたapiや利用方法のみ、記載しています。不足、認識間違い等あるかもしれませんが、その際は生暖かく見守るかご指摘頂ければと思います

DOMの取得

  • まずはここから 
    • 『$』関数の第1引数セレクタ文字列を指定
    • 取得されるのはjQueryオブジェクト
      • jQueryオブジェクトとは ... かなり雑ですが、一旦DOMそのものと捉えて頂いた上で、残りの内容をご覧頂けるとスムーズかもしれません
      • セレクタ文字列とは ... ざっくり言うとスタイルシート(css)で指定するアレです。.hoge-classとかbodyとかを指定して、スタイル値を書いて行くと思いますが、その指定値と全く同じです。.hoge-classとかbodyがjQueryのDOM指定に欠かせないアレ、すなわちセレクタ文字列にあたります
$('.hoge-class') // jQueryオブジェクトが取得される

const hogeClass = $('.hoge-class') // 変数、定数への格納ももちろん可能

クラス指定

html
<div class="hoge-class">
 <!-- something -->
</div>
javascript
$('.hoge-class') // 画面内の「hoge-class」を全取得

id指定

html
<div id="hogeId">
 <!-- something -->
</div>
javascript
$('#hogeId')

タグ種別指定

html
<div>
 <!-- something -->
</div>
javascript
$('div') // 「div」タグを全取得

属性の条件判定

例 : name属性「hoge-name」のタグを取得する

html
<div name="hoge-name">
 <!-- something -->
</div>
javascript
$('[name="hoge-name"]') // 「name」属性が「hoge-name」の要素を全て取得

例 : inputタグかつtypecheckbox(よく見かけるパターン)

html
<input type="checkbox" value="hogeCheckBox" />
javascript
// よく見かける例だとこうだが…
$('input[type=checkbox]')

// 実はこれだけでも上記とほとんど同様の結果が得られる。最初にある「input」はinputタグを表しているので、この場合は無くても問題はなく、typeに対する条件判定だけで事足りる
$('[type=checkbox]') 

カスタムタグだろうが条件判定に利用可能

html
<div data-custom-hoge="true">
 <!-- something -->
</div>
javascript
$('[data-custom-hoge="true"]') // 「data-custom-hoge」属性が「true」の要素を全て取得

[属性名=値]で条件指定となる
完全一致だけでなく、(ここでは割愛するが)後方一致前方一致での指定も可能
DOMの属性(nameidも始め、『data』から始まるカスタムデータ属性に至っても)については[]で囲めば(ほぼ)どんな属性でも、条件検索が出来ると考えて貰って差支え無い

『●●内の▲▲』を取得(入れ子要素の取得)

例 : 「hoge-class」内の『button要素全て』を取得

html
<div class="hoge-class">
 <button>送信</button>
</div>

<!-- 直下の子要素でなくてもok -->
<div class="hoge-class">
 <div>
  <button>決定</button>
 </div>
</div>
javascript
$('.hoge-class button') // 『半角スペース区切り』で親子関係を表現

『●●かつ▲▲』であるタグの取得(複数条件指定)

例 : 「hoge-class」が付与されているbuttonタグを取得

html
<button class="hoge-class">ほげほげ</button>
javascript
$('button.hoge-class') // 複数のセレクタを区切り無く記述

若干紛らわしいですが、半角スペースで区切ると親子関係の表現になってしまうので注意

NG
$('button .hoge-class') // NG。これだとdivタグ内のhoge-classクラスという指定になってしまう

DOMの操作

  • 値のセットから、クラスの指定等

値のセット(value)

val関数

html
<input id="hogeText" type="text" />
javascript
$('#hogeText').val('ほげほげ') // 引数を与えればsetter化

const inputValue = $('#hogeText').val() // 引数が無ければgetter化

クラスの付与、削除、判定

addClass関数
removeClass関数
toggleClass関数
hasClass関数

html
<div class="hoge-class">
</div>
javascript
$('.hoge-class').addClass('fuga-class') // fuga-classを追加

$('.hoge-class').removeClass('fuga-class') // fuga-classを削除

$('.hoge-class').toggleClass('fuga-class') // fuga-classが付与されていれば削除、付与されていなければ付与

const existsFuga = $('.hoge-class').hasClass('fuga-class') // クラスの有無判定。fuga-classが付与されていればtrue、されていなければfalse

innterTextの取得、変更

text関数

html
<button id="hogeButton">ほげほげ</button>
javascript
$('#hogeButton').text('ふがふが') // 引数を与えればsetter化

const buttonText = $('#hogeButton').text() // 引数を与えなければgetter化

 

html
<h1>h1 hoge</h1>
javascript
$('h1').text('h1 fuga') // innerTextが存在するタグならbuttonタグ以外も(もちろん)指定が可能

その他属性値の変更、取得

attr関数

html
<div id="hogeId" name="hogeName">
</div>
javascript
const name = $('#hogeId').attr('hogeName') // name属性の値取得

$('#hogeId').attr('hogeName', 'fugaName') // 属性に対する値の再設定も

wai-aria等の特殊な属性も自由に設定可能

html
<div id="hogeId" aria-hidden="true">
</div>
javascript
const hidden = $('#hogeId').attr('aria-hidden') // 第二引数を与えなければgetter化

$('#hogeId').attr('aria-hidden', false) // 第二引数を与えればsetter化

checkedselected属性には、prop関数で存在の可否を真偽値で設定、及び取得
※attr関数との違いについては、先達様のわかりやすい記事がありますので詳しくはそちらで・・・手抜き

html
<select id="hogeSelectBox">
 <option>foo</option>
 <option selected>bar</option>
 <option>fooBar</option>
</select>
javascript
$('#hogeSelectBox option') // 条件に合致するoptionタグは複数取得されるため、each関数でぐるぐる回す
  .each(function(index) {
     /** テキストがfooBarのoptionタグを選択済にする **/

     const option = $(this) // 1行分のoptionタグ(jQueryオブジェクト)を取得

     const isFooBar = 'fooBar' === option.text()

     option.prop('selected', isFooBar) // 第二引数を与えればsetter化
     // option.prop('selected')  第二引数を与えなければgetter化
  })

DOMへのイベント定義、削除

  • addEventListenerとほぼ同義
    • jQueryなりに簡潔にイベント定義が出来る

定義

on関数
例 : fuga-class子要素のbuttonタグにonClickイベントを定義する

html
<div class="fuga-class">
 <button>fuga</button>
 <button>fugafuga</button>
</div>
javascript
$('.fuga-class button')
 .on('click', function() {
  /** 押されたボタンのテキストをログ出力する **/

  const button = $(this) // $(this)で、押された自分自身(jQueryオブジェクト)を取得
  console.log(`押されたのは${button.text()}ボタン`) // ※es6以降のテンプレートリテラル表記
 })

削除

off関数
例 : fuga-class以下のbuttonタグに指定されたonClickイベントを削除する

html
<div class="fuga-class">
 <button>fuga</button>
 <button>fugafuga</button>
</div>
javascript
$('.fuga-class button').off('click')

$('.fuga-class button')
 .off('click') // off関数、on関数共に自分自身(jQueryオブジェクト)を返却するため、メソッドチェーンでイベントの定義しなおしも可能
 .on('click', function() {
   // do something
  })

応用

例 : クリックされた自分と同階層に存在するチェックボックスのチェック状態を取得する

html
<div class="hoge-class">
 <button>hoge</button>
 <input type="checkbox"/>
</div>
javascript
$('.hoge-class button')
 .on('click', function() {
  /** クリックされたボタンと同階層にあるDOM要素を取得し、値をログ出力する **/
  const button = $(this)

  const checkbox = button.parents('.hoge-class').find('input[type=checkbox]')

  console.log(checkbox.prop('checked'))
 })

parents関数で自分から見た親要素を取得
find関数で自分に対する子要素を取得
どちらも「$」関数と同様に、セレクタ文字列を引き渡して利用する

$('.fuga-class button')

$('.fuga-class').find('button')

/** 上記はそれぞれ同じ結果が返却される **/

その他便利操作

DOMを隠す、再表示する

hide関数

html
<button class="hoge-button">ほげ</button>
<button class="hoge-button">ほげほげ</button>
javascript
// hoge-button全てを非表示にする
$('.hoge-button').hide()

show関数

html
<button class="fuga-button">ふが</button>
<button class="fuga-button">ふがふが</button>
javascript
// fuga-button全てを表示する
$('.fuga-button').show()

例によってメソッドチェーンも可

javascript
$('.hoge-class').hide().show() // この動作はどう考えても無意味だケド・・・

以上

書いてみて

  • 使ってみたらやっぱり便利だなぁと思うjQuery
    • しかし、システムの規模が大きくなればなるほど、ステートフルにDOMを扱いたくなってくるので、コンポーネント指向である昨今のjsフレームワークで書きたくなっていきます。
    • 動的な要素があまりなかったり、規模の小さいプロダクトをスピーディに作りたい場合には、jQueryという選択肢もまだまだ有りかもしれません。