首页 > 解决方案 > 通过 JavaScript 在 HTML 中正确编码变体选择器

问题描述

在 Unicode 中,变体选择器可以用于多种用途。我使用 VS15 ( ︎) 来防止浏览器(它们都是错误的)将某些字符显示为表情符号。

我需要对 Unicode 字符 128 及以上进行编码,因为我们发现问题不仅与数据库有关,而且与浏览器错误有关。即使有建议的修复,VS15(变体选择器 15:)︎也无法正确编码:

HTML,来自数据库,被渲染之前

😏︎

XML 编码函数和用于呈现 HTML的字符编码函数:

function xml_encode(s)
{
 var r = '';
 var skip = 0;
 for (var i = 0; i < s.length; i++)
 {
  if (skip > 0) {skip--;}
  else if (character_code(s, i) > 127)
  {
   r += '&#' + character_code(s, i) + ';';
  }
  else {r += s.charAt(i);}
 }

 return r;
}

function character_code(s, i)
{
 i = i || 0;
 var c = s.charCodeAt(i), hi, low;

 if (0xD800 <= c && c <= 0xDBFF)
 {
  hi = c;
  low = s.charCodeAt(i + 1);
  if (isNaN(low)) {console.log('Error: high surrogate not followed by low surrogate in fixedCharCodeAt()');}
  c = ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
 }

 if (0xDC00 <= c && c <= 0xDFFF) {c = false;}

 return c;
}

此代码的一个示例使用是当用户从页面的可视化编辑切换到 XML 编辑时。如何确保对变体选择器进行正确编码?

标签: javascriptunicodehtml-entities

解决方案


let s = 'a︎';
// U+0061 ‹a› \N{LATIN SMALL LETTER A}
// U+1F60F ‹› \N{SMIRKING FACE}
// U+FE0E ‹◌︎› \N{VARIATION SELECTOR-15}
Array.from(s).map(c => {
    const cp = c.codePointAt(0);
    return cp < 128 ? c : '&#' + cp + ';';
}).join('')
// 'a&#128527;&#65038;'

推荐阅读