当谷歌的 JS 转换失败时,如何防止材料图标文本出现?

Posted

技术标签:

【中文标题】当谷歌的 JS 转换失败时,如何防止材料图标文本出现?【英文标题】:How to prevent material icon text from showing up when Google's JS fails to convert them? 【发布时间】:2017-06-02 07:47:41 【问题描述】:

当 Google 的 JS 无法将它们转换为图标时,如何防止出现实质性图标文本?

图标在标记中定义如下:

<span class="material-icons">icon_name</span>

示例:https://archive.fo/CKqKG/scr.png(参见最上面的按钮行)。

材料图标文档:https://material.io/icons/

这也是谷歌搜索中的一个问题,谷歌实际上会读取并保存 div 的文本,而不是忽略它。

例如:https://i.imgur.com/TixS06y.png

我了解一种解决方案是简单地切换到 .PNG(由 Google 提供)。我想做任何能减少用户系统(网络)负载的事情。

谢谢!

【问题讨论】:

这可能对***.com/a/12316349/3183699有帮助 【参考方案1】:

这是我设法将这个问题降到最低的方法。但请注意,它仅适用于 Chrome 和 Edge,否则它将退回到通常的行为。通过使用 document.fonts.onloadingdone 我检查我想要的字体是否已加载。如果它被加载,我会创建一个类,它将“material-icons”类的不透明度变为 1,该类最初在 css 中设置为 0。

我在一个 css 文件中编写了这个规则(它将被最终在脚本中定义的类覆盖)

.material-icons  opacity: 0 ;

我在我的 index html 页面中添加了一个脚本标签。

  <script>
    // This executes on chrome and EDGE only as tested
    document.fonts.onloadingdone = function (fontFaceSetEvent) 
      // console.log(fontFaceSetEvent.fontfaces) to see the available fonts which have been loaded
      // and change the font family name according to your font family requirement
      const fontName = 'Material Icons';
      if (fontFaceSetEvent.fontfaces.filter(i => i.family === fontName).length > 0) 
        addMakeIconsVisibleClass();
      
    ;

    // Fallback - call below function if not chrome (or EDGE)
    if (navigator.userAgent.toLowerCase().indexOf('chrome') === -1) 
      addMakeIconsVisibleClass();
    

    function addMakeIconsVisibleClass() 
      let style = document.createElement('style');
      style.innerHTML = '.material-icons  opacity: 1 !important ';
      document.getElementsByTagName('head')[0].appendChild(style);
    
  </script>

【讨论】:

【参考方案2】:

我们可以先使用 css 将图标的透明度归零,然后在 3 秒后使用 addClass 显示图标。

var delayInMilliseconds = 3000;
setTimeout(function() 
var element = document.getElementById("mayicons");
  element.className +="ops1";
, delayInMilliseconds);
.material-icons 
    width: 26px;
    height: 30px;
    overflow: hidden;
    opacity: 0;



.ops1
    opacity: 1;
&lt;i id="mayicons" class="material-icons "&gt;list&lt;/i&gt;

【讨论】:

如果你的网速太慢,3秒后字体仍未加载怎么办?【参考方案3】:

我发现如果您在链接标签中的 href 末尾插入 &amp;display=swap 会有所帮助,如下所示:

<link
    href="https://fonts.googleapis.com/icon?family=Material+Icons&display=swap"
    rel="stylesheet"
  >

这里有一个link 供参考

【讨论】:

"在加载自定义字体时避免显示不可见文本的最简单方法是临时显示系统字体 (...) 交换告诉浏览器使用该字体的文本应立即使用系统字体显示. 一旦自定义字体准备好,它就会替换系统字体。”这正好与问题的内容相反。【参考方案4】:

您可以使用相应的十六进制代码点,而不是使用材料图标全文。 当然这不是隐藏,但如果没有加载字体,它只会显示未知的字符符号。

示例:

<i class="material-icons">&#xE87D;</i>

您可以在以下位置找到代码点列表:

https://github.com/google/material-design-icons/issues/813#issuecomment-401601344

https://raw.githubusercontent.com/flutter/flutter/master/packages/flutter/lib/src/material/icons.dart

【讨论】:

【参考方案5】:

对此的正确解决方案是添加相同字体大小的最大宽度并将溢出设置为隐藏。

.material-icons 
    max-width: 16px;
    overflow: hidden;

【讨论】:

【参考方案6】:

在首页创建一个 div style = "position: absolute; top: -1000px" 并输入所有具有类material-icon或awesome字体的项目如下:

<div   style="position:absolute;top:-1000px" >      
<i class="icon material-icons-outlined"  >add_circle</i>
<i class="icon material-icons "  >list_alt</i>
<span class="fas fa-circle fa-stack-2x " ></span>
<span class="fas fa-home fa-stack-1x fa-inverse"  ></span>
</div>

【讨论】:

【参考方案7】:

如果你使用 angularjs,修复可能是

<i class="material-icons-outlined" ng-bind-html=" 'icon_text' "></i>

或者如果你使用的是 jquery,那么

HTML

<i material-icons="icon_text" class="material-icons"></i>

jQuery.onLoad

