LoginSignup
259

More than 5 years have passed since last update.

非jQuery環境ではどう書んだっけ?チートシート

Last updated at Posted at 2016-03-04

※追記
コメントでこの記事よりも断然質の良い記事を教えてもらいました。
@kabochaさんありがとうございます。

You Don't Need jQuery
https://github.com/oneuijs/You-Dont-Need-jQuery

追記の追記。
日本語訳のお手伝いをさせていただきました。

github
https://github.com/oneuijs/You-Dont-Need-jQuery/blob/master/README-ja.md

[Qiita]もうjQueryは必要ない
http://qiita.com/tatesuke/items/b9548dd484b01b139b74

jQueryが使える環境でコーディングした後、jQueryが使えない環境でコーディングしようとすると、「どう書くんだっけ?」となることが多いです。ということで分かる範囲でチートシートを作りました。

当然ですが、サンプルコードは「似たような動作をする」「代替になりうる」という意味なので厳密に同じではありません。

また、JavaScriptやECMAScriptの仕様を意識していないため、古い書き方や新しい書き方など混在していると思います。

Selectors

エレメントを選択

伝統的なやり方ならば

// idで取得
var elem = document.getElementById("id");

// クラス名で取得
elem = document.getElementsByClassName("className");

// タグ名で取得
elem = document.getElementsByTagName("div");

最近のブラウザならquerySelectorAll/querySelectorのほうが便利。jqueryのセレクタを流用できる。

// セレクタに合致するエレメントを取得
var elem = document.querySelectorAll("#id");

// セレクタに合致する最初のエレメントを取得
elem = document.querySelector(".query");

ただし、jQueryのオブジェクトじゃないのでeach関数は使えない。自作するか、素直にfor文で回す。

Attributes

attr/removeAttr

// 属性を設定
element.setAttribute("name", "value");

// 属性を取得
var attr = element.getAttribute("name");

// 属性を削除
element.removeAttribute();

// 属性が存在するか
var hasAttr = element.hasAttribute("name");

addClass/removeClass/toggleClass

// クラスを追加
element.classList.add("className");

// クラスを切り替え
element.classList.toggle("className");

// クラスを削除
element.classList.remove("className");

// クラスが存在するか
var contains = element.classList.contains("className");

一応className属性で文字列を取得することも可能

var classNames = element.className;

html

// htmlを取得
var html = element.innerHTML;

// htmlを設定
element.innerHTML = html;

text

// テキストを取得
var text = element.innerText;

// テキストを設定
element.innerText = text;

firefoxではinnerTextが使えないのでtextContentを使う。

var text = element.textContent;

当然、ブラウザによって処理を振り分けるのは面倒なので次のようにするとよい。

引用元:『TM Life』 Firefox で innerText を使えるようにする方法
http://tmlife.net/programming/javascript/firefox-can-use-innertext.html

(function(){
    var temp = document.createElement("div");
    if (temp.innerText == undefined) {
        Object.defineProperty(HTMLElement.prototype, "innerText", {
            get: function()  { return this.textContent },
            set: function(v) { this.textContent = v; }
        });
    }
})();

val

// valueを取得
var val = element.value;

// valueを設定
element.value = val;

Traversing

hasClass

var hasClass = element.classList.contains(className);

children

var chldren = element.children;

こちらもjQueryオブジェクトではないのでeach関数は使えない。

closest

// 親エレメントを取得
var closet = element.parentNode;

セレクタがある場合はゴリゴリ書くしかない。
たとえば、タグ名を指定したければwhile文で遡る。

var parent = element.parentNode;
while (parent.tagName != "BODY") {
    parent = parent.parentNode;
}

find

エレメント自体にもquerySelectorAll/querySelectorがあるので、それで代用可能。

// findの代用
var elements = element.querySelectorAll(query);

next

// 次の要素を得る
var next = element.nextElementSibling;

nextAll

var nexts = [];
var current = element.nextElementSibling;
while (current != null) {
    nexts.push(current);
    current = current.nextElementSibling;
}

parent

// 親エレメントを取得
var parent = element.parentNode;

parents

element.parentNodewhile文、if文を組み合わせてゴリゴリ書く。

prev

// 前の要素を得る
var prev = element.previousElementSibling;

prevAll

var prevs = [];
var current= element.parentNode.firstElementChild;
while (current != element) {
    prevs.push(current);
    current = current.nextElementSibling;
}

siblings

var siblings = [];
var children = element.parentNode.children;
for (var i = 0; i < children.length; i++) {
    if (children[i] != element) {
        siblings.push(children[i]);
    }
}

Manipulation

エレメント作成

エレメント作成の基本はdocument.createElement

var newElement = document.createElement("div");

createElementではjQueryのよう文字列からエレメントを簡単に作成することはできない。
その場合、以下のように、ダミーのエレメントを使うことで実現可能。

