nextSiblingは何を取得するか

自分で確認しないと身に染みないので。


以下のようなHTMLを作成。

	<table>
		<tbody>
			<tr>
				<th>見出し1</th>
				<td id="data1_1">data1_1</td>
				<td id="data1_2">data1_2</td>
			</tr>
			<tr>
				<th>見出し2</th>
				<td id="data2_1">data2_1</td><td>data2_2</td>
			</tr>
		</tbody>
	</table>
		
	<div id="div_idtest">
		<p id="p_1">
			これは、(ここで改行)	
			<abbr id="abbr1_1">ここはabbr要素(ここで改行)</abbr>
			<span id="span1_1">ここはspan要素(ここで改行)</span>
			です。(ここで改行)
		</p>
		<p id="p_2">
			これは、(ここで改行)
			<abbr id="abbr2_1">ここはabbr要素(改行なし)</abbr><span id="span2_1">ここはspan要素(ここで改行)</span>
			です。(ここで改行)
		</p>
		<p id="p_3">3つ目のpタグ(改行なし)</p><p id="p_4">4つ目のpタグ</p>
	</div>

<td id="data1_1">のnextSiblingを確認(table要素:改行ありの場合)

ノードタイプを確認してみる。
HTML:

	<td id="data1_1">data1_1</td>
	<td id="data1_2">data1_2</td>

JavaScript

	var data1_1 = document.getElementById("data1_1");
	alert(data1_1.nextSibling.nodeType);


各ブラウザごとの結果:


ノードタイプ1は、要素ノード、
ノードタイプ3は、テキストノード。


ノードバリューを取得してみると、

	var data1_1 = document.getElementById("data1_1");
	alert(data1_1.nextSibling.nodeValue);


各ブラウザごとの結果:


ノードネームを取得してみると、

	var data1_1 = document.getElementById("data1_1");
	alert(data1_1.nextSibling.nodeName);


各ブラウザごとの結果:


IEは要素ノード(<td id="data1_2">)を参照しているので、
nodeValueを取得しようとするとnullが返ってくる。
FirefoxSafariでは、</td>のあとの改行が取得されるので、alertに何も表示されない。

<td id="data2_1">のnextSiblingを確認(table要素:改行なしの場合)

ノードタイプを確認してみる。
HTML:

	<td id="data2_1">data2_1</td><td>data2_2</td>

JavaScript

	var data2_1 = document.getElementById("data2_1");
	alert(data2_1.nextSibling.nodeType);


各ブラウザごとの結果:


この場合、2つのtd要素が改行なしで記述されているので、
すべてのブラウザで、2つ目のtd要素が取得されている。

<p id="p_1">のnextSiblingを確認(ブロック要素:改行ありの場合)

ノードタイプを確認してみる。
HTML:

	<p id="p_1">
		これは、(ここで改行)	
		<abbr id="span1_1">ここはabbr要素(ここで改行)</abbr>
		<span id="abbr1_1">ここはspan要素(ここで改行)</span>
		です。(ここで改行)
	</p>
	<p id="p_2">
		これは、(ここで改行)
		<abbr id="abbr2_1">ここはabbr要素(改行なし)</abbr><span id="span-2_1">ここはspan要素(ここで改行)</span>
		です。(ここで改行)
	</p>

JavaScript

	var p_1 = document.getElementById("p_1");
	alert(p_1.nextSibling.nodeType);


各ブラウザごとの結果:


ノードバリューを取得してみると、

	var p_1 = document.getElementById("p_1");
	alert(p_1.nextSibling.nodeValue);


各ブラウザごとの結果:


IEは要素ノード(<p id="p_2">)を参照しているので、
nodeValueを取得しようとするとnullが返ってくる。
FirefoxSafariでは、</p>のあとの改行が取得されるので、alertに何も表示されない。

<p id="p_3">のnextSiblingを確認(ブロック要素:改行なしの場合)

ノードタイプを確認してみる。
HTML:

	<p id="p_3">3つ目のpタグ(改行なし)</p><p id="p_4">4つ目のpタグ</p>

JavaScript

	var p_3 = document.getElementById("p_3");
	alert(p_3.nextSibling.nodeType);


各ブラウザごとの結果:


id属性を確認してみる。
JavaScript

	var p_3 = document.getElementById("p_3");
	alert(p_3.nextSibling.getAttribute("id"));


各ブラウザごとの結果:


この場合、2つのp要素が改行なしで記述されているので、
すべてのブラウザで、2つ目のp要素が取得されている。

<abbr id="abbr1_1">のnextSiblingを確認(インライン要素:改行ありの場合)

ノードタイプを確認してみる。
HTML:

	<abbr id="abbr1_1">ここはabbr要素(ここで改行)</abbr>
	<span id="span1_1">ここはspan要素(ここで改行)</span>

JavaScript

	var abbr1_1 = document.getElementById("abbr1_1");
	alert(abbr1_1.nextSibling.nodeType);


各ブラウザごとの結果:


ノードバリューを確認してみる。
JavaScript

	var abbr1_1 = document.getElementById("abbr1_1");
	alert(abbr1_1.nextSibling.nodeValue);


各ブラウザごとの結果:


IE6はabbr要素をサポートしていない。
IE Developper Toolbarで確認すると、
「ここはabbr要素(ここで改行)」の部分は、
abbr要素の子要素ではなく、兄弟要素として扱われている。


下記のようにspanとabbrを入れ替えて、span要素のnextSiblingを確認してみる。
HTML:

	<span id="span1_2">ここはspan要素(ここで改行)</span>
	<abbr id="abbr1_2">ここはabbr要素(ここで改行)</abbr>

ノードタイプ:
JavaScript

	var span1_2 = document.getElementById("span1_2");
	alert(span1_2.nextSibling.nodeType);


ノードバリュー:
JavaScript

	var span1_2 = document.getElementById("span1_2");
	alert(span1_2.nextSibling.nodeValue);

さらにspan要素の後にテキストを追加してみる。
HTML:

	<span id="span1_2">ここはspan要素</span>ここにてきすと(ここで改行)
	<abbr id="abbr1_2">ここはabbr要素(ここで改行)</abbr>

ノードバリュー:
JavaScript

	var span1_2 = document.getElementById("span1_2");
	alert(span1_2.nextSibling.nodeValue);


まあ、ブロック要素内なので、改行だろうとテキストだろうとテキストノードはテキストノードであると。

<abbr id="abbr2_1">のnextSiblingを確認(インライン要素:改行なしの場合)

ノードタイプを確認してみる。
HTML:

	<abbr id="abbr2_1">ここはabbr要素(改行なし)</abbr><span id="span2_1">ここはspan要素(ここで改行)</span>

JavaScript

	var abbr2_1 = document.getElementById("abbr2_1");
	alert(abbr2_1.nextSibling.nodeType);


各ブラウザごとの結果:

ノードバリューを確認してみる。
JavaScript

	var abbr2_1 = document.getElementById("abbr2_1");
	alert(abbr2_1.nextSibling.nodeValue);


各ブラウザごとの結果:


abbr要素とspan要素を入れ替えてみる。
HTML:

	<span id="span2_2">ここはabbr要素(改行なし)</span><abbr id="abbr2_2">ここはspan要素(ここで改行)</abbr>

ノードタイプ:
JavaScript

	var span2_2 = document.getElementById("span2_2");
	alert(span2_2.nextSibling.nodeType);


各ブラウザごとの結果:


ノードネーム:
JavaScript

	var span2_2 = document.getElementById("span2_2");
	alert(span2_2.nextSibling.nodeName);


各ブラウザごとの結果:

まとめ

やってみると大したことではないような気もするけど、IE6のおかげで結構混乱してたな。


とりあえず、以下の3点。

  1. HTML内のブロック要素間、table要素間の改行について、IEは無視、そのほかはノードと解釈。
  2. インライン要素間の改行について、各ブラウザとも改行をノード(普通にテキストノード)と解釈。
  3. IE6ではサポートしていない要素を使うときは注意する。


3点目については、nextSibling以外についても注意する。
対応については、とりあえずその都度検討。