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') // 変数、定数への格納ももちろん可能
クラス指定
<div class="hoge-class">
<!-- something -->
</div>
$('.hoge-class') // 画面内の「hoge-class」を全取得
id指定
<div id="hogeId">
<!-- something -->
</div>
$('#hogeId')
タグ種別指定
<div>
<!-- something -->
</div>
$('div') // 「div」タグを全取得
属性の条件判定
例 : name属性が**「hoge-name」**のタグを取得する
<div name="hoge-name">
<!-- something -->
</div>
$('[name="hoge-name"]') // 「name」属性が「hoge-name」の要素を全て取得
例 : inputタグかつtypeがcheckbox(よく見かけるパターン)
<input type="checkbox" value="hogeCheckBox" />
// よく見かける例だとこうだが…
$('input[type=checkbox]')
// 実はこれだけでも上記とほとんど同様の結果が得られる。最初にある「input」はinputタグを表しているので、この場合は無くても問題はなく、typeに対する条件判定だけで事足りる
$('[type=checkbox]')
カスタムタグだろうが条件判定に利用可能
<div data-custom-hoge="true">
<!-- something -->
</div>
$('[data-custom-hoge="true"]') // 「data-custom-hoge」属性が「true」の要素を全て取得
[属性名=値]
で条件指定となる
完全一致だけでなく、(ここでは割愛するが)後方一致や前方一致での指定も可能
DOMの属性(nameやidも始め、『data』から始まるカスタムデータ属性に至っても)については[]
で囲めば(ほぼ)どんな属性でも、条件検索が出来ると考えて貰って差支え無い
『●●内の▲▲』を取得(入れ子要素の取得)
例 : 「hoge-class」内の『button要素全て』を取得
<div class="hoge-class">
<button>送信</button>
</div>
<!-- 直下の子要素でなくてもok -->
<div class="hoge-class">
<div>
<button>決定</button>
</div>
</div>
$('.hoge-class button') // 『半角スペース区切り』で親子関係を表現
『●●かつ▲▲』であるタグの取得(複数条件指定)
例 : 「hoge-class」が付与されているbuttonタグを取得
<button class="hoge-class">ほげほげ</button>
$('button.hoge-class') // 複数のセレクタを区切り無く記述
若干紛らわしいですが、半角スペースで区切ると親子関係の表現になってしまうので注意
$('button .hoge-class') // NG。これだとdivタグ内のhoge-classクラスという指定になってしまう
DOMの操作
- 値のセットから、クラスの指定等
値のセット(value)
val関数
<input id="hogeText" type="text" />
$('#hogeText').val('ほげほげ') // 引数を与えればsetter化
const inputValue = $('#hogeText').val() // 引数が無ければgetter化
クラスの付与、削除、判定
addClass関数
removeClass関数
toggleClass関数
hasClass関数
<div class="hoge-class">
</div>
$('.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関数
<button id="hogeButton">ほげほげ</button>
$('#hogeButton').text('ふがふが') // 引数を与えればsetter化
const buttonText = $('#hogeButton').text() // 引数を与えなければgetter化
<h1>h1 hoge</h1>
$('h1').text('h1 fuga') // innerTextが存在するタグならbuttonタグ以外も(もちろん)指定が可能
その他属性値の変更、取得
attr関数
<div id="hogeId" name="hogeName">
</div>
const name = $('#hogeId').attr('name') // name属性の値取得
$('#hogeId').attr('name', 'fugaName') // 属性に対する値の再設定も
wai-aria等の特殊な属性も自由に設定可能
<div id="hogeId" aria-hidden="true">
</div>
const hidden = $('#hogeId').attr('aria-hidden') // 第二引数を与えなければgetter化
$('#hogeId').attr('aria-hidden', false) // 第二引数を与えればsetter化
checked、selected属性には、prop関数で存在の可否を真偽値で設定、及び取得
※attr関数との違いについては、先達様のわかりやすい記事がありますので詳しくはそちらで・・・手抜き
<select id="hogeSelectBox">
<option>foo</option>
<option selected>bar</option>
<option>fooBar</option>
</select>
$('#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イベントを定義する
<div class="fuga-class">
<button>fuga</button>
<button>fugafuga</button>
</div>
$('.fuga-class button')
.on('click', function() {
/** 押されたボタンのテキストをログ出力する **/
const button = $(this) // $(this)で、押された自分自身(jQueryオブジェクト)を取得
console.log(`押されたのは${button.text()}ボタン`) // ※es6以降のテンプレートリテラル表記
})
削除
off関数
例 : fuga-class以下のbuttonタグに指定されたonClickイベントを削除する
<div class="fuga-class">
<button>fuga</button>
<button>fugafuga</button>
</div>
$('.fuga-class button').off('click')
$('.fuga-class button')
.off('click') // off関数、on関数共に自分自身(jQueryオブジェクト)を返却するため、メソッドチェーンでイベントの定義しなおしも可能
.on('click', function() {
// do something
})
応用
例 : クリックされた自分と同階層に存在するチェックボックスのチェック状態を取得する
<div class="hoge-class">
<button>hoge</button>
<input type="checkbox"/>
</div>
$('.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関数
<button class="hoge-button">ほげ</button>
<button class="hoge-button">ほげほげ</button>
// hoge-button全てを非表示にする
$('.hoge-button').hide()
show関数
<button class="fuga-button">ふが</button>
<button class="fuga-button">ふがふが</button>
// fuga-button全てを表示する
$('.fuga-button').show()
例によってメソッドチェーンも可
$('.hoge-class').hide().show() // この動作はどう考えても無意味だケド・・・
以上
書いてみて
- 使ってみたらやっぱり便利だなぁと思うjQuery
- しかし、システムの規模が大きくなればなるほど、ステートフルにDOMを扱いたくなってくるので、コンポーネント指向である昨今のjsフレームワークで書きたくなっていきます。
- 動的に変化する『状態を全く持たない』(←ココ重要)アプリだったり、非常に規模の小さいモックアップの様なプロダクトをスピーディに作りたい場合には、jQueryという選択肢もまだまだ有りかもしれません。