週末長知識: 不換行空格

最近處裡一些 HTML 裡面的字串空白,發現在出現   的時候好像用 ' ' 會消不完全… 沒道理啊?

舉個例子

有沒有感覺到一點點的微妙,為何中間的空白不會被 split() 切開呢? 難道從 $(...).text() 取得的中間有些空白不是一般的空白?

接著把上面實驗中的字串拿來研究一下。

// 來源: 上面範例中的 $.trim($('#content').text())
var str = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.';

console.log(str.charCodeAt(str.indexOf('sit') - 1)));
// output: 160

知道 charcode 是 160 之後應該就很好搜尋囉,於是用 「charcode space 160」 去 google 了一下找到這篇文章:

White-space and character 160

So I used charCodeAt and found it was ASCII character 160. I looked up char code 160 and saw that it is a “Non-breaking space”. You would think that a “space” character would be trimmed. I looked at the jQuery code that does the trimming and the grep pattern uses \s. So, evidently you can’t use \s to catch the “Non-breaking space” in IE. I wonder why no one else has seen this.

乍看好像是古早年代的 IE 問題? 那我怎麼現在會在 modern browser 裡面碰到呢?

接著來試著搜尋中文 「char 160 空白」,發現相關的問題在各種地方出現…

char_160_whitespace.png

突然就看到了 Wikipedia 的連結

眼尖的話會注意到原來在 HTML 裡面的 &nbps; 竟然是也是不換行空格的實現!!!!! 小時候填鴨式學的 HTML,只知道   是一種輸入空白的方法,原來它還有這層特別的含意… 更何況原來它根本不是空白!(說是也可以是啦)

原來 2009 年的 IE 是對的。(根據上面 2009 年的文章,當時的其他瀏覽器都把   輸出為一般的空白 ' ',但 IE 裡面用 regular expression /\s/ 還是 match 不到 '\u00a0')

總之現在 modern browser 們也都是把   轉為這個 '\u00a0',以後碰到類似的東西就不需要大驚小怪囉! 心裡有個底的話,debug 起來會快很多的。

最後補充一下,上面 2009 那篇文章的內容已經與現在瀏覽器的情況不符了。 文中附的 test 頁面 ,展示的 jQuery trim(text) 結果現在看起來是正確的,因為現在的瀏覽器已經確實把 '\u00a0' 視為空白的一種囉!

用 code 來說就是

'\u00a0\u00a0'.replace(/\s/g, '') === '';  // true