Calcola la larghezza del testo con JavaScript


467

Vorrei usare JavaScript per calcolare la larghezza di una stringa. È possibile senza dover usare un carattere monospaziale?

Se non è integrato, la mia unica idea è quella di creare una tabella di larghezze per ogni personaggio, ma questo è abbastanza irragionevole, specialmente supportando Unicode e dimensioni di tipi diversi (e tutti i browser per quella materia).


10
Fai attenzione che se stai utilizzando caratteri esterni, dovrai utilizzare le tecniche seguenti dopo che sono state caricate. Potresti non rendertene conto se li hai memorizzati nella cache o se hai versioni locali installate.
Seth W. Klein,

Risposte:


355

Crea un DIV in stile con i seguenti stili. Nel tuo JavaScript, imposta la dimensione del carattere e gli attributi che stai cercando di misurare, inserisci la stringa nel DIV, quindi leggi la larghezza e l'altezza correnti del DIV. Si allungherà per adattarsi al contenuto e la dimensione sarà entro pochi pixel dalla dimensione del rendering della stringa.

var fontSize = 12;
var test = document.getElementById("Test");
test.style.fontSize = fontSize;
var height = (test.clientHeight + 1) + "px";
var width = (test.clientWidth + 1) + "px"

console.log(height, width);
#Test
{
    position: absolute;
    visibility: hidden;
    height: auto;
    width: auto;
    white-space: nowrap; /* Thanks to Herb Caudill comment */
}
<div id="Test">
    abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
</div>


8
L'unica cosa che aggiungerei è che ciò può dare dimensioni errate a seconda degli stili utilizzati. Ricorda che potresti avere stili come p {letter-spacing: 0.1em; } che un elemento DIV non rifletterebbe. È necessario assicurarsi che gli stili in atto siano appropriati per dove si utilizzerà il testo.
Jim,

5
Il commento di Ditto Jim: ricontrolla per assicurarti che il contenitore, div in questo caso, non abbia altri stili applicati tramite regole di selezione CSS che potresti non conoscere al momento. Rimuovere tutti gli stili rilevanti dal contenitore prima di applicare quelli a cui tieni prima di misurare.
Jason Bunting,

44
Dovresti anche metterlo nello spazio bianco: nowrap se pensi che il testo superi la larghezza del browser.
Herb Caudill,

5
@Bog tutto ciò che l'hacking è il motivo per cui suggerisco un approccio diverso, meno confuso, al piano di sotto. Dai un'occhiata qui .
Domi il

11
Sei solo curioso di sapere a cosa +1serve ogni dimensione?
Kip

385

In HTML 5 , puoi semplicemente usare il metodo Canvas.measureText (ulteriori spiegazioni qui ).

Prova questo violino :

/**
 * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
 * 
 * @param {String} text The text to be rendered.
 * @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
 * 
 * @see /programming/118241/calculate-text-width-with-javascript/21015393#21015393
 */
function getTextWidth(text, font) {
    // re-use canvas object for better performance
    var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
    var context = canvas.getContext("2d");
    context.font = font;
    var metrics = context.measureText(text);
    return metrics.width;
}

console.log(getTextWidth("hello there!", "bold 12pt arial"));  // close to 86

Questo violino confronta questo metodo Canvas con una variante del metodo DOM di Bob Monteverde , in modo da poter analizzare e confrontare l'accuratezza dei risultati.

Ci sono molti vantaggi in questo approccio, tra cui:

  • Più conciso e più sicuro rispetto agli altri metodi (basati su DOM) perché non cambia lo stato globale, come il DOM.
  • Ulteriore personalizzazione è possibile modificando più proprietà del testo del canvas , come textAligne textBaseline.

NOTA: quando aggiungi il testo al DOM, ricorda di tenere conto anche del riempimento, del margine e del bordo .

NOTA 2: in alcuni browser, questo metodo produce una precisione sub-pixel (il risultato è un numero in virgola mobile), in altri no (il risultato è solo un int). Potresti voler eseguire Math.floor(o Math.ceil) il risultato, per evitare incoerenze. Poiché il metodo basato su DOM non è mai accurato sotto-pixel, questo metodo ha una precisione ancora maggiore rispetto agli altri metodi qui.

