如何防止 Unicode 字符从 JavaScript 呈现为 HTML 中的表情符号?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32915485/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:23:03  来源:igfitidea点击:

How to prevent Unicode characters from rendering as emoji in HTML from JavaScript?

javascripthtmlcssunicodeemoji

提问by Huang

I'm finding Unicode for special characters from FileFormat.Info's search.

我正在从FileFormat.Info's search 中找到特殊字符的 Unicode 。

Some characters are rendering as the classic black-and-white glyphs, such as ? (warning sign, \u26A0or ⚠). These are preferable, since I can apply CSS styles (such as color) to them.

一些字符被渲染为经典的黑白字形,例如 ? (警告标志,\u26A0⚠)。这些是可取的,因为我可以对它们应用 CSS 样式(例如颜色)。

image of warning glyph

警告字形的图像

Others are rendering as newer cartoony emoji, such as ? (hourglass, \u231Bor ⌛). These are not preferable, since I cannot fully style them.

其他人则呈现为较新的卡通表情符号,例如?(沙漏,\u231B⌛)。这些不是可取的,因为我无法完全设置它们的样式。

image of hourglass emoji

沙漏表情符号的图像

It appears that the browser is making this change, since I'm able to see the hourglass glyph on Mac Firefox, just not Mac Chrome nor Mac Safari.

浏览器似乎正在进行此更改,因为我能够在 Mac Firefox 上看到沙漏字形,而 Mac Chrome 和 Mac Safari 都看不到。

Is there a way to force browsers to display the older (flat monotone) versions to display?

有没有办法强制浏览器显示要显示的旧(平面单调)版本?

Update: It seems (from comments below) there is a text presentation selector, FE0E, available to enforce text-vs-emoji. The selector is concatenated as a suffix without space onto the character's code, such as ⌛︎for HTML hex or \u231B\uFE0Efor JS. However, it is simply not honored by all browsers(eg Chrome and Edge).

更新:看来(从下面的评论)有一个文本显示选择FE0E,可用来执行文本VS-表情符号。选择器作为没有空格的后缀连接到字符代码上,例如⌛︎HTML 十六进制或\u231B\uFE0EJS。然而,并非所有浏览器(例如 Chrome 和 Edge)都支持它。

回答by Huang

Append the Unicode variation selectorcharacter for forcing text, VS15, ︎.
This forces the previous character to be rendered as text rather than as an Emoji Symbol.

追加Unicode的变化选择字符迫使文本,VS15, ︎
这会强制将前一个字符呈现为文本而不是表情符号。

<p>&#xFE0E;</p>

Result: ︎

结果:︎

Learn more at: Unicode symbol as text or emoji

了解更多信息:Unicode 符号作为文本或表情符号

回答by Glia

I had a Unicode character in the contentof a span::before, and I had the font-familyof the spanset to "Segoe UI Symbol". But Chrome used "Segoe UI Emoji" as the font to render it.

我曾在一个Unicode字符contentspan::before,和我有font-family在中span设置为“的Segoe UI符号”。但是 Chrome 使用“Segoe UI Emoji”作为呈现它的字体。

However, when I set the font-familyto "Segoe UI Symbol" explicitlyfor the span::before, rather than just for the span, then it worked.

但是,当我设置font-family为“的Segoe UI符号”明确span::before,而不是只为span,那么它的工作。

回答by Daneel S. Yaitskov

Android fonts are not rich as you may expect. Font files don't have these exotic glyph and Android has a hack for few characters without glyph. They are replaced with icons.

Android 字体并不像您期望的那样丰富。字体文件没有这些异国情调的字形,而 Android 有一些没有字形的字符的 hack。它们被替换为图标。

So solution is to integrate the site with a web font (woff). Create new font file with FontForge and pick required glyph from free serif TTF for example. Every glyph takes 1k. Generate woff file.

所以解决方案是将站点与网络字体(woff)集成。例如,使用 FontForge 创建新字体文件并从免费衬线 TTF 中选择所需的字形。每个字形需要 1k。生成 woff 文件。

Prepare simple CSS to import the custom font family.

准备简单的 CSS 以导入自定义字体系列。

style.css:

样式.css:

@font-face {
  font-family: 'Exotic Icons';
  src: url('exotic-icons.woff') format('woff');
}

.exotic-symbol-font {
    position: relative;
    top: 1px;
    display: inline-block;
    font-family: 'Exotic Icons';
    font-style: normal;
    font-weight: normal;
    line-height: 1;

    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

index.html file:

index.html 文件:

<html>
  <head>
    <meta charset="utf-8">
    <link href="style.css" rel="stylesheet"></head>
    <title>Test custom glyphs</title>
  </head>
  <body>
    <table>
      <tr>
        <td class="exotic-symbol-font">
             ? &#x2660; a  g
        </td>       
      </tr>
    </table>
  </body>
</html>

回答by ssokolow

If your primary concern is forcing monochromatic display so the emoji don't stand out from the text too much, CSS filters, either alone or in combination with the Unicode variation selector, may be something you want.

如果您主要关心的是强制单色显示以便表情符号不会从文本中脱颖而出,那么 CSS 过滤器,无论是单独使用还是与 Unicode 变体选择器结合使用,都可能是您想要的。

p.gscale { 
  -webkit-filter: grayscale(100%);
  filter: grayscale(100%);
}
a {
  color: #999;
  -webkit-filter: grayscale(100%) sepia(100%) saturate(400%) hue-rotate(170deg);
   filter: grayscale(100%) sepia(100%) saturate(400%) hue-rotate(170deg);
}
<p class="gscale">You've now got emoji display on lockdown.</p>

<p>External Link: <a href="https://knowyourmeme.com/memes/party-hard">celebrate </a></p>

Unlike the variation selector, it shouldn't matter how the emoji are rendered, because CSS filters apply to everything. (I use them to grayscale PNG-format "link type" icons on hyperlinks that have been modified to point to the Wayback Machine.)

与变体选择器不同,表情符号的呈现方式无关紧要,因为 CSS 过滤器适用于所有内容。(我使用它们对已修改为指向 Wayback Machine 的超链接上的 PNG 格式“链接类型”图标进行灰度处理。)

Just mind the caveat. You can't override a parent element's filter in a child, so this technique can't be used to grayscale a paragraph, then re-colorize the links within it.

注意警告。您不能在子元素中覆盖父元素的过滤器,因此此技术不能用于对段落进行灰度化,然后对其中的链接重新着色。

...still, it's useful for situations where you're either going to be making the whole thing a hyperlink or disallowing rich markup within it. (eg. titles and descriptions)

...不过,它对于您要使整个内容成为超链接或禁止其中包含丰富标记的情况很有用。(例如标题和描述)

However, this won't work unless CSS actually gets applied, so I'll give a second option which is more reliable in <title>elements than the Unicode variation selector (I'm looking at you GitHub. I don't like fake icons in my browser tabs):

但是,除非真正应用 CSS,否则这将不起作用,所以我将提供第二个选项,它在<title>元素中比 Unicode 变体选择器更可靠(我正在 GitHub 上查看。我不喜欢我的浏览器标签):

If you're putting a user-provided string into a <title>element, filter out the emoji along with any bold/italic/underline/etc. markup. (Yes, for those who missed it, the standard does call for the contents of <title>to be plain text aside from the ampersand escapes and the browsers I tested all interpret tags within as literal text.)

如果您将用户提供的字符串放入<title>元素中,请过滤掉表情符号以及任何粗体/斜体/下划线/等。标记。(是的,对于那些错过它的人,标准确实要求<title>除了&符号转义之外的内容是纯文本,并且我测试的浏览器将所有标签解释为文字文本。)

The two ways I can think of are:

我能想到的两种方法是:

  1. Directly use a manually-maintained regexwhich matches the blocks where the newest version of Unicode puts its emoji and their modifiers.
  2. Iterate through the grapheme clusters and discardany which contain recognized emoji codepoints. (A grapheme cluster is a base glyph plus all the diacritics and other modifiers which make up the visible character. The example I link to uses Python's regex engine to tokenize and then the emojipackage for the database, but Rust is a good example of a language where iterating grapheme clusters is quick and easy via a crate like unicode-segmentation.)
  1. 直接使用手动维护的正则表达式,该正则表达式匹配最新版本的 Unicode 放置其表情符号及其修饰符的块。
  2. 遍历字素簇并丢弃任何包含已识别表情符号代码点的内容。(字形集群是一个基本字形加上构成可见字符的所有变音符号和其他修饰符。我链接到的示例使用 Python 的正则表达式引擎进行标记,然后emoji是数据库的包,但 Rust 是一种很好的语言示例通过像unicode-segmentation.)

回答by IllidanS4 wants Monica back

Expanding upon ssokolow's answer, using a filter is nice and at least makes the contours visible instead of using a simple font, but converting an RGB color into a sequence of CSS filters is very hard when you want to use a specific color.

扩展ssokolow 的答案,使用过滤器很好,至少使轮廓可见而不是使用简单的字体,但是当您想要使用特定颜色时,将 RGB 颜色转换为 CSS 过滤器序列非常困难。

A better (although quite wordy) option is to use the <feColorMatrix>SVG filter. Combined with the grayscale filter and the data URI scheme, you can represent the color via RGB and in-line CSS:

一个更好的(虽然很冗长)选项是使用<feColorMatrix>SVG 过滤器。结合灰度过滤器和数据 URI 方案,您可以通过 RGB 和内嵌 CSS 来表示颜色:

.violet {
  color: white;
  filter: grayscale(100%) url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='0.78 0 0 0 0  0 0.082 0 0 0  0 0 0.522 0 0  0 0 0 1 0'/></filter></svg>#f");
}

Unfortunately, you cannot interpolate the URL with data (taken from attributes or variables), but at least you don't have to calculate CSS filters from RGB.

不幸的是,您不能用数据(取自属性或变量)插入 URL,但至少您不必从 RGB 计算 CSS 过滤器。

回答by cmbuckley

For a CSS-only solution to prevent iOS displaying emojis, you can use font-family: monospacewhich defaults to the text variant of the glyph rather than the emoji variant.

对于阻止 iOS 显示表情符号font-family: monospace的纯CSS 解决方案,您可以使用默认为字形的文本变体而不是表情符号变体。

回答by Clay Allen

Google Chrome, desktop version 75, seems to disambiguate its approach to rendering Unicode characters based on the first Unicode escape it encounters while loading a page. For instance, when parsed as the first HTML Unicode escape in a page source, and having no emoji equivalent, &#9207; seems to clarify to Chrome that the page contains escapes not to be rendered as emoji.

谷歌浏览器,桌面版本 75,似乎消除了其基于加载页面时遇到的第一个 Unicode 转义符呈现 Unicode 字符的方法的歧义。例如,当被解析为页面源中的第一个 HTML Unicode 转义符并且没有等效的表情符号时,⏷ 似乎向 Chrome 澄清了该页面包含不会呈现为表情符号的转义符。

回答by dave.mcalpine

I dont know of a way to turn off the emoji type rendering. Usually I use an icon font such as font awesomeor glyphicons(comes with Bootstrap 3).

我不知道关闭表情符号类型渲染的方法。通常我使用图标字体,例如font awesomeglyphicons(随 Bootstrap 3 提供)。

The benefit of using these over the unicode characters is that

使用这些超过 unicode 字符的好处是

  1. you can choose from many different styles so it fits the design of your site;
  2. they are consistent across browsers (if you ever tried doing a unicode star character, you'll notice it's different in IE vs other browser);
  3. also, they are fully stylable, like the unicode characters you're trying to use.
  1. 您可以从许多不同的样式中进行选择,使其适合您网站的设计;
  2. 它们在浏览器之间是一致的(如果你曾经尝试过做一个 unicode 星号,你会注意到它在 IE 和其他浏览器中是不同的);
  3. 此外,它们是完全可样式化的,就像您尝试使用的 unicode 字符一样。

The only downside is that its one more thing for the browser to download when they view your page.

唯一的缺点是浏览器在查看您的页面时还要下载另一件事。

回答by Nathan

For me on OSX the solution was to set font-family to EmojiSymbols

对于 OSX 上的我来说,解决方案是将 font-family 设置为 EmojiSymbols

回答by rubo77

None of the solutions above worked for the "Emoji for Google Chrome" Extension.

上述解决方案均不适用于“Google Chrome 表情符号”扩展程序。

So as a workaroundI made a screenshot of the Unicode Character 'BALLOT BOX WITH CHECK' (U+2611) and added it as image with php:

因此,作为一种解决方法,我制作了 Unicode 字符“BALLOT BOX WITH CHECK”(U+2611)的屏幕截图,并将其添加为带有 php 的图像:

 $ballotBoxWithCheck='<img src="pics/U2611.png" style="height:11px;margin-bottom:-1px">'; # &#9745; or /U2611

enter image description here

在此处输入图片说明

See: https://spacetrace.org/man_card.php?tec_id=21&techname=multi-emp-vessel

参见:https: //spacetrace.org/man_card.php?tec_id=21&techname=multi-emp-vessel