Calculate text width with JavaScript

前端 未结 24 1486
陌清茗
陌清茗 2020-11-21 05:08

I\'d like to use JavaScript to calculate the width of a string. Is this possible without having to use a monospace typeface?

If it\'s not built-in, my only idea is t

相关标签:
24条回答
  • 2020-11-21 05:18

    The ExtJS javascript library has a great class called Ext.util.TextMetrics that "provides precise pixel measurements for blocks of text so that you can determine exactly how high and wide, in pixels, a given block of text will be". You can either use it directly or view its source to code to see how this is done.

    http://docs.sencha.com/extjs/6.5.3/modern/Ext.util.TextMetrics.html

    0 讨论(0)
  • 2020-11-21 05:18

    You can also do this with createRange, which is more accurate, than the text cloning technique:

    function getNodeTextWidth(nodeWithText) {
        var textNode = $(nodeWithText).contents().filter(function () {
            return this.nodeType == Node.TEXT_NODE;
        })[0];
        var range = document.createRange();
        range.selectNode(textNode);
        return range.getBoundingClientRect().width;
    }
    
    0 讨论(0)
  • 2020-11-21 05:19

    Without jQuery:

    String.prototype.width = function (fontSize) {
        var el,
            f = fontSize + " px arial" || '12px arial';
        el = document.createElement('div');
        el.style.position = 'absolute';
        el.style.float = "left";
        el.style.whiteSpace = 'nowrap';
        el.style.visibility = 'hidden';
        el.style.font = f;
        el.innerHTML = this;
        el = document.body.appendChild(el);
        w = el.offsetWidth;
        el.parentNode.removeChild(el);
        return w;
    }
    
    // Usage
    "MyString".width(12);
    
    0 讨论(0)
  • 2020-11-21 05:20

    I'm using text-metrics package. Works really nice, I tried this solution but in some reasons, it counts it wrong.

    textMetrics.init(document.querySelector('h1'), { fontSize: '20px' });
    
    textMetrics.init({
      fontSize: '14px',
      lineHeight: '20px',
      fontFamily: 'Helvetica, Arial, sans-serif',
      fontWeight: 400,
      width: 100,
    });
    
    0 讨论(0)
  • 2020-11-21 05:20

    Rewritten my answer from scratch (thanks for that minus). Now function accepts a text and css rules to be applied (and doesn't use jQuery anymore). So it will respect paddings too. Resulting values are being rounded (you can see Math.round there, remove if you want more that precise values)

    function getSpan(){
        const span = document.createElement('span')
        span.style.position = 'fixed';
        span.style.visibility = 'hidden';
        document.body.appendChild(span);
        return span;
    }
    
    function textWidth(str, css) {
        const span = getSpan();
        Object.assign(span.style, css || {});
        span.innerText = str;
        const w = Math.round(span.getBoundingClientRect().width);
        
        span.remove();
        
        return w;
    }
    
    
    const testStyles = [
      {fontSize: '10px'},
      {fontSize: '12px'},
      {fontSize: '60px'},
      {fontSize: '120px'},
      {fontSize: '120px', padding: '10px'},
      {fontSize: '120px', fontFamily: 'arial'},
      {fontSize: '120px', fontFamily: 'tahoma'},
      {fontSize: '120px', fontFamily: 'tahoma', padding: '5px'},
    ];
    
    const ul = document.getElementById('output');
    testStyles.forEach(style => {
      const li = document.createElement('li');
      li.innerText = `${JSON.stringify(style)} > ${textWidth('abc', style)}`;
      ul.appendChild(li);
    });
    <ul id="output"></ul>

    0 讨论(0)
  • 2020-11-21 05:21

    jQuery:

    (function($) {
    
     $.textMetrics = function(el) {
    
      var h = 0, w = 0;
    
      var div = document.createElement('div');
      document.body.appendChild(div);
      $(div).css({
       position: 'absolute',
       left: -1000,
       top: -1000,
       display: 'none'
      });
    
      $(div).html($(el).html());
      var styles = ['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing'];
      $(styles).each(function() {
       var s = this.toString();
       $(div).css(s, $(el).css(s));
      });
    
      h = $(div).outerHeight();
      w = $(div).outerWidth();
    
      $(div).remove();
    
      var ret = {
       height: h,
       width: w
      };
    
      return ret;
     }
    
    })(jQuery);
    
    0 讨论(0)
提交回复
热议问题