Secondo questo jsperf (grazie ai collaboratori nei commenti), il metodo Canvas e il metodo basato su DOM sono altrettanto veloci, se la memorizzazione nella cache viene aggiunta al metodo basato su DOM e non si utilizza Firefox. In Firefox, per qualche motivo, questo metodo Canvas è molto più veloce del metodo basato su DOM (a partire da settembre 2014).


7
Questa è un'opzione fantastica, non lo sapevo. Hai mai confrontato le prestazioni di questo con le prestazioni di misurazione nel DOM?
Semplicemente

2
Ho aggiunto la memorizzazione nella cache a quel benchmark jsperf. Ora i due metodi sono praticamente alla pari: jsperf.com/measure-text-width/4
Brandon Bloom

1
@Martin Huh? Cosa c'entra "molti elementi HTML" con qualcosa qui? L'oggetto canvas in questo esempio non è nemmeno collegato al DOM. E anche a parte questo, cambiare il carattere in un contesto di disegno su tela non influisce nemmeno sulla tela fino a quando tu strokeText()o fillText(). Forse intendevi commentare una risposta diversa?
Ajedi32,

1
Bella soluzione. Ho racchiuso un paio di altri metodi intorno alla risposta di Domi in modo che io possa: Ottenere una stringa (potenzialmente) troncata con i puntini di sospensione (...) alla fine se non si adatta in un determinato spazio (come gran parte della stringa verrà usato il più possibile) - Passa a un elemento JQuery che deve contenere la stringa (possibilmente troncata) e determina gli attributi dei caratteri in modo dinamico in modo che non debbano essere codificati, consentendo agli attributi dei caratteri CSS di cambiare senza interruzione lo schema. JSFiddle Here: jsfiddle.net/brebey/1q94gLsu/6/embed
BRebey

2
Bene perché l'utente non lo vede!
clabe45,

110

Eccone uno che ho montato insieme senza esempio. Sembra che siamo tutti sulla stessa pagina.

String.prototype.width = function(font) {
  var f = font || '12px arial',
      o = $('<div></div>')
            .text(this)
            .css({'position': 'absolute', 'float': 'left', 'white-space': 'nowrap', 'visibility': 'hidden', 'font': f})
            .appendTo($('body')),
      w = o.width();

  o.remove();

  return w;
}

Usarlo è semplice: "a string".width()

** Aggiunto in white-space: nowrapmodo da poter calcolare stringhe con larghezza maggiore della larghezza della finestra.


2
Grazie JordanC. Una cosa che aggiungerei è che, se lo chiami molte volte sulla stessa pagina, e le prestazioni sono un problema, potresti persistere il DIV e cambiare semplicemente il contenuto e controllare la larghezza. L'ho fatto in questo modo, quindi una volta detto e fatto tutto, il DOM sarebbe stato lo stesso di quando hai iniziato
Bob Monteverde,

3
Non aggiungerei questo metodo Stringpoiché riduce la separazione dei problemi del tuo programma (codice core separato rispetto al codice UI). Immagina di voler trasferire il tuo codice principale su una piattaforma con un framework UI molto diverso ...
Domi

23
Questo è un cattivo design , non solo abbina il tuo modello alla tua vista, ma lo accoppia direttamente con jQuery. Inoltre, questo è l'inferno del riflusso, che sicuramente non si ridimensionerebbe bene.
James,

1
Se si desidera il valore float, è possibile utilizzare o[0].getBoundingClientRect().widthcome suggerito qui: stackoverflow.com/a/16072668/936397
Alexander Olsson

1
@virus ha detto bene che probabilmente più di 100 persone non si preoccupano delle prestazioni ... Tuttavia, ciò che rende meno valido o vero non rende ciò che ho detto.
James,

30

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);

27

Questo funziona per me ...

// Handy JavaScript to measure the size taken to render the supplied text;
// you can supply additional style information too if you have it.

