使用getComputedStyle时,Firefox返回字符串的空字符串

时间:2018-05-28 22:27:31

标签: javascript css typescript firefox fonts

我编写了一个实用程序函数来获取字符串的像素宽度。我希望该函数可以选择在特定元素上使用字体集,因此无论该元素的样式是什么,我都会自动使用该字体进行测量。

问题是Firefox不想告诉我元素使用的是什么字体。以下代码适用于其他浏览器:

wget https://atom.io/download/deb && dpkg -i deb

问题是export function getTextWidth(items: string | string[], font: string | HTMLElement, fallbackFont?: string): number { const canvas = ((getTextWidth as any).canvas as HTMLCanvasElement || ((getTextWidth as any).canvas = document.createElement('canvas') as HTMLCanvasElement)); const context = canvas.getContext('2d'); let maxWidth = 0; if (typeof font === 'string') context.font = (font ? font : 'normal 12px sans-serif'); else if (typeof font === 'object') { const elementFont = window.getComputedStyle(font).getPropertyValue('font'); if (elementFont) context.font = elementFont; else if (fallbackFont) context.font = fallbackFont; else context.font = 'normal 12px sans-serif'; } if (!Array.isArray(items)) items = [items]; for (const item of items) { const width = context.measureText(item).width; maxWidth = Math.max(maxWidth, width); } return maxWidth; } 在Firefox上返回一个空字符串,因此我无法将window.getComputedStyle(font).getPropertyValue('font')设置为匹配的字体,以便context正常工作。

我在我的函数measureText中添加了可选参数,所以我可以传递一个显式字体,但这不是一个非常令人满意的解决方案。

2 个答案:

答案 0 :(得分:0)

必须以这种方式获取字体有点痛苦,但我发现Firefox将分别返回元素当前字体的各个方面,例如font-sizefont-family。它们都可以被查询并组装成一个字体字符串:

  if (typeof font === 'string')
    context.font = (font ? font : 'normal 12px sans-serif');
  else if (typeof font === 'object') {
    let style = window.getComputedStyle(font);
    let elementFont = style.getPropertyValue('font');

    if (elementFont)
      context.font = elementFont;
    else {
      const fontStyle = style.getPropertyValue('font-style');
      const fontVariant = style.getPropertyValue('font-variant');
      const fontWeight = style.getPropertyValue('font-weight');
      const fontSize = style.getPropertyValue('font-size');
      const fontFamily = style.getPropertyValue('font-family');

      elementFont = (fontStyle + ' ' + fontVariant + ' ' + fontWeight + ' ' + fontSize + ' ' + fontFamily)
        .replace(/ +/g, ' ').trim();

      if (elementFont)
        context.font = elementFont;
      else if (fallbackFont)
        context.font = fallbackFont;
      else
        context.font = 'normal 12px sans-serif';
    }
  }

答案 1 :(得分:0)

这是我用来从getComputedStyle()返回的对象中安全地检索.font属性的函数。已在Chrome / Safari / Firefox中测试。请注意,我还将Firefox的字体扩展百分比值转换为关键字,因为百分比值似乎无法与Canvas一起使用,例如measureText()。

function getFontFromComputedStyle (computedStyle) {
  let font = computedStyle.font;
  // Firefox returns the empty string for .font, so create the .font property manually
  if (font === '') {
    // Firefox uses percentages for font-stretch, but Canvas does not accept percentages
    // so convert to keywords, as listed at:
    //   https://developer.mozilla.org/en-US/docs/Web/CSS/font-stretch
    let fontStretchLookupTable = {
      '50%': 'ultra-condensed',
      '62.5%': 'extra-condensed',
      '75%': 'condensed',
      '87.5%': 'semi-condensed',
      '100%': 'normal',
      '112.5%': 'semi-expanded',
      '125%': 'expanded',
      '150%': 'extra-expanded',
      '200%': 'ultra-expanded'
    };
    // If the retrieved font-stretch percentage isn't found in the lookup table, use
    // 'normal' as a last resort.
    let fontStretch = fontStretchLookupTable.hasOwnProperty(computedStyle.fontStretch)
      ? fontStretchLookupTable[computedStyle.fontStretch]
      : 'normal';
    font = computedStyle.fontStyle
      + ' ' + computedStyle.fontVariant
      + ' ' + computedStyle.fontWeight
      + ' ' + fontStretch
      + ' ' + computedStyle.fontSize
      + '/' + computedStyle.lineHeight
      + ' ' + computedStyle.fontFamily;
  }
  return font;
}

用法:

getFontFromComputedStyle(getComputedStyle(elem))