かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript   なスペースのあるHTMLの扱い

先に JSX 内で   が含まれる場合のテストのハマりどころ書いてしまったけど、改めて JavaScript での扱いをメモ。

JavaScript での取得

<p id="elm">星宮&nbsp;いちご</p>
const elm = document.getElementById('elm');

elm.innerText; // 星宮 いちご
elm.firstChild.nodeValue; // 星宮 いちご
elm.textContent; // 星宮 いちご
elm.innerHTML; // 星宮&nbsp;いちご

&nbsp;を含むテキストのマッチ

通常のスペース 文字コード\u0020
&nbsp;なスペース 文字コード\u00A0

const testTest = [
  "星宮 いちご", // 通常のスペース
  "星宮 いちご"; // &nbsp; なスペース
  "星宮&nbsp;いちご",
  "星宮\u0020いちご", // 通常のスペースを文字コードに
  "星宮\u00A0いちご", // `&nbsp;`なスペースを文字コードに
];
const matchText = (str) => {
  testTest.forEach((val, i) => {
    console.log( str === val );
  });
};

const str1 = elm.innerText; // 星宮 いちご
matchText(str1);
// str1 === "星宮 いちご" => false 
// str1 === "星宮 いちご" => true
// str1 === "星宮&nbsp;いちご" => false
// str1 === "星宮\u0020いちご" => false
// str1 === "星宮\u00A0いちご" => true

const str2 = elm.firstChild.nodeValue; 星宮 いちご
matchText(str2);
// str2 === "星宮 いちご" => false 
// str2 === "星宮 いちご" => true
// str2 === "星宮&nbsp;いちご" => false
// str2 === "星宮\u0020いちご" => false
// str2 === "星宮\u00A0いちご" => true

const str3 === elm.textContent; // 星宮 いちご
matchText(str3);
// str3 === "星宮 いちご" => false 
// str3 === "星宮 いちご" => true
// str3 === "星宮&nbsp;いちご" => false
// str3 === "星宮\u0020いちご" => false
// str3 === "星宮\u00A0いちご" => true

const str4 === elm.innerHTML; // 星宮&nbsp;いちご
matchText(str4);
// str4 === "星宮 いちご" => false 
// str4 === "星宮 いちご" => false
// str4 === "星宮&nbsp;いちご" => true
// str4 === "星宮\u0020いちご" => false
// str4 === "星宮\u00A0いちご" => false

JavaScriptのテキストノードで取得した &nbsp; なスペースは (&nbsp; なスペース) または \u00A0 と同じ扱いになり、通常のスペースや &nbsp; という文字列とは同じには扱われません。

&nbsp; なスペースの操作

テキストノードで取得した &nbsp; なスペースは \s にマッチする

.replace(/\s/g, ' ') で通常のスペースに置き換えることが出来る

// HTML <p id="elm">星宮&nbsp;いちご</p>
const elm = document.getElementById('elm');

elm.textContent.replace(/\s/g, ' ') === "星宮 いちご"; // 通常のスペース
// => true
elm.textContent.replace(/\s/g, ' ') === "星宮\u0020いちご"; 
// => true

テキストノードで取得した &nbsp; なスペースは trim() で除去できる

\s にマッチするからだと思うが、空白扱いになり前後にあるものなら trim() で除去することが出来る。

// HTML <p id="elm">&nbsp;星宮 いちご&nbsp;</elm>
const elm = document.getElementById('elm');

elm.textContent.trim() === "星宮 いちご";
// => true
まとめ

文字列のマッチなどを行う時に、 を見分けるのは困難なので、マッチを行うときは .replace(/\s/g, ' ') で置き換えてしまうのが良さそうだと思いました。
それ以前に必然性のない不要な箇所で &nbsp; を使わないようにするのが間違いなく一番だと思います。


[参考]

スラスラ読める JavaScript ふりがなプログラミング (ふりがなプログラミングシリーズ)

スラスラ読める JavaScript ふりがなプログラミング (ふりがなプログラミングシリーズ)