JavaScript ile metin genişliğini hesaplama


467

Bir dizenin genişliğini hesaplamak için JavaScript kullanmak istiyorum. Tek boşluklu bir yazı tipi kullanmak zorunda kalmadan bu mümkün müdür?

Yerleşik değilse, tek fikrim her karakter için bir genişlik tablosu oluşturmaktır, ancak bu özellikle Unicode ve farklı tür boyutlarını (ve bu konudaki tüm tarayıcıları) destekleyen oldukça mantıksızdır .


10
Harici yazı tipleri kullanıyorsanız, yüklendikten sonra aşağıdaki teknikleri kullanmanız gerektiğini unutmayın. Bunları önbelleğe aldıysanız veya yerel sürümleri yüklediyseniz bunu gerçekleştiremeyebilirsiniz.
Seth W. Klein

Yanıtlar:


355

Aşağıdaki stillerle stilize edilmiş bir DIV oluşturun. JavaScript'inizde, ölçmeye çalıştığınız yazı tipi boyutunu ve niteliklerini ayarlayın, dizenizi DIV'ye koyun, ardından DIV'nin geçerli genişliğini ve yüksekliğini okuyun. İçeriğe uyacak şekilde gerilecek ve boyut, işlenen dize boyutunun birkaç pikseli içinde olacaktır.

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
Ekleyeceğim tek şey, kullanılan stillere bağlı olarak bunun yanlış boyutlar verebilmesidir. Unutmayın p {letter-spacing: 0.1em; } bir DIV öğesinin yansıtmayacağı. Mevcut stillerin metni kullanacağınız yere uygun olduğundan emin olmalısınız.
Jim

5
Ditto Jim'in yorumu - kabın, bu durumda div'ın, o zaman bilemeyeceğiniz css seçim kuralları yoluyla uygulanan başka stilleri olmadığından emin olmak için tekrar kontrol edin. Ölçmeden önce önem verdiklerinizi uygulamadan önce ilgili tüm stilleri kaptan çıkarın.
Jason Bunting

44
Ayrıca beyaz boşluk koymalısınız: metnin tarayıcı genişliğini aşacağını düşünüyorsanız nowrap.
Herb Caudill

5
@BBog hack, alt katta farklı, daha az hacky bir yaklaşım önermem nedenidir. Buraya bir bakın .
Domi

11
Sadece +1her boyutta ne için olduğunu merak ediyor musunuz?
Kip

385

In HTML 5 , sadece kullanabilirsiniz Canvas.measureText yöntemi (daha fazla açıklama buraya ).

Bu kemanı deneyin :