function measureText(pText, pFontSize, pStyle) {
    var lDiv = document.createElement('div');

    document.body.appendChild(lDiv);

    if (pStyle != null) {
        lDiv.style = pStyle;
    }
    lDiv.style.fontSize = "" + pFontSize + "px";
    lDiv.style.position = "absolute";
    lDiv.style.left = -1000;
    lDiv.style.top = -1000;

    lDiv.innerHTML = pText;

    var lResult = {
        width: lDiv.clientWidth,
        height: lDiv.clientHeight
    };

    document.body.removeChild(lDiv);
    lDiv = null;

    return lResult;
}

Ciao, la tua risposta è davvero utile, tuttavia usa .cssText invece di .style per supportare IE 8 e versioni precedenti.
Dilip Rajkumar,

Questa risposta è ottima, ma quando generi un grosso pezzo di testo, diventa inaccurato di alcuni pixel. È perché la larghezza non è un numero intero?
Bobtroopo il

20

La libreria javascript di ExtJS ha una grande classe chiamata Ext.util.TextMetrics che "fornisce misurazioni precise dei pixel per blocchi di testo in modo da poter determinare esattamente quanto sarà alto e largo, in pixel, un determinato blocco di testo". Puoi usarlo direttamente o visualizzare il suo codice sorgente per vedere come viene fatto.

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


1
ExtJS ha una licenza dispari. O paghi gli attuali manutentori, la Sencha Company per usarlo, o devi open-source tutto il codice relativo nella tua applicazione. Questo è un punto fermo per la maggior parte delle aziende. jQuery, d'altra parte, utilizza la licenza MIT altamente permissiva.
Devdanke,

1
Javascript non soddisfa automaticamente i requisiti dell'open source? Offri la fonte a chiunque visualizzi la pagina.
PatrickO,

10
C'è una differenza tra la possibilità di visualizzare il codice sorgente e l'open source, che è definito dalla licenza.
Parker Ault,

Grazie a quelli che usano ancora ExtJS :-)
Monarch Wadia il

1
avresti dovuto lasciare che ExtJS riposasse in pace
canbax

19

Mi piace la tua "unica idea" di fare solo una mappa statica della larghezza dei caratteri! In realtà funziona bene per i miei scopi. A volte, per motivi di prestazioni o perché non si ha un facile accesso a un DOM, è possibile che si desideri semplicemente una calcolatrice autonoma hacky rapida calibrata su un singolo carattere. Quindi eccone uno calibrato su Helvetica; passare una stringa e (facoltativamente) una dimensione del carattere:

function measureText(str, fontSize = 10) {
  const widths = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.2796875,0.2765625,0.3546875,0.5546875,0.5546875,0.8890625,0.665625,0.190625,0.3328125,0.3328125,0.3890625,0.5828125,0.2765625,0.3328125,0.2765625,0.3015625,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.2765625,0.2765625,0.584375,0.5828125,0.584375,0.5546875,1.0140625,0.665625,0.665625,0.721875,0.721875,0.665625,0.609375,0.7765625,0.721875,0.2765625,0.5,0.665625,0.5546875,0.8328125,0.721875,0.7765625,0.665625,0.7765625,0.721875,0.665625,0.609375,0.721875,0.665625,0.94375,0.665625,0.665625,0.609375,0.2765625,0.3546875,0.2765625,0.4765625,0.5546875,0.3328125,0.5546875,0.5546875,0.5,0.5546875,0.5546875,0.2765625,0.5546875,0.5546875,0.221875,0.240625,0.5,0.221875,0.8328125,0.5546875,0.5546875,0.5546875,0.5546875,0.3328125,0.5,0.2765625,0.5546875,0.5,0.721875,0.5,0.5,0.5,0.3546875,0.259375,0.353125,0.5890625]
  const avg = 0.5279276315789471
  return str
    .split('')
    .map(c => c.charCodeAt(0) < widths.length ? widths[c.charCodeAt(0)] : avg)
    .reduce((cur, acc) => acc + cur) * fontSize
}

Quella brutta matrice gigante è la larghezza dei caratteri ASCII indicizzata dal codice carattere. Quindi questo supporta solo ASCII (altrimenti assume una larghezza media dei caratteri). Fortunatamente, la larghezza si ridimensiona sostanzialmente in modo lineare con la dimensione del carattere, quindi funziona abbastanza bene con qualsiasi dimensione del carattere. È evidentemente privo di consapevolezza di crenatura, legature o altro.

