🙌

[脱jQuery] 第一回 - 基礎

2023/02/15に公開

TL;DR

  • 素の JavaScript だけで書くことを以後ピュア JS と呼称するのでよろしく。
  • 口語で書くけど許してね。
  • 今回は脱 jQuery したいからピュア JS でどうやって書くのか教えて欲しい、って依頼があったので書くよ。
  • 記念すべき第一回目はセレクタとイベントの基本について書いてくよ。
    • そんなん知っとるわいって人はブラウザバックどうぞ。
  • ちなみにTL;DR ってなんぞや?って思った人は下記を参照してね。

https://e-words.jp/w/TL-DR.html

それでは本題

の前に本記事では .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