JavaScript – テキストノードを取得して要素へ追加する

JavaScriptを使ってテキストノードを取得(削除)して特定の要素へ追加する方法を解説する。例えば下記のようなリストがあるとする。この場合のテキストノードは<a>タグの後ろにある(1)などの数字にあたる。

<ul class="list">
    <li class="list-item"><a href="#">Acrobat&nbsp;Reader</a> (1)</li>
    <li class="list-item"><a href="#">AltTab</a> (1)</li>
    <li class="list-item"><a href="#">Amazon</a> (8)</li>
    <li class="list-item"><a href="#">Android</a> (2)</li>
    .
    .
    .
    .
</ul>

このテキストノードを取得して次のように<a>タグ内のテキストへ埋め込む方法を解説する。

<ul class="list">
    <li class="list-item"><a href="#">Acrobat&nbsp;Reader (1)</a></li>
    <li class="list-item"><a href="#">AltTab (1)</a></li>
    <li class="list-item"><a href="#">Amazon (8)</a></li>
    <li class="list-item"><a href="#">Android (2)</a></li>
    .
    .
    .
    .
</ul>

1.NodeListの取得

まず、リスト内のテキスト情報を取得したいのでquerySelectorAll()を使用してNodeListを取得する。コードは次のようになる。

let texts = document.querySelectorAll('li.list-item');
console.log(texts);

console.log(texts)とデバックすると次のように取得されているのがわかるかと思う。

これらのNodeListの子要素にアクセスるにはforEach()を使い次のように記述をすれば各子要素を取得することができる。

texts.forEach((txt) => {
    console.log(txt);
});

2.childNodesで子ノードの情報を取得と置換

先ほどの方法で子要素を取得することができましたが、それだけでは子ノードの情報は取得できません。なのでchildNodes()を使い子ノードの情報を取得します。childNodes()を使うことでテキストノード、コメントノードなどのすべてのノードにアクセス可能になります。コンソールで確認すればNodeListに子ノードが格納されているのがわかるかと思います。

let texts = document.querySelectorAll('li.list-item');
texts.forEach((txt) => {
    console.log(txt.childNodes);
});

// -> NodeList(2) [a, text]...

次に、テキストノードを取得するには下記のように記述します。

let texts = document.querySelectorAll('li.list-item');
texts.forEach((txt) => {
    console.log(txt.childNodes[1].textContent);
});

なぜそのような記述になったのかはコンソールでデバックすると理解が深まる。テキストノードは[1]に格納されており、取得したい情報はtextContentであるため。

そして最後に取得したテキストノードを<a>タグ内のテキストに埋め込み、テキストノードを削除します。この場合の記述は次のようになります。

let texts = document.querySelectorAll('li.list-item');
texts.forEach((txt) => {
    txt.childNodes[0].innerText += txt.childNodes[1].textContent;
    txt.childNodes[1].remove();
});

また、この場合の構造だとtxt.textContentでもテキストノードを取得することはできるので下記のコードでも置換することは可能。

txt.childNodes[0].innerText = txt.textContent;

最後にremove()を使い不要なテキストノードを削除します。