Per "calibrare" ho appena eseguito il rendering di ogni carattere fino a charCode 126 (la potente tilde) su uno svg e ho ottenuto il rettangolo di selezione e l'ho salvato in questo array; più codice e spiegazione e demo qui .


1
questa è una soluzione intelligente, bella :) Uso sempre lo stesso carattere / dimensione, quindi mi sta bene. Ho trovato le prestazioni delle soluzioni DOM / Canvas un vero problema, questo è davvero pulito, evviva!
mikeapr4,

1
elimina la necessità di tela +1
frage

Puoi sbarazzartene * fontSizee usarli e basta
Matt Fletcher,

Che risposta incredibile!
Almosnow,


7

È possibile utilizzare la tela in modo da non dover affrontare così tanto le proprietà CSS:

var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "20pt Arial";  // This can be set programmaticly from the element's font-style if desired
var textWidth = ctx.measureText($("#myElement").text()).width;

Non è molto più pesante (con ottenere il contesto 2d ecc.) Che creare un elemento DOM e specificare le proprietà CSS per esso?
Pharao2k,

1
Questo è un approccio pulito se stai già usando canvas per qualcosa. Ma MOLTO LENTO. La sola chiamata measureText richiede circa 8-10 ms (utilizzando Chrome).
Rui Marques,

6
<span id="text">Text</span>

<script>
var textWidth = document.getElementById("text").offsetWidth;
</script>

Dovrebbe funzionare finché il tag <span> non ha altri stili applicati. offsetWidth includerà la larghezza di tutti i bordi, l'imbottitura orizzontale, la larghezza della barra di scorrimento verticale, ecc.


Questo è più o meno ciò che rende soluzioni superiori, ma poiché il testo può essere suddiviso in più righe, aggiungono alcuni stili CSS al testo per ottenere la larghezza del testo reale.
Adrian Maire,

2

Il codice che segue, "calcola" la larghezza del tag span, aggiunge "..." se è troppo lungo e riduce la lunghezza del testo, fino a quando non si adatta al suo genitore (o fino a quando non ha provato più di migliaia di volte)

CSS

div.places {
  width : 100px;
}
div.places span {
  white-space:nowrap;
  overflow:hidden;
}

HTML

<div class="places">
  <span>This is my house</span>
</div>
<div class="places">
  <span>And my house are your house</span>
</div>
<div class="places">
  <span>This placename is most certainly too wide to fit</span>
</div>

JavaScript (con jQuery)

// loops elements classed "places" and checks if their child "span" is too long to fit
$(".places").each(function (index, item) {
    var obj = $(item).find("span");
    if (obj.length) {
        var placename = $(obj).text();
        if ($(obj).width() > $(item).width() && placename.trim().length > 0) {
            var limit = 0;
            do {
                limit++;
                                    placename = placename.substring(0, placename.length - 1);
                                    $(obj).text(placename + "...");
            } while ($(obj).width() > $(item).width() && limit < 1000)
        }
    }
});

2
Prova una ricerca binaria, invece di looping 1 carattere alla volta: vedere il mio commento sulla risposta di Alex per stackoverflow.com/questions/536814/...
StanleyH

@StanleyH: buona idea - implementerò il tuo suggerimento il prima possibile.
Techek,

2

La cosa migliore è rilevare se il testo si adatta perfettamente prima di visualizzare l'elemento. Quindi puoi usare questa funzione che non richiede che l'elemento sia sullo schermo.

function textWidth(text, fontProp) {
    var tag = document.createElement("div");
    tag.style.position = "absolute";
    tag.style.left = "-999em";
    tag.style.whiteSpace = "nowrap";
    tag.style.font = fontProp;
    tag.innerHTML = text;

    document.body.appendChild(tag);

    var result = tag.clientWidth;

    document.body.removeChild(tag);

    return result;
}

Uso:

if ( textWidth("Text", "bold 13px Verdana") > elementWidth) {
    ...
}

2

Nel caso in cui qualcun altro fosse qui alla ricerca sia di un modo per misurare la larghezza di una stringa sia di un modo per sapere qual è la dimensione del carattere più grande che si adatterà in una larghezza particolare, ecco una funzione che si basa sulla soluzione di @Domi con una ricerca binaria :

