カビパン男と私

HOME/横書き縦書き

html 要素の Javascript による並び換え(メモ)

実演

もしかすると、あなたがやりたいのは、こういうことでは?

おはなし

getElementsByTagName や querySelectorAll を使って取得したオブジェクトはノードリストというもの(ノードリスト・クラスのインスタンス)であり、ノードリストは配列ではない。

ノードリストは length プロパティを持ち、myList[i] のようにしてメンバーを取得できる点では配列に似ているが、slice や push や sort といった、配列が持つメソッドを持っていない。

[余談開始] getElementsByTagName で得たノードリストは、動的に DOM ツリーを反映し続ける。すなわち、getElementsByTagName でノードリストを取得した後に、DOM ツリーを変更すれば、ノードリストはただちにこの変更の影響を受ける。(たとえば、 myNodeList = document.getElementByTabName("p"); とやってノードリストを取得した後、新たに 1 つの p 要素を作成して document に追加すると、myNodeList の長さは 1 増える)

一方、document.querySelectorAll("p") とやって取得したノードリストはこういう動的な性質を持っていない。[余談終了]

比較的簡単な方法でノードリストから配列を得ることができる(非破壊的に変換できる)。

問題

li 要素に含まれるテキストによりソートせよ。

<ul id="test">
  <li>b</li>
  <li>c</li>
  <li>a</li>
</ul>

ヒント

(1) getElementByTagName もしくは querySelectorAll を使ってノードリストを取得し、(2)これから配列を得る。(3)この配列をソートし、(4) 新しい順番を DOM ツリーに反映させる。

解答

document.getElementById("myButton").onclick=mySort;
function mySort() {
    // (1) ノードリストを取得
    var myUL = document.getElementById("test");
    var myNodeList = myUL.getElementsByTagName("li");
    // (2) 配列を得る
    var myArray = Array.prototype.slice.call(myNodeList);
    // (3) 配列をソート
    function compareText (a,b) {
        if (a.textContent > b.textContent)
            return 1;
        else if (a.textContent < b.textContent)
            return -1;
        return 0;
        }
    myArray.sort(compareText);
    // (4) 新しい順番を DOM ツリーに反映
    for (var i=0; i<myArray.length; i++) {
        myUL.appendChild(myUL.removeChild(myArray[i]))
    }
}

@kabipanotoko