// ダミーのdiv作成
var dummy = document.createElement("div");
// ダミーのinnerHTMLを書き換える
dummy.innerHTML = "<div>hoge</div>";
// 作成したエレメントを取り出す。
var newElement = dummy.childNodes[0];
delete dummy;

append

parent.appendChild(element);

prepend

parent.insertBefore(element, parent.childNodes[0]);

after

var parent = element.parentNode;
var prev = element.nextSibling;
parent.insertBefore(insertElement, prev);

before

var parent = element.parentNode;
parent.insertBefore(insertElement, element);

insertAfter

$(A).insertAfter(B)

var parent = B.parentNode;
var prev = B.nextSibling;
parent.insertBefore(A, prev);

insertBefore

$(A).insertBefore(B)

var parent = B.parentNode;
parent.insertBefore(A, B);

wrap

$(A).wrap(B);

var next = A.nextSibling;
var parent = A.parentNode;
parent.removeChild(A);
parent.insertBefore(B, next);
B.appendChild(A);

empty

element.innerHTML = "";

remove

element.parentNode.removeChild(element);

clone

element.cloneNode(true);

CSS

css

element.style配下のプロパティをいじる。

element.style.border = "1px solid gray";

どんなプロパティがあるかはその都度調べる。たとえば↓とか。
http://javascriptist.net/docs/samples_element_style.html

offset/position

簡単に代替になるものがない(多分)。
一応、下記を使うと、起点となる要素からの相対距離が得られる。

var offsetTop = element.offsetTop;
var offsetLeft = element.offsetLeft;

起点となるエレメントに要注意。必ずしも画面の左上が起点ではない。親要素がposition:relativeなら親要素が起点になる。

画面左上を起点としたいならDOM構造に注意して、各要素のoffsetTopやoffsetLeftを足し合わせるという作業が必要になることがある。

scrollTop, scrollLeft

// スクロール量を得る
var scrollTop = element.scrollTop;
var scrollLeft = element.scrollLeft;

// スクロール量を設定
element.scrollTop = scrollTop;
element.scrollLeft = scrollLeft;

width/height

// 横幅、縦幅を得る(padding,border含む)
var width = element.offsetWidth;
var height = element.offsetHeight;

// 横幅、縦幅を設定する
// 普通はpadding, borderを含まない box-sizing:border-boxならpadding, bordeerを含む。
element.style.width = "100px";
element.style.heigth = "100px";

offsetWidthoffsetHeightはReadOnlyです。

Events

on, off(イベント)

addEventListener/removeEventListener一択(attachEvent?何それ?)。

element.addEventListener("eventName", callback);
element.removeEventListener("eventName", callback);

jQuery.on(element, "eventName", callback)のように、将来的に追加されるエレメントにも対応させる方法は調べてません。

ready

単純なところではwindow.onload

window.onload = function() {
    // コード
}

これだとひとつしかイベントを登録できないし、''$(document).ready''とも厳密にはタイミングが違う。

最近のブラウザでは以下のほうが無難かも。

document.addEventListener('DOMContentLoaded', function() {
  console.log('DOMContentLoaded');
});

trigger

  1. イベントオブジェクトの生成
  2. イベントオブジェクトを初期化
  3. イベントをディスパッチ

の流れ。

// クリックイベントを発生させる

// イベント作成
var event = document.createEvent("MouseEvent");

// イベントオブジェクトを初期化
event.initMouseEvent("click",true,true,window,0,0,0,0,0,false,false,false,false,0,null);

// イベントをディスパッチ
targetElement.dispatchEvent(event);

MouseEvent以外にもKeyboardEventとか色々あってブラウザごとにバリエーションは違うらしい。Mozillaだと↓にいっぱい載ってる。

クリックイベントとかを自前で発火させることはあまりないとは思うけど・・・

カスタムイベントを発火させるには

var event= document.createEvent("Event");
event.initEvent("eventName",false,false);
targetElement.dispatchEvent(event);

各引数の意味とかはこの辺が詳しい↓

Effects

show/hide/toggle

display:noneするcssクラスを準備しておいて、styleListを通してクラスをつけたり外したりするのが一番楽。

.hide{
    display:none !important;
}
// 非表示にする
element.classList.remove("hide");

// 表示する
element.classList.add("hide");

// toggle
element.classList.toggle("hide");

もちろん、

// 直接styleをいじって非表示にする
element.style.display = "none";

として非表示にすることも可能。しかし、どうやって表示するか決めかねる。

// 表示するとき
// displayはblockか?inlineか?はたまたinline-blockか?それ以外?
element.style.display = "??";

jQueryはこのあたりをhide前にキャッシュしたり、見えないiframeにエレメントを追加したりしてうまいこと実装しているようだけど、ゼロから実装しなおすのは面倒くさい。可能なら上の例のようにcssのクラスを準備しておくのが一番手っ取り早い。

ajax

詳しくない&Web上にたくさん情報があるので割愛。
気が向いたら書くかも。

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
259