DOMおれおれAdvent Calendar 2015 – 07日目

2015-12-07

jQueryだと属性の操作はほとんど attr() で済むんですが、DOMは色々setとgetと分かれてます。あと名前が長いです。

// el = <a href="#top">TOP</a>

console.log(el.getAttribute('href'));  // => "#top"

el.setAttribute('href', '#top-of-the-world');
console.log(el.getAttribute('href'));  // => "#top-of-the-world"

属性値がないもの

は属性名と同じになります。

// el = `<input type="checkbox" checked />`

console.log(el.getAttribute('checked'));  // => "checked"

削除

el.setAttribute('foo', undefined) とかしても foo="undefined" とそのまま設定されるだけで、空文字列を設定 el.setAttribute('foo', '') してもやっぱり foo="" とそのまま設定されます。いやこれはjQueryでも同じなんだけど。

削除したい場合は削除用のAPIを用います。jQueryの removeAttr() に相当します。

// el = <a href="#top" target="_blank">TOP</a>

el.removeAttribute('target');

有無の確認

これはjQueryにはない機能だ。

if (el.hasAttribute('target')) {
  el.setAttribute('target', '_blank');
}

まあ getAttribute() は属性がなければ null を返す(jQueryだと undefined )ので、それで判断するんでも十分だけど。ちなみに昔の仕様だと、 getAttribute() は属性がない場合に空文字列を返すと定められていたそうだ。

まとめて

attributes という配列風プロパティがありまして、 length で個数が取れたり [i] でアクセスできたりしつつ、直接名前 [key] でもアクセスできるという便利なやつです。NamedNodeMapのインスタンスです。

とはいえそんなに使う事もないと思うんだよなー。

attributes の子はまたオブジェクトになってます。 namevalue を持っているので、具体的な属性の名前と値はこれでアクセスします。この子オブジェクトはAttrのインスタンスだそうです。(なんでこれだけAttributeじゃなくて省略形なんだ!)

// el = <textarea name="comment" cols="30" rows="10"></textarea>

var attrs = el.attributes;
for (var i=0; i<attrs.length; i++) {
  var attr = attrs[i];
  console.log(attr.name, ':', attr.value);
}
// =>
// rows : 10
// cols : 30
// name : comment

【重要】属性とプロパティは別物

今回扱ったのはHTMLの属性なんだけども、通常JavaScriptから操作する対象は属性ではなくプロパティになります。 例えばチェックボックスにチェックが付いているかどうかを判断するのに getAttribute() は使えません。

// el = <input type="checkbox" checked />

// checked属性の値を確認
console.log(el.getAttribute('checked'));  // => "checked"

// checkedプロパティの値を変更
// (チェックを外す。)
el.checked = false;

// checked属性の値を再確認
console.log(el.getAttribute('checked'));  // => "checked"

というわけで、プロパティを使ってください。詳しくは過去に書いた記事をどうぞ。

属性を操作する場面ってほとんどないんじゃないかなあ。

参考