/**
 * 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

Bu keman , bu Canvas yöntemini Bob Monteverde'nin DOM tabanlı yönteminin bir varyasyonu ile karşılaştırır, böylece sonuçların doğruluğunu analiz edebilir ve karşılaştırabilirsiniz.

Bu yaklaşımın çeşitli avantajları vardır, bunlardan bazıları:

  • DOM'niz gibi genel durumu değiştirmediğinden diğer (DOM tabanlı) yöntemlerden daha özlü ve güvenli.
  • Daha özelleştirme yoluyla mümkündür daha tuval metin özellikleri modifiye gibi, textAlignve textBaseline.

NOT: Metni DOM'nize eklerken, dolgu, kenar boşluğu ve kenarlığı da dikkate almayı unutmayın .

NOT 2: Bazı tarayıcılarda, bu yöntem alt piksel doğruluğunu verir (sonuç bir kayan nokta sayısıdır), diğerlerinde ise (sonuç yalnızca int'tir). Tutarsızlıklardan kaçınmak için sonuç üzerinde çalışmak Math.floor(veya Math.ceil) yapmak isteyebilirsiniz . DOM tabanlı yöntem hiçbir zaman alt piksel doğru olmadığından, bu yöntem buradaki diğer yöntemlerden daha yüksek bir hassasiyete sahiptir.

Göre bu jsperf (yorumlardaki katkıda bulunanlara teşekkür), Tuval yöntemi ve DOM tabanlı yöntem önbelleğe alma eklenirse, eşit hızlı üzeresiniz DOM tabanlı yöntemle ve Firefox kullanmıyorsunuz. Firefox'ta, bazı nedenlerden dolayı, bu Canvas yöntemi DOM tabanlı yöntemden çok daha hızlıdır (Eylül 2014 itibariyle).


7
Bu harika bir seçenek, bunu bilmiyordum. Bunun performansını DOM'daki ölçüm performansıyla hiç karşılaştırdınız mı?
SimplGy

2
Önbelleği o jsperf karşılaştırmasına ekledim. Şimdi iki yöntem hemen hemen par: jsperf.com/measure-text-width/4
Brandon Bloom

1
@Martin Huh? "Birçok HTML öğesi" nin buradaki herhangi bir şeyle ne ilgisi var? Bu örnekteki tuval nesnesi DOM'ya bile bağlı değildir. Ve bunun dışında bile, bir tuval çizim bağlamında yazı tipini değiştirmek, siz strokeText()veya tuvaline kadar tuvali bile etkilemez fillText(). Belki de farklı bir cevap hakkında yorum yapmak istediniz?
Ajedi32

1
Güzel çözüm. Domi'nin cevabının etrafına birkaç yöntem daha ekledim, böylece - verilen bir alana sığmayacaksa (sonunda) üç nokta (()) ile elips (...) ile kesilmiş bir dize alın mümkün olduğunda kullanılacaktır) - (muhtemelen kesilmiş) dizeyi içerecek bir JQuery Öğesini iletin ve CSS font niteliklerinin kırılmadan değişmesine izin verecek şekilde sabit kodlanması gerekmeyecek şekilde Font niteliklerini dinamik olarak belirleyin tasarım. JSFiddle Here: jsfiddle.net/brebey/1q94gLsu/6/embed
BRebey

2
İyi çünkü kullanıcı görmüyor!
clabe45

110

İşte örnek olmadan birlikte çırptığım. Görünüşe göre hepimiz aynı sayfadayız.

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

Kullanımı basit: "a string".width()

** white-space: nowrapPencere genişliğinden daha büyük genişliğe sahip dizelerin hesaplanabilmesi için eklenmiştir .


2
Teşekkürler JordanC. Ekleyeceğim bir şey, bunu aynı sayfada birçok kez çağırıyorsanız ve performans bir sorunsa, DIV'yi devam ettirebilir ve sadece içeriği değiştirebilir ve genişliği kontrol edebilirsiniz. Sadece bu şekilde yaptım, bu yüzden her şey söylendiğinde ve yapıldıktan sonra, DOM başladığınız
Bob Monteverde

3
Ben bu yöntemi endişelerinizi ayırma (ayrı çekirdek kodu vs UI kodu) Stringprogramınızın azaldığı için için eklemek olmaz . Temel kodunuzu çok farklı bir kullanıcı arayüzü çerçevesine sahip bir platforma taşımak istediğinizi düşünün ...
Domi

23
Bu kötü tasarım , sadece modelinizi görünümünüzle birleştirmekle kalmaz, aynı zamanda doğrudan jQuery ile çiftler. Bunun da ötesinde, bu yeniden akış cehennemidir, bu kesinlikle iyi ölçeklenmez.
James

1
Kayan nokta değerini istiyorsanız, o[0].getBoundingClientRect().widthburada önerildiği gibi kullanabilirsiniz : stackoverflow.com/a/16072668/936397
Alexander Olsson

1
@virüs 100'den fazla insanın muhtemelen performansı umursamadığını söyledi ... Bununla birlikte, söylediklerimi daha az geçerli veya doğru yapmıyor.
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

Bu benim için çalışıyor ...

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

Merhaba cevap gerçekten yararlı ancak IE 8 ve daha düşük desteklemek için .style yerine .cssText kullanın ..
Dilip Rajkumar

Bu cevap harika, ancak büyük bir metin parçası oluşturduğumda, birkaç piksel yanlış oluyor. Genişlik bir tamsayı olmadığı için mi?
Bobtroopo

20

Extjs JavaScript kütüphanesi "tam olarak ne kadar yüksek belirleyebilir ve geniş piksel olarak metnin belirli bir blok olacak şekilde metnin bloklar için hassas piksel ölçümleri sağlar" diye Ext.util.TextMetrics adında harika bir sınıf vardır. Bunun nasıl yapıldığını görmek için doğrudan kullanabilir veya kodlamak için kaynağını görüntüleyebilirsiniz.

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


1
ExtJS'nin tek bir lisansı var. Geçerli bakıcılara, Sencha Company'ye bunu kullanmak için ödeme yaparsınız veya başvurunuzdaki ilgili tüm kodu açık kaynak koduyla göndermelisiniz. Bu, çoğu şirket için bir gösteri tıpasıdır. Öte yandan jQuery, oldukça izin verilen MIT lisansını kullanır.
devdanke

1
Javascript otomatik olarak açık kaynak gereksinimlerini karşılamıyor mu? Kaynağı, sayfayı görüntüleyen herkese sunarsınız.
PatrickO

10
Kaynak kodu ile lisanslama tarafından tanımlanan açık kaynak kodunu görüntüleyebilme arasında bir fark vardır.
Parker Ault

Hala ExtJS kullananlardan teşekkürler :-)
Monarch Wadia


19

Statik bir karakter genişliği haritası yapma "tek fikrinizi" seviyorum! Aslında benim amacım için iyi çalışıyor. Bazen, performans nedenlerinden dolayı veya bir DOM'a kolay erişiminiz olmadığından, tek bir yazı tipiyle kalibre edilmiş hızlı bir hacky bağımsız hesap makinesi isteyebilirsiniz. İşte Helvetica için kalibre edilmiş bir tane; bir dize ve (isteğe bağlı olarak) bir yazı tipi boyutu iletme:

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
}

Bu dev çirkin dizi, karakter koduyla dizinlenmiş ASCII karakter genişliğidir. Yani bu sadece ASCII'yi destekler (aksi takdirde ortalama bir karakter genişliği varsayar). Neyse ki, genişlik temel olarak yazı tipi boyutuyla doğrusal olarak ölçeklenir, bu nedenle herhangi bir yazı tipi boyutunda oldukça iyi çalışır. Belirgin şekilde, karakter aralığı veya bitişik harfler veya başka herhangi bir farkındalıktan yoksundur.

"Kalibre" Ben sadece bir svg charCode 126 (kudretli tilde) kadar her karakter render ve sınırlama kutusu var ve bu diziye kaydetti; daha fazla kod ve açıklama ve demo burada .


1
Bu akıllı bir çözüm, güzel bir :) Her zaman aynı yazı tipini / boyutunu kullanıyorum, bu yüzden bana çok yakışıyor. DOM / Canvas çözümlerinin performansını gerçek bir problem olarak buldum, bu gerçekten temiz, şerefe!
mikeapr4

1
tuval +1 ihtiyacını ortadan kaldırır
frage

* fontSizeOnlardan kurtulabilir ve sadece 'em' kullanabilirsiniz
Matt Fletcher

Ne harika bir cevap!
almosnow


7

Tuvali kullanabilirsiniz, böylece css özellikleri ile çok fazla uğraşmanıza gerek kalmaz:

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;

Bu, bir DOM öğesi oluşturmak ve onun için css özelliklerini belirtmekten çok daha ağır değil mi (2d bağlamı vb. İle)?
Pharao2k

1
Zaten bir şey için tuval kullanıyorsanız bu temiz bir yaklaşımdır. Ama ÇOK YAVAŞ. MeasureText çağrısı tek başına yaklaşık 8-10 ms sürer (Chrome kullanarak).
Rui Marques

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

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

Bu, <span> etiketinde başka bir stil uygulanmadığı sürece çalışmalıdır. offsetWidth, herhangi bir kenarlığın genişliğini, yatay dolguyu, dikey kaydırma çubuğu genişliğini vb. içerecektir.


Üst çözümler yapan şey aşağı yukarı budur, ancak metniniz birkaç satıra bölünebileceğinden, gerçek tam metin genişliğini elde etmek için metne bazı CSS stilleri ekler.
Adrian Maire

2

Aşağıdaki kod pasajları, span etiketinin genişliğini "hesapla", çok uzunsa "..." ekler ve metin uzunluğunu ebeveyne sığana kadar (veya bin defa)

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 (jQuery ile)

// 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
Yerine bir seferde 1 karakterini döngü bir ikili arama deneyin: Alex'in cevabı benim yorumu görmek stackoverflow.com/questions/536814/...
StanleyH

@StanleyH: İyi fikir - Önerinizi mümkün olan en kısa sürede uygulayacağım.
Techek

2

Daha iyisi, öğeyi görüntülemeden hemen önce metnin uyup uymayacağını tespit etmektir. Böylece, öğenin ekranda olmasını gerektirmeyen bu işlevi kullanabilirsiniz.

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

Kullanımı:

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

2

Durumda başkasının bir dize genişliğini ölçmek için bir yol hem seyir burada var ve belirli bir genişlikte uyacak en büyük yazı tipi boyutu ne bilmek için bir yol, burada bir ikili arama ile Domi çözümüyle @ üzerine inşa bir fonksiyondur :

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

Bu şaşırtıcı bir şekilde çalışıyor (
Domi'nin

1

Bu kodu deneyin:

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

Bir metnin genişliği ve yüksekliği ile clientWidthveclientHeight

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

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

stil konumu özelliğinin mutlak olarak ayarlandığından emin olun

element.style.position = "absolute";

a içinde olması gerekmez div, a pveya a içinde olabilirspan


1

Deepak Nadar'ın cevabından yola çıkarak, metin ve yazı tipi stillerini kabul etmek için parametre parametrelerini değiştirdim. Bir öğeye başvurmanıza gerek yoktur. Ayrıca, fontOptionsvarsayılan var, bu yüzden hepsini sağlamanız gerekmez.

(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

Sanırım bu Depak girişine benziyor ama Louis Lazaris'in etkileyici web sayfasındaki bir makalede yayınlanan çalışmalarına dayanıyor

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

Fit olayı, işleve kontrole bağlandıktan sonra fonksiyon çağrısını ara olarak yürütmek için kullanılır.

örneğin: $ ('input'). autofit (). trigger ("fit");


0

JQuery olmadan:

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

bir sayı ayarladığınızda çalışmaz, çünkü gereksiz bir boşluk varsa, kaldırırsanız, düzgün çalışır: fontSize + "px arial" -> fontSize + "px arial", sadece bu.
Alberto Acuña

0

Çalışan örnek keman: 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>

JavaScript kodu:

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

Element.getClientRects()Yöntem bir koleksiyon döndürür DOMRectbir istemci her CSS sınır kutusu için sınırlayıcı dikdörtgenler gösterir nesneler. Döndürülen değer, DOMRectöğeyle ilişkilendirilmiş her CSS kenarlık kutusu için bir tane olmak üzere bir nesne koleksiyonudur . Her bir DOMRectnesne salt okunur içerir left, top, rightve bottomüst sol akraba, piksel olarak, sınır kutusunun tarif özellikleri görünüm en sol.

Mozilla Katılımcılar tarafından Element.getClientRects () CC-BY-SA 2.5 altında lisanslanmıştır .

Döndürülen tüm dikdörtgen genişliklerinin toplanması piksel cinsinden toplam metin genişliğini verir.

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

Küçük bir ES6 modülü yaptım (jQuery kullanır):

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

Kullanımı kolay:

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

Fark edebileceğiniz harika bir şey - herhangi bir CSS özelliğini, hatta dolguları hesaba katmanıza izin verir!


0

Bunu, metin klonlama tekniğinden daha doğru olan createRange ile de yapabilirsiniz:

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'));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.