/**
 * Find the largest font size (in pixels) that allows the string to fit in the given width.
 * 
 * @param {String} text The text to be rendered.
 * @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold ?px verdana") -- note the use of ? in place of the font size.
 * @param {width} the width in pixels the string must fit in
 * @param {minFontPx} the smallest acceptable font size in pixels
 * @param {maxFontPx} the largest acceptable font size in pixels
**/
function GetTextSizeForWidth( text, font, width, minFontPx, maxFontPx )
{
    for ( ; ; )
    {
        var s = font.replace( "?", maxFontPx );
        var w = GetTextWidth( text, s );
        if ( w <= width )
        {
            return maxFontPx;
        }

        var g = ( minFontPx + maxFontPx ) / 2;

        if ( Math.round( g ) == Math.round( minFontPx ) || Math.round( g ) == Math.round( maxFontPx ) )
        {
            return g;
        }

        s = font.replace( "?", g );
        w = GetTextWidth( text, s );
        if ( w >= width )
        {
            maxFontPx = g;
        }
        else
        {
            minFontPx = g;
        }
    }
}

Funziona meravigliosamente (insieme al codice della risposta di Domi)
r3wt

1

Prova questo codice:

function GetTextRectToPixels(obj)
{
var tmpRect = obj.getBoundingClientRect();
obj.style.width = "auto"; 
obj.style.height = "auto"; 
var Ret = obj.getBoundingClientRect(); 
obj.style.width = (tmpRect.right - tmpRect.left).toString() + "px";
obj.style.height = (tmpRect.bottom - tmpRect.top).toString() + "px"; 
return Ret;
}

1

La larghezza e l'altezza di un testo possono essere ottenute con clientWidtheclientHeight

var element = document.getElementById ("mytext");

var width = element.clientWidth;
var height = element.clientHeight;

assicurarsi che la proprietà position style sia impostata su assoluta

element.style.position = "absolute";

non è necessario essere all'interno di a div, può essere all'interno di a po aspan


1

Basandomi sulla risposta di Deepak Nadar , ho modificato i parametri delle funzioni per accettare gli stili di testo e font. Non è necessario fare riferimento a un elemento. Inoltre, fontOptionshanno impostazioni predefinite, quindi non è necessario fornirle tutte.

(function($) {
  $.format = function(format) {
    return (function(format, args) {
      return format.replace(/{(\d+)}/g, function(val, pos) {
        return typeof args[pos] !== 'undefined' ? args[pos] : val;
      });
    }(format, [].slice.call(arguments, 1)));
  };
  $.measureText = function(html, fontOptions) {
    fontOptions = $.extend({
      fontSize: '1em',
      fontStyle: 'normal',
      fontWeight: 'normal',
      fontFamily: 'arial'
    }, fontOptions);
    var $el = $('<div>', {
      html: html,
      css: {
        position: 'absolute',
        left: -1000,
        top: -1000,
        display: 'none'
      }
    }).appendTo('body');
    $(fontOptions).each(function(index, option) {
      $el.css(option, fontOptions[option]);
    });
    var h = $el.outerHeight(), w = $el.outerWidth();
    $el.remove();
    return { height: h, width: w };
  };
}(jQuery));

var dimensions = $.measureText("Hello World!", { fontWeight: 'bold', fontFamily: 'arial' });

// Font Dimensions: 94px x 18px
$('body').append('<p>').text($.format('Font Dimensions: {0}px x {1}px', dimensions.width, dimensions.height));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


0

Immagino che questo sia molto simile alla voce di Depak, ma si basa sul lavoro di Louis Lazaris pubblicato in un articolo nella pagina web impressionante

(function($){

        $.fn.autofit = function() {             

            var hiddenDiv = $(document.createElement('div')),
            content = null;

            hiddenDiv.css('display','none');

            $('body').append(hiddenDiv);

            $(this).bind('fit keyup keydown blur update focus',function () {
                content = $(this).val();

                content = content.replace(/\n/g, '<br>');
                hiddenDiv.html(content);

                $(this).css('width', hiddenDiv.width());

            });

            return this;

        };
    })(jQuery);