$('[material-icons]').each(function()
  var icon_text = $(this).attr('material-icons');
  $(this).html(icon_text)
);

图标在页面加载后出现。

【讨论】:

这看起来很有希望【参考方案8】:

不是修复,但在support preconnect 的浏览器上,您可以尝试尽快加载字体。应该有助于减少在慢速连接上显示文本和图标之间的时间。

<link rel="preconnect" href="//fonts.googleapis.com">
<link rel="preconnect" href="//fonts.gstatic.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">

【讨论】:

您实际上可以做的极少数事情之一。当然不是修复,但它仍然是一些东西。不幸的是,问题是请求返回样式表,接下来添加对字体本身的请求。大部分时间都排在队列的末尾。不过还是有的。【参考方案9】:

我一直在为类似的情况而苦苦挣扎:我的问题不在于图标 从未 加载,只是它们可能需要一段时间才能在较慢的连接上加载,直到它们加载丑陋的无格式文本比如 sentiment_very_satisfied 会显示在页面上(通常比周围的文字大很多倍,也非常明显)。

这里的其他解决方案对我不起作用(包括我认为可能很有希望的font-display:block),所以我使用 CSS 和 jQuery 提出了自己的解决方案。我相信你可以很容易地调整它以使用 vanilla JS。

CSS:

.material-icons
    opacity:0;

jQuery:

$(window).load(function() 
    $('.material-icons').css('opacity','1');
);

这里的诀窍是,与更常用的$(document).ready() 侦听器不同,$(window).load() 在触发之前等待页面的所有元素下载完毕。在这种情况下,这意味着在下载图标字体之前,它不会更改图标的不透明度。

缺点是图标在页面上的所有内容都被下载之前不会显示,但这是我愿意做出的权衡,以避免出现大量文本可见在加载图标字体之前在我的页面上。

(我还向 CSS .material-iconstransition:opacity 0.5s; 添加了一个过渡,因此它们显示得又好又流畅。)

【讨论】:

我刚刚查了一下,sentiment_very_satisfied 是一个真正的图标:material.io/resources/icons/…。是的,这就是我想要让我的用户闪烁的东西。【参考方案10】:

您可以使用font-display: block;,只需将此 CSS 添加到您的 HTML 头部:

<style>
   @font-face 
      font-family: 'Material Icons';
      font-display: block;
    
</style>

更多信息font-display

【讨论】:

这只有在你在@font-face 中指定字体的src 并且不在你的头脑中使用@importlink 标签时才有效。不幸的是,谷歌字体(目前)还不能做到这一点:css-tricks.com/… 注意:font-display: 块将显示一个不可见的字体,这意味着在加载字体时,将显示一个不可见的文本,其长度与备用文本相同。此连字文本通常比实际字体宽,因此您需要设置一些样式,以便即使由于 font-display:block 不可见,宽度仍然较小,因此不会出现闪烁。 老问题,但对我来说是新问题。您现在可以使用 Google 字体指定 font-display 属性,因此 fonts.googleapis.com/… 有效。 我尝试了您的解决方案并且它正在工作,但是当网络速度太慢时就不行了。更清楚地说,它将显示块(实际上什么都没有)而不是文本,大约两秒钟,所以当我尝试 fast 3G 模式时很好,它不会向用户显示文本,但对于 slow 3G 模式,问题仍然存在,只是延迟了大约两秒钟!有什么办法可以增加这个延迟?!【参考方案11】:

我也面临同样的问题。不过,我相信使用像 i.material-icons:before 这样的伪选择器会有所帮助。请参阅this 了解更多信息。

---- 编辑:工作示例

i.material-icons:beforedisplay:none;

【讨论】:

【参考方案12】:

如果您使用的是 Typekit 的 webfont loader,您可以应用条件类来在 Web 字体加载或加载失败时隐藏图标,例如:

.wf-loading, .wf-materialicons-n4-inactive 
  .material-icons 
    display: none;
  

您当然可以根据自己的喜好应用其他样式技术以获得最佳效果,例如font-size: 0;,这取决于您的站点和用例。

要使用 webfont 加载器加载材质图标,请使用如下配置:

window.WebFontConfig = 
  google: 
    families: [
      'Material Icons',
    ],
  ,
;

【讨论】:

您能否详细说明为什么素材图标无法显示以及为什么显示为文本?有什么解决方法? 素材图标无法显示的原因有很多,例如互联网连接失败或获取字体文件的请求失败。在这种情况下,如果您使用带有连字的材料图标,当您的代码类似于&lt;i class="material-icons"&gt;face&lt;/i&gt; 时,“face”一词将在您的页面上以纯文本形式显示。我的答案中的解决方法阻止了此文本的显示。

以上是关于当谷歌的 JS 转换失败时,如何防止材料图标文本出现?的主要内容,如果未能解决你的问题,请参考以下文章

谷歌的搜索如何知道你想说啥? [复制]

如何允许用户在 Node JS Passport JS 失败后尝试不同的电子邮件?

重新定位材料自动完成弹出图标

谷歌的 Firebase UI 身份验证失败并显示消息(代码:10 消息:10)

当谷歌浏览器中有很多 websocket 连接时,socket io 会中断

如何掌握谷歌的Chrome developer tool调试技巧