Programming Field

DOMで要素の属性を取得・設定・削除する

このページでは、DOMの要素における属性(attribute)の設定方法を紹介します。

[関連キーワード: getAttributesetAttributeremoveAttributegetAttributeNodesetAttributeNoderemoveAttributeNodeattributes]

属性

DOMでは、要素(Element)だけが「属性」を持つことが出来ます。Elementの継承元であるNodeattributesプロパティが定義されていますが、Element以外ではnullとなります。

attributesの中身は読み書き可能な名前付きリスト(NamedNodeMap)となっているため、属性を操作するにはこれ1つでも問題はありませんが、Elementに定義されている各種メソッドを使用して属性を操作することもできます。

属性の取得

まずは簡単な属性の取得方法です。以下のコードはいずれも同じ結果(val1 == val2 == val3)を得ることができます。

[JavaScript]

var val1 = element.attributes.getNamedItem("attr1");
var val2 = element.getAttribute("attr1");
var attrNode = element.getAttributeNode("attr1");
var val3 = attrNode ? attrNode.nodeValue : null;

また、attributesはインデックスによる参照も可能(配列と同じ)なので、以下のように書くこともできます。(結果: val4 == val1)

[JavaScript]

var val4 = null;
for (var i = 0; i < element.attributes.length; i++) {
    var attrNode = element.attributes[i];
    if (attrNode.nodeName == "attr1") {
        val4 = attrNode.nodeValue;
        break;
    }
}

Attrにはnamevalueプロパティが定義されており、それぞれnodeNamenodeValueと同値です。

さらに、Attrは子ノードとしてTextを持つことができ、それを参照することで属性の値を取得することもできます。なお、子ノードが複数ある場合、nodeValueはそれらを連結した値になります。(結果: val5 == val1)

[JavaScript]

var attrNode = element.getAttributeNode("attr1");
var val5;
if (attrNode) {
    val5 = "";
    for (var i = 0; i < attrNode.childNodes.length; i++)
        val5 += attrNode.childNodes[i].nodeValue;
}
else
    val5 = null;

なお、属性によっては「既定値」が存在する場合があり、既定値が存在する属性はユーザー自身が属性を指定していない場合でも(あたかも既定値が指定されているかのように)attributesのリストに現れます。この「既定値が使用されている」かどうかを判定するには、Attrspecifiedプロパティを使います。

[JavaScript]

var attrNode = element.getAttributeNode("attr1");
if (!attrNode || !attrNode.specified) {
    // ユーザーは属性'attr1'を指定していない
}
else {
    // ユーザーは属性'attr1'を指定している
}

※ 既定値が存在せずユーザーもその属性を指定していない場合、その属性はリストに現れず、その属性名が渡されたgetAttributeNodeメソッドはnullを返します。
specifiedの挙動はブラウザによって多少異なる模様です。

属性の値を(XMLやHTMLを記述する際に)指定する時、文字列の一部に実体参照(EntityReference)を含むことができます。この場合、nodeValueには展開された値が入りますが、Attrの子ノード(childNodesリスト)にはEntityReferenceのインスタンスが入ります。

EntityReferenceがリストに現れる機能はブラウザ上ではMSXMLでしか機能しない模様です。

属性の設定

要素にある属性の値を設定する単純な方法として、ElementsetAttributeメソッドを使う方法があります。

[JavaScript]

element.setAttribute("attr1", "newValue");

Attrインターフェイスを介して設定する場合は、DocumentインターフェイスのcreateAttributeメソッドを使い、必要な値を設定したのち、そのインスタンスをElementsetAttributeNodeメソッドに渡します。

[JavaScript]

var attrNode = document.createAttribute("attr1");
attrNode.nodeValue = "newValue";
element.setAttributeNode(attrNode);

setAttributeNodeで指定するAttrのインスタンスは、その要素が所属するDocumentで作成されたものでなければなりません。(上記のelementは、documentの子ノードになっているか、そのdocumentのcreateElementで作成されたものである必要があります。)

一方、attributesを使って以下のように書くこともできます。

[JavaScript]

var attrNode = document.createAttribute("attr1");
attrNode.nodeValue = "newValue";
element.attributes.setNamedItem(attrNode);

さらに、以下のようにTextノードを作成して子ノードして追加する方法もあります。

[JavaScript]

var attrNode = document.createAttribute("attr1");
var textNode = document.createTextNode("newValue");
attrNode.appendChild(textNode);
element.setAttributeNode(attrNode);

※ この方法はブラウザ間で挙動が異なり、実行できないブラウザ(Firefoxなど)もあります。

属性の削除

属性の値をクリアする場合、空の文字列("")を設定してもクリアされていない場合があります。その場合、ElementremoveAttributeremoveAttributeNodeを使います。なお、属性の値を既定値に戻したい場合もこの方法を取ってください。

[JavaScript]

element.removeAttribute("attr1");
[JavaScript]

var attrNode = element.getAttributeNode("attr1");
element.removeAttributeNode(attrNode);

removeAttributeNodeの引数として指定したAttrインスタンスは直ちに無効にならないため、再び同じ要素や別の要素のsetAttributeNodeメソッドに渡すことができます。