[脱jQuery] 第一回 - 基礎
TL;DR
- 素の JavaScript だけで書くことを以後ピュア JS と呼称するのでよろしく。
- 口語で書くけど許してね。
- 今回は脱 jQuery したいからピュア JS でどうやって書くのか教えて欲しい、って依頼があったので書くよ。
- 記念すべき第一回目はセレクタとイベントの基本について書いてくよ。
- そんなん知っとるわいって人はブラウザバックどうぞ。
- ちなみに
TL;DR
ってなんぞや?って思った人は下記を参照してね。
それでは本題
の前に本記事では .prettierrc
に以下の設定をしているよ。
{
"printWidth": 120,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "none",
"semi": true
}
ちなみに JavaScript は行末に;
なくても動くけどぼくは書く派。
だって minify したらどうせよしなにしてくれるからね。
.prettierrc
で "semi": true
にして勝手につけてもらえば手間なんてないし。
賛否両論あるだろうしここで正否を語るのは趣旨とは違うから次へ行くよ。
基本編
セレクタについて
本解説では DOM のロードを待つための
$(function () {
// コード
});
といった js の実行タイミングのお話は割愛するよ。
[jQuery]
jQuery を使うとき DOM の指定に css セレクタ使うよね?
雑に書くとこんな感じ。
$('.sample-cls').on('click', function () {
const text = $(this).text();
console.log(text);
});
これでクラス.sample-cls
がついているエレメントをクリックするとコンソールログに 押してみ?
って文字が出る、というだけの本当にしょうもないロジック。
条件を満たすための html はこんな感じ。
<span id="sample-id" class="sample-cls" name="sample-name">押してみ?</span>
[ピュア JS]
ES6 以前
参考までに昔の書き方だよ
getElementsByClassName
を使った例
document.getElementsByClassName('sample-cls')[0].addEventListener(
'click',
function (e) {
const text = e.target.innerText;
console.log(text);
},
false
);
document
は <html>~</html>
だと思っておけばだいたいそんな感じ。
document.toString()
すると HTMLDocument
というオブジェクトだとわかる。
で、この getElementsByClassName
なんだけどこれ getElements
とあることからもわかるようにリストが返ってくるんだよね。
document.getElementsByClassName('sample-cls').toString()
としてみると HTMLCollection
なるクラスが返ってくる。
これはリストなのでループして全要素に addEventListener
するか、単純に [0]
として一番最初の要素を取ってやると単一のエレメントが取れる。
類似するメソッドに
-
getElementById
- ここでいうsample-id
-
getElementsByName
- ここでいうsample-name
-
getElementsByTagName
- ここでいうspan
などがあるよ。他にもあるけど面倒なので割愛するね。
この中で唯一、getElementById
だけは最初から単一のエレメントが返ってくるよ。
id はユニークである、という前提のメソッドだからね。
他は複数形であることからもわかるように HTMLCollection
が返ってくるから注意だね。
ちなみに html 的に同一の id を複数使ってしまうと最初に見つかった要素だけ取れるので id 被りで変にハマらないようにね。
さて、先程の例を見て分かる通り、id、クラス、タグ、name それぞれ違うメソッドで探索しなきゃいけないことや返ってくるオブジェクトが異なることがあって
これらがピュア JS が嫌煙されて jQuery が流行った原因の一端ではあるけれど、時代は変わって ES6 辺りから新たなメソッドが誕生して css セレクタ名でのエレメント指定ができるようになったんだよね。
ES6(ES2015)以降
最近のブラウザならほぼ対応しているというか大体対応していないブラウザは根絶されているから気にせず使っていこう。
document.querySelector('.sample-cls').addEventListener(
'click',
function (e) {
const text = e.target.innerText;
console.log(text);
},
false
);
一見同じように見えるけど違いは css のセレクタ方式で選択できるようになったところだね。
ちなみに querySelector
は最初にヒットしたエレメントを一個だけ取ってくるから全部欲しい!ってときはquerySelectorAll
を使う必要があるよ。
ただし jQuery とは違って querySelectorAll
もあくまでリストを返すのでイベントを設定するならループする必要があるよ。
addEventListener
には 3 つの引数が設定できるけど小難しい話になってくるから詳しくは適に調べてね。
一番の違いはこの querySelector
には id なら#sample-id
とすればいいし name なら[name="sample-name"]
とタグ名ならそのまんま span
と書けるよ。
もっというと css や jQuery のセレクタ指定と同じように書けるから #sample-id.sample-cls[name="sample-name"]
とかでもヒットさせられるから getElement 系メソッドより遥かに扱いやすくなっているよ。
とまぁ長くなったけどここまでがエレメント指定の基本だよ。
ちなみに addEventListener
を使わず onclick
を使う方法もあるよ。
document.querySelector('.sample-cls').onclick = function (e) {
const text = e.target.innerText;
console.log(text);
};
イベントを一つしか登録できないという制約が出てくるからあまりおすすめはできないよ。
ちなみに html 属性の onclick の中に書くのとほぼ一緒だね。
イベント解除したかったら addEventListener
は対になる removeEventListener
を使う必要があるよ。
まとめ
応用編に行こうかと思ったけど疲れたので今回はここまでにしておくよ。
ピュア JS の基本である addEventListener
などのメソッドは変わらずだけどエレメントを選択するメソッドが
querySelector
querySelectorAll
となって $()
と同様の記述ができるようになったことが大きな点かな。
ちなみに jQuery の
$
この$って特別な識別子とかじゃなくて単なる変数なんだよね。
window.$ = jQuery
ってだけで jQuery っていう function の alias なんだよね。
v3 や v2 辺りはソース見てないからわからないけど v1 くらいまでは多分、
var jQuery = function () {};
jQuery.prototype.ajax = function () {};
とかやって prototype 継承でメソッド継ぎ足していってクロスブラウザ対応や便利メソッドを生やしまくったのが jQuery である。
昔は
class Hoge {}
とかもなかったからね。
全部 function(){}.prototype でゴリ押し。
機会があったら arrow-function と通常の function の this の違いやらを説明していきたいと思うけど。
とても疲れたのでまた今度。
執筆って大変だね。
Discussion