JS:为什么我不能在Firefox中使用JS函数获取字体?

时间:2018-02-03 15:31:17

标签: javascript

function getFonts(obj) {
        var o = obj || {},
            sheet = document.styleSheets,
            rule = null,
            i = sheet.length,
            j;
        while(0 <= --i) {
            rule = sheet[i].rules || sheet[i].cssRules || [];
            j = rule.length;
            while(0 <= --j) {
                if(rule[j].constructor.name === 'CSSFontFaceRule') {  
                    o[rule[j].style.fontFamily] = rule[j].style.src;
                };
            }
        }
        return o;
    }

适用于Chrome ... 我不明白为什么这个JS代码在Firefox中不起作用...

2 个答案:

答案 0 :(得分:1)

不要比较.constructor.name来确定你正在处理的对象类型。

在您的特定示例中,CSSRules可以并且应该通过.type进行区分。将rule[j].constructor.name === 'CSSFontFaceRule'条件替换为

if(rule[j].type == CSSRule.FONT_FACE_RULE) {

答案 1 :(得分:0)

修改

正如Bergi在他的评论和回答中指出的那样,你不应该检查构造函数名称来区分不同的CSSRule types。相反,你应该使用:

if (rule[j].type == CSSRule.FONT_FACE_RULE)

原始答案:

某些构造函数名称可能以'Moz'为前缀,因此不是:

if (rule[j].constructor.name === 'CSSFontFaceRule')

你应该检查:

if (rule[j].constructor.name.match(/^(Moz)?CSSFontFaceRule$/))

这样您就可以匹配'CSSFontFaceRule'MozCSSFontFaceRule。此外,在尝试阅读sheet[i].rules时(例如,如果样式表已通过HTTPS加载),您可能会收到指示安全问题的错误,因此您应添加try-catch

function getFonts(obj) {
  var o = obj || {},
    sheet = document.styleSheets,
    rule = null,
    i = sheet.length,
    j;

  while (0 <= --i) { 
    try {
      rule = sheet[i].rules || sheet[i].cssRules || [];
    } catch(err) {
      console.error(err);
      continue;
    }
    
    j = rule.length;

    while (0 <= --j) {
      if (rule[j].constructor.name.match(/^(Moz)?CSSFontFaceRule$/)) {
        o[rule[j].style.fontFamily] = rule[j].style.src;
      }
    }
  }
  
  return o;
}

console.log(getFonts());
@font-face {
    font-family: FontName;
    src: url(font_name.woff);
}
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">