L'evento fit viene utilizzato per eseguire la chiamata di funzione immediatamente dopo che la funzione è stata associata al controllo.

ad esempio: $ ('input'). autofit (). trigger ("fit");


0

Senza 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);

quando si imposta un numero non funziona, perché non è necessario uno spazio, se lo si rimuove, funzionerà bene: fontSize + "px arial" -> fontSize + "px arial", solo quello.
Alberto Acuña,

0

Fiddle di esempio funzionante: http://jsfiddle.net/tdpLdqpo/1/

HTML:

<h1 id="test1">
    How wide is this text?
</h1>
<div id="result1"></div>
<hr/>
<p id="test2">
    How wide is this text?
</p>
<div id="result2"></div>
<hr/>
<p id="test3">
    How wide is this text?<br/><br/>
    f sdfj f sdlfj lfj lsdk jflsjd fljsd flj sflj sldfj lsdfjlsdjkf sfjoifoewj flsdjfl jofjlgjdlsfjsdofjisdojfsdmfnnfoisjfoi  ojfo dsjfo jdsofjsodnfo sjfoj ifjjfoewj fofew jfos fojo foew jofj s f j
</p>
<div id="result3"></div>

Codice JavaScript:

function getTextWidth(text, font) {
    var canvas = getTextWidth.canvas ||
        (getTextWidth.canvas = document.createElement("canvas"));
    var context = canvas.getContext("2d");
    context.font = font;
    var metrics = context.measureText(text);
    return metrics.width;
};

$("#result1")
.text("answer: " +
    getTextWidth(
             $("#test1").text(),
             $("#test1").css("font")) + " px");

$("#result2")
    .text("answer: " +
        getTextWidth(
             $("#test2").text(),
             $("#test2").css("font")) + " px");

$("#result3")
    .text("answer: " +
        getTextWidth(
             $("#test3").text(),
             $("#test3").css("font")) + " px");

0

Il Element.getClientRects()metodo restituisce una raccolta di DOMRectoggetti che indicano i rettangoli di delimitazione per ogni riquadro del bordo CSS in un client. Il valore restituito è una raccolta di DOMRectoggetti, uno per ogni riquadro del bordo CSS associato all'elemento. Ciascun DOMRectoggetto contiene sola lettura left, top, righte bottomproprietà che descrivono il bordo casella, in pixel, con alto a sinistra rispetto alla parte superiore sinistra della finestra.

Element.getClientRects () di Mozilla Contributors è concesso in licenza in base a CC-BY-SA 2.5 .

Riassumendo tutte le larghezze rettangolari restituite si ottiene la larghezza totale del testo in pixel.

document.getElementById('in').addEventListener('input', function (event) {
    var span = document.getElementById('text-render')
    span.innerText = event.target.value
    var rects = span.getClientRects()
    var widthSum = 0
    for (var i = 0; i < rects.length; i++) {
        widthSum += rects[i].right - rects[i].left
    }
    document.getElementById('width-sum').value = widthSum
})
<p><textarea id='in'></textarea></p>
<p><span id='text-render'></span></p>
<p>Sum of all widths: <output id='width-sum'>0</output>px</p>


0

Ho realizzato un piccolo modulo ES6 (usa jQuery):

import $ from 'jquery';

const $span=$('<span>');
$span.css({
    position: 'absolute',
    display: 'none'
}).appendTo('body');

export default function(str, css){
    $span[0].style = ''; // resetting the styles being previously set
    $span.text(str).css(css || {});
    return $span.innerWidth();
}

Facile da usare:

import stringWidth from './string_width';
const w = stringWidth('1-3', {fontSize: 12, padding: 5});

Cosa interessante che potresti notare: ti permette di prendere in considerazione qualsiasi attributo CSS, persino i padding!


0

Puoi anche farlo con createRange, che è più preciso, rispetto alla tecnica di clonazione del testo:

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;
}

-1
var textWidth = (function (el) {
    el.style.position = 'absolute';
    el.style.top = '-1000px';
    document.body.appendChild(el);

    return function (text) {
        el.innerHTML = text;
        return el.clientWidth;
    };
})(document.createElement('div'));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.