ElementオブジェクトのAttrオブジェクトについて

javascript

ElementオブジェクトのAttrオブジェクトについて

ElementオブジェクトのAttrについて調べてみます。

ElementオブジェクトはHTML/XMLを内包したオブジェクトです。
Elementオブジェクトは親のインターフェイスの「Node型」、その親インターフェイスである「EventTarget型」のプロパティを継承しています。

そのNode型にはattributesプロパティが定義されています。
このattributesプロパティは要素の属性を表すリスト(配列のようなもの)「NamedNodeMap」を参照します。
このattributesプロパティのNamedNodeMapに対しては数値(インデックス)を使ってアクセス可能です。
また、数値(インデックス)ではなく属性名でもアクセス可能です。

実際にどんな挙動になるのか、試してみました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<div id="test1">
	<input class="form1" id="p1" type="text" name="test1">
</div>

<script type="text/javascript">
// ID「p1」のオブジェクトを取得
let test1 = document.getElementById("p1");

// 取得したオブジェクトのattributesを確認
console.log("test1 -> " + test1.attributes);

// 取得したオブジェクトのattributesの最初の要素を確認
console.log("test2 -> " + test1.attributes[0]);
</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

出力結果は次のようになります。

test1 -> [object NamedNodeMap]
test2 -> [object Attr]

取得したオブジェクトに対してattributesプロパティを調べると、
「NamedNodeMapオブジェクト」を参照していることがわかります。

また、attributesオブジェクトにインデックスを指定すると「Attrオブジェクト」を参照しています。

AttrオブジェクトはNode型の派生です。
Attrオブジェクトはnameプロパティとvalueプロパティがあり、属性の名前と値が格納されています。
試しに、先ほどのHTMLドキュメントに追記して、次のようなHTMLを用意しました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<div id="test1">
	<input class="form1" id="p1" type="text" name="test1">
</div>

<script type="text/javascript">
// ID「p1」のオブジェクトを取得
let test1 = document.getElementById("p1");

// 取得したオブジェクトのattributesを確認
console.log("test1 -> " + test1.attributes);

// 取得したオブジェクトのattributesの最初の要素を確認
console.log("test2 -> " + test1.attributes[0]);

// 取得オブジェクトの最初の要素のname属性とvalue属性を出力
console.log("test3_name -> " + test1.attributes[0].name);
console.log("test3_value -> " + test1.attributes[0].value);

// 取得オブジェクトの2番目の要素のname属性とvalue属性を出力
console.log("test4_name -> " + test1.attributes[1].name);
console.log("test4_value -> " + test1.attributes[1].value);

// 取得オブジェクトの3番目の要素のname属性とvalue属性を出力
console.log("test5_name -> " + test1.attributes[2].name);
console.log("test5_value -> " + test1.attributes[2].value);

// 取得オブジェクトの4番目の要素のname属性とvalue属性を出力
console.log("test6_name -> " + test1.attributes[3].name);
console.log("test6_value -> " + test1.attributes[3].value);
</script>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

このHTMLドキュメントにアクセスすると、ログには次のように出力されます。

test1 -> [object NamedNodeMap]
test2 -> [object Attr]
test3_name -> class
test3_value -> form1
test4_name -> id
test4_value -> p1
test5_name -> type
test5_value -> text
test6_name -> name
test6_value -> test1

test3以降、ドキュメント内の

<input class="form1" id="p1" type="text" name="test1">

に対しての、
属性の名前と値を順に取得できていることがわかります。

では、さらにHTMLに追記して、下記のような記述を試してみます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<div id="test1">
	<input class="form1" id="p1" type="text" name="test1">
</div>

<script type="text/javascript">
// ID「p1」のオブジェクトを取得
let test1 = document.getElementById("p1");

// 取得したオブジェクトのattributesを確認
console.log("test1 -> " + test1.attributes);

// 取得したオブジェクトのattributesの最初の要素を確認
console.log("test2 -> " + test1.attributes[0]);

// 取得オブジェクトの最初の要素のname属性とvalue属性を出力
console.log("test3_name -> " + test1.attributes[0].name);
console.log("test3_value -> " + test1.attributes[0].value);

// 取得オブジェクトの2番目の要素のname属性とvalue属性を出力
console.log("test4_name -> " + test1.attributes[1].name);
console.log("test4_value -> " + test1.attributes[1].value);

// 取得オブジェクトの3番目の要素のname属性とvalue属性を出力
console.log("test5_name -> " + test1.attributes[2].name);
console.log("test5_value -> " + test1.attributes[2].value);

// 取得オブジェクトの4番目の要素のname属性とvalue属性を出力
console.log("test6_name -> " + test1.attributes[3].name);
console.log("test6_value -> " + test1.attributes[3].value);

// 取得オブジェクトの5番目の要素のname属性とvalue属性を出力
console.log("test7_name -> " + test1.attributes[4].name);
console.log("test7_value -> " + test1.attributes[4].value);
</script>

</body>
</html>

サーバ上のHTMLはこちら(test3.html)

存在しないはずの5番目の要素にアクセスする書き方をしてみました。

出力結果は、次のようになります。

test1 -> [object NamedNodeMap]
test2 -> [object Attr]
test3_name -> class
test3_value -> form1
test4_name -> id
test4_value -> p1
test5_name -> type
test5_value -> text
test6_name -> name
test6_value -> test1
Uncaught TypeError: Cannot read properties of undefined (reading 'name')
    at test1.html:43

もともと、ドキュメント内の

<input class="form1" id="p1" type="text" name="test1">

には、
要素が4つしかない為、5つめの要素にアクセスした為に

Cannot read properties of undefined

というエラーになりました。
余談ですが、存在しない要素にアクセスするとどうなるかを試しました。
実際のプログラムでは起こりえない(実装しない)ことですが、内部構造を理解する意味でも色々と試してみるとよいかもしれません。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です