LoginSignup
5
2

More than 5 years have passed since last update.

DOMを拡張してみる

Last updated at Posted at 2016-12-10

この記事はJ2complexed Advent Calendar 2016の10日目です。

DOMをprototypeで拡張してみよう

ArrayやObjectをprototypeで拡張してしまうとfor inループで意図しないメソッドが挙がってしまいました。(人これを、プロトタイプ汚染という)
参考:プロトタイプ汚染とループ

ですが、DOMのprototypeを精査するようなことはまずないので、DOMだけはprototypeで拡張してしまいましょう。1
なお、ここではES5の記述でいきます。ES2015でもそのまま使えます。

addClass,removeClassを実装

jQueryで頻出するメソッドです。

addClass

Element.prototype.addClass = function(classname) {
  if(classname == null || classname typeof classname !== "string") return this;
  var parse = classname.split(" "),
      len = parse.length;
  for(len;len--;) {
    this.classList.add(parse[len]);
  }
  return this;
};

var el = document.querySelector("#identify"); // <div id="identify"></div>
el.addClass("hoge"); // <div id="identify" class="hoge"></div>

removeClass

Element.prototype.removeClass = function(classname) {
  if(classname == null || classname typeof classname !== "string") return this;
  var parse = classname.split(" "),
      len = parse.length;
  for(len;len--;) {
    this.classList.remove(parse[len]);
  }
  return this;
};

var el = document.querySelector(".hoge"); // <div class="hoge foo bar"></div>
el.removeClass("foo"); // <div class="hoge bar"></div>

同じ要領でhasClassも作れます。
Elementに対してaddClass,hassClassはぶっちゃけコードにもあるようにclassListを使えば済みます。
ですが、NodeListやHTMLCollectionそのものにclassListはないのでループさせる必要があります。なのでNodeListにaddClass,removeClassを拡張してしまうのが便利です。

NodeListにaddClass,removeClassを実装

※Elementが拡張されてる前提のコードです。

addClass

NodeList.prototype.addClass = function(classname) {
  [].forEach.call(this, function(el) {
    el.addClass(classname);
  });
};

var div = document.querySelectorAll("div"); // [<div></div>, <div></div>];
div.addClass("hoge"); // [<div class="hoge"></div>,<div class="hoge"></div>];

removeClass

NodeList.prototype.addClass = function(classname) {
  [].forEach.call(this, function(el) {
    el.removeClass(classname);
  });
};

var div = document.querySelectorAll(".hoge"); // [<div class="hoge"></div>, <div class="hoge"></div>];
div.addClass("hoge"); // [<div></div>,<div></div>];

  1. ただし将来的に同じ名前のメソッドが実装された場合、それをオーバーライドしてしまうので注意です。 

5
2
0

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
5
2