在javascript中检测浏览器字符支持?

Posted

技术标签:

【中文标题】在javascript中检测浏览器字符支持?【英文标题】:Detect browser character support in javascript? 【发布时间】:2011-06-05 20:39:51 【问题描述】:

我正在开发一个与音乐相关的网站,并且经常使用 html 特殊字符来表示升号 (♯) 和降号 (♭) 以保持内容美观,例如:

♯
♭

但是,我注意到在某些浏览器(IE6、PC 版 Safari)中不支持这些字符。我创建了一个条件 javascript,它提供普通的、受支持的字符来代替特殊字符( G# 代表 G♯ 和 Bb 代表 B♭ )。但我很难弄清楚如何检测哪些浏览器缺少这些字符。

我知道我可以测试浏览器(例如 ie6),但我希望做正确的事情并测试 字符支持 本身。

有谁知道使用 javascript、jQuery 或 rails 的好方法吗? (该页面由 rails 应用程序提供服务,因此请求对象和任何其他 Rails 魔法都在桌面上。

【问题讨论】:

我最终选择了 Mike Samuel 的出色解决方案,尽管我认为那些表明格式问题的可能存在一些问题——我确实尝试了所有解决方案,但这并不意味着我没有错过任何东西。正如其他人所建议的那样,遇到类似问题的任何人都应该:1.确保他们的页面具有正确的字符编码,2.查看 Matt Ball 引用的链接答案。我在 99% 的情况下偷偷地怀疑他可能是比 javascript hack 更好的解决方案。 我怀疑这是字体问题。所选字体不包含您想要的代码点的字素。许多现代浏览器可以使用字体替换(从另一种字体中挑选字形)来弥补这一点。 Mike Samuel 的解决方案很聪明,但如果涉及到固定宽度的字体,可能就行不通了。不幸的是,我没有更好的解决方案。 @McDowell - 嗯...我查看了this list of fonts 并没有看到任何可能在带有ie6 的系统上的网络安全字体。所以我只是尝试了“无衬线”但没有成功。我在这里错过了什么吗?有什么好的选择? Microsoft seems to claim that Arial Unicode MS works,但它不适合我(或者可能我的 Windows XP 版本不包含它)。 【参考方案1】:

如果你创建了两个 SPAN,一个包含你想要的字符,另一个包含不可打印字符 U+FFFD (�) 是一个好的,那么你可以测试它们是否具有相同的宽度。

<div style="visibility:hidden">
  <span id="char-to-check">&#9839;</span>
  <span id="not-renderable">&#xfffd;</span>
</div>
<script>
  alert(document.getElementById('char-to-check').offsetWidth ===
        document.getElementById('not-renderable').offsetWidth
        ? 'not supported' : 'supported');
</script>

您应该确保 DIV 没有使用固定字体设置样式。

【讨论】:

非常聪明!而且速度如此之快,以至于我必须再等四分钟才能将您的答案标记为已接受,我会的。 我之前曾尝试将特殊字符作为类添加到一次性 div 上,然后测试该类,但没有任何运气。这是一段非常优雅的代码——谢谢! @Pirrpli,谢谢。在将其标记为接受之前,我会确保它确实适用于您担心的浏览器。马特·鲍尔可能是对的。 这个方法的问题在于 �显示宽度和其他有效字符具有相同宽度,例如 █ 此方法基于隐含的假设,即字体中缺少的字符呈现为与 U+FFFD 相同。这是不可靠的,并且已知浏览器会使用其他渲染。【参考方案2】:

“浏览器支持”不是这里的问题。您应该以UTF-8* 的身份提供文件,并使用适当的字符而不是 HTML 实体。

Unicode 尖锐符号:♯ (U+266F) Unicode 平面符号:♭ (U+266D)

您还应该确保将文件保存为 UTF-8(而不是 ASCII 或 ISO-8859-1)。

另请参阅:必须提及的Joel on Software: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)。


*我不是 Rails 人,但我认为它默认会这样做。

【讨论】:

嗯...我相信我已经在这样做了。我有一个元标记:。除了将实际符号复制并粘贴到我的标记中之外,我还应该做些什么特别的事情吗?我刚刚做了这个,在ie6上测试了一下,发现了小方块。你知道ie6支持这两个符号吗? @Pirrpli:见this answer。这可能只是字体问题,但将符号插入标记绝对是可行的方法。您确定将文件保存为 UTF-8 吗? 非常有趣,绝对值得一读,但我无法打开 this page's insights into sharp symbols... 我首先尝试将相关 div 的类更改为使用 Arial,然后只是简单的 sans-衬线,没有成功。我很可能在这里遗漏了一些东西,但目前,我想我将使用 Mike Samuel 的建议。稍后我会告诉你我是否成功,但在这一点上,我认为仍然在 ie6 上的用户类型不会介意看到# 为♯。 ;) @Pirrpli:很高兴您了解 JS 方法更像是一种 hack。 IMO,最好的解决方案是简单地stopsupportingIE6。也就是说 - 你确实提到 Windows 上的 Safari 也有问题...... 哈!我喜欢 ie6nomore.com 并且会考虑使用他们的代码来提示用户正确的方向。然而,我注意到,即使我每天都在与 ie6 搏斗(这是我在任何设计项目中最不喜欢的部分),我发现尝试让 ie6 工作通常会让我的代码更好,依赖于更简单的 HTML,更少的盒子模型黑客(例如负边距等...),这让我通常更全面地考虑页面,而不仅仅是 DIV 和 CSS 的集合。不要误会我的意思,我仍然讨厌它。但我认为它更像是一个混蛋田径教练。【参考方案3】:

你应该做的是使用 css 的 unicode-range,而不是乱搞 JavaScript:

@font-face 
  font-family: 'MyWebFont'; /* Define the custom font name */
  src:  local("Segoe UI Symbol"),
        local("Symbola"),
        url('myfont.woff2') format('woff2'),
        url('myfont.woff') format('woff'); /* Define where the font can be downloaded */
  unicode-range: U+266F, U+266D; /* Define the available characters */


body 
  font-family: 'MyWebFont', Arial;
&#9839;
&#9837;
Normal text

local 块中,定义人们可能已在本地安装的字体并包含您想要的符号(如 Window 的 Segoe UI 符号)。然后定义一个包含您要显示的符号的网络字体(我建议Symbola)。

unicode-range 指令告诉支持浏览器 (IE9 and up) 不要下载字体,除非页面上存在指定的符号(您可以通过搜索 Unicode-Tables 找到它们的 unicode 编号。)

如果他们已经拥有该字体,他们将不会下载它。如果页面上不存在符号并且您的浏览器不比污垢旧,则不会下载字体。它只会在需要时下载。

(如果您仍想支持旧版 IE,请使用 fontsquirrel 生成初始的 @font-face 语句,然后自己添加 localunicode-range 部分。

【讨论】:

【参考方案4】:

将此添加到您的 HTML

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 

</head>

并检查 IE 和 Safari 是否正确呈现页面。

【讨论】:

不,不走运。我已经有了 ,但我尝试添加你的属性无济于事......不过,谢谢你的想法!我希望是这样... ;)

以上是关于在javascript中检测浏览器字符支持?的主要内容,如果未能解决你的问题,请参考以下文章

[转]JavaScript快速检测浏览器对CSS3特性的支持

JS 严格模式

JavaScript 检测浏览器是否支持 CSS 变量

javascript 检测浏览器是否支持画布

javascript 检测浏览器是否支持帆布

如何在 Javascript 中比较字符串和布尔值?