Рассчитать ширину текста с помощью JavaScript


467

Я хотел бы использовать JavaScript для расчета ширины строки. Возможно ли это без использования моноширинного шрифта?

Если он не встроенный, моя единственная идея - создать таблицу ширины для каждого символа, но это довольно неразумно, особенно с поддержкой Unicode и разных размеров шрифта (и всех браузеров в этом отношении).


10
Помните, что если вы используете внешние шрифты, вам придется использовать методы, приведенные ниже, после их загрузки. Возможно, вы этого не поймете, если вы их кэшировали или если у вас установлены локальные версии.
Сет В. Кляйн

Ответы:


355

Создайте DIV со следующими стилями. В вашем JavaScript установите размер шрифта и атрибуты, которые вы пытаетесь измерить, поместите вашу строку в DIV, затем прочитайте текущую ширину и высоту DIV. Он растянется, чтобы соответствовать содержимому, и размер будет в пределах нескольких пикселей от размера отображаемой строки.

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
Единственное, что я хотел бы добавить, это то, что это может дать неправильные размеры в зависимости от того, какие стили используются. Помните, что у вас могут быть такие стили, как p {letter-spacing: 0.1em; } что элемент DIV не будет отражать. Вы должны убедиться, что стили на месте соответствуют тому, где вы будете использовать текст.
Джим

5
Ditto Jim's comment - перепроверьте, чтобы убедиться, что к контейнеру, div в этом случае, не применяются какие-либо другие стили, применяемые к нему через правила выбора css, о которых вы, возможно, не знали в то время. Удалите все соответствующие стили из контейнера, прежде чем применять те, которые вам нужны, перед измерением.
Джейсон Бантинг

44
Вы также должны поставить пробел: nowrap, если вы думаете, что текст будет превышать ширину браузера.
Herb Caudill

5
@BBog все эти взломы, поэтому я предлагаю другой, менее хакерский подход внизу. Посмотрите на это здесь .
Доми

11
Просто любопытно, что +1для каждого измерения?
Кип

385

В HTML 5 вы можете просто использовать метод Canvas.measureText (дальнейшее объяснение здесь ).

Попробуйте эту скрипку :

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

Эта скрипка сравнивает этот метод Canvas с вариацией метода , основанного на DOM Боба Монтеверде , так что вы можете анализировать и сравнивать точность результатов.

У этого подхода есть несколько преимуществ, в том числе:

ПРИМЕЧАНИЕ. При добавлении текста в DOM не забывайте также учитывать отступы, поля и границы .

ПРИМЕЧАНИЕ 2: В некоторых браузерах этот метод дает субпиксельную точность (результат - число с плавающей запятой), в других - нет (результат - только целое число). Возможно, вы захотите запустить Math.floor(или Math.ceil) результат, чтобы избежать несоответствий. Поскольку метод на основе DOM никогда не является субпиксельным с точностью, этот метод имеет даже более высокую точность, чем другие методы здесь.

Согласно этому jsperf (спасибо авторам в комментариях), метод Canvas и метод на основе DOM работают примерно одинаково, если к методу на основе DOM добавлено кэширование, а вы не используете Firefox. В Firefox по какой-то причине этот метод Canvas намного быстрее, чем метод на основе DOM (по состоянию на сентябрь 2014 года).


7
Это отличный вариант, я не знал об этом. Когда-нибудь сравнивать производительность этого с производительностью измерения в DOM?
SimplGy

2
Я добавил кеширование в этот тест jsperf. Теперь эти два метода в значительной степени совпадают
Брэндон Блум,

1
@ Мартин А? При чем здесь «много элементов HTML»? Объект canvas в этом примере даже не прикреплен к DOM. И даже помимо этого, изменение шрифта в контексте рисования холста даже не влияет на холст, пока вы strokeText()или fillText(). Возможно, вы хотели прокомментировать другой ответ?
Ajedi32

1
Хорошее решение. Я обернул несколько других методов вокруг ответа Domi, чтобы я мог: - Получить (потенциально) усеченную строку с многоточием (...) в конце, если она не помещается в заданное пространство (столько же в строке будет использоваться, насколько это возможно) - передать элемент JQuery, который должен содержать (возможно, усеченную) строку, и динамически определять атрибуты Font, чтобы их не нужно было жестко кодировать, позволяя атрибутам шрифта CSS изменяться без прерывания расположение. JSFiddle Здесь: jsfiddle.net/brebey/1q94gLsu/6/embed
BRebey

2
Хорошо, потому что пользователь этого не видит!
clabe45

110

Вот тот, который я взбил без примера. Похоже, мы все на одной странице.

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

Используя это просто: "a string".width()

** Добавлено, white-space: nowrapчтобы можно было рассчитать строки с шириной, превышающей ширину окна.


2
Спасибо Джордан. Я бы добавил, что если вы вызываете это много раз на одной и той же странице, и производительность является проблемой, вы можете сохранить DIV и просто изменить содержимое и проверить ширину. Я просто сделал это таким образом, чтобы после того, как все было сказано и сделано, DOM был бы таким же, как когда вы начинали
Боб Монтеверде

3
Я бы не стал прибегать к этому методу, Stringпоскольку он уменьшает разделение интересов вашей программы (отдельный код ядра и код пользовательского интерфейса). Представьте, что вы хотите портировать свой основной код на платформу с совершенно другой структурой пользовательского интерфейса ...
Domi

23
Это плохой дизайн , он не только соединяет вашу модель с вашим представлением, но также соединяет ее напрямую с jQuery. Кроме того, это адский рефлоу, это определенно не будет хорошо масштабироваться.
Джеймс

1
Если вы хотите использовать значение с плавающей запятой, вы можете использовать его o[0].getBoundingClientRect().widthв соответствии с предложением здесь: stackoverflow.com/a/16072668/936397
Александр Олссон,

1
@virus хорошо сказал, что 100+ людей, вероятно, тоже не заботятся о производительности ... Тем не менее, не делает то, что я сказал, менее достоверным или правдивым.
Джеймс

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

Это работает для меня ...

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

Привет, ваш ответ действительно полезен, однако используйте .cssText вместо .style для поддержки IE 8 и ниже.
Дилип Раджкумар

Этот ответ хорош, но когда я генерирую большой фрагмент текста, он становится неточным на несколько пикселей. Это потому, что ширина не является целым числом?
Bobtroopo

20

В библиотеке ExtJS javascript есть отличный класс Ext.util.TextMetrics, который «обеспечивает точные измерения пикселей для блоков текста, чтобы вы могли точно определить, насколько высокими и широкими в пикселях будет данный блок текста». Вы можете использовать его напрямую или просмотреть его исходный код, чтобы увидеть, как это делается.

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


1
ExtJS имеет нечетную лицензию. Либо вы платите текущим сопровождающим, либо компании Sencha за их использование, или вы должны открыть исходный код всего связанного кода в вашем приложении. Это шоу-стоппер для большинства компаний. С другой стороны, jQuery использует лицензию MIT с высокой разрешающей способностью.
Девданке

1
Разве javascript автоматически не отвечает требованиям открытого исходного кода? Вы предоставляете источник любому, кто просматривает страницу.
PatrickO

10
Существует разница между возможностью просмотра исходного кода и открытого исходного кода, что определяется лицензированием.
Паркер Олт

Спасибо от тех, кто все еще использует ExtJS :-)
Monarch Wadia

1
ты должен был позволить ExtJS покоиться с миром
canbax

19

Мне нравится ваша "единственная идея" просто сделать статическую карту ширины символов! Это на самом деле хорошо работает для моих целей. Иногда по соображениям производительности или из-за того, что у вас нет простого доступа к DOM, вам может понадобиться быстрый взломанный автономный калькулятор, откалиброванный для одного шрифта. Итак, вот один, откалиброванный для Helvetica; передать строку и (необязательно) размер шрифта:

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
}

Этот гигантский уродливый массив имеет ширину символов ASCII, проиндексированную кодом символов. Так что это просто поддерживает ASCII (в противном случае предполагается средняя ширина символа). К счастью, ширина в основном линейно масштабируется в зависимости от размера шрифта, поэтому она отлично работает при любом размере шрифта. Ему явно не хватает понимания кернинга, лигатур или чего-то еще.

Чтобы «откалибровать», я просто визуализировал каждый символ до charCode 126 (могущественная тильда) в SVG, получил ограничивающий прямоугольник и сохранил его в этом массиве; больше кода и объяснений и демо здесь .


1
это умное решение, хорошо :) Я всегда использую один и тот же шрифт / размер, так что он мне подходит. Я считаю, что производительность решений DOM / Canvas - настоящая проблема, это действительно чисто, ура!
mikeapr4

1
устраняет необходимость в холсте +1
фрейм

Вы можете избавиться от * fontSizeи просто использовать их
Мэтт Флетчер

Какой удивительный ответ!
almosnow


7

Вы можете использовать холст, чтобы вам не приходилось иметь дело со свойствами 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;

Разве это не намного тяжелее (с получением 2d-контекста и т. Д.), Чем создание элемента DOM и указание для него свойств CSS?
Pharao2k

1
Это чистый подход, если вы уже используете canvas для чего-то. Но ОЧЕНЬ МЕДЛЕННО. Один только вызов measureText занимает около 8-10 мс (с использованием Chrome).
Руи Маркес

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

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

Это должно работать, пока к тегу <span> не применяются другие стили. offsetWidth будет включать в себя ширину любых границ, горизонтальное заполнение, ширину вертикальной полосы прокрутки и т. д.


Это более или менее то, что делает верхние решения, но так как ваш текст может быть разбит на несколько строк, они добавляют несколько стилей CSS к тексту, чтобы получить реальную полную ширину текста.
Адриан Мэйр

2

Приведенный ниже фрагмент кода «вычисляет» ширину тега span, добавляет к нему «...», если он слишком длинный, и сокращает длину текста до тех пор, пока он не уместится в родительском элементе (или пока он не попытается выполнить более тысячи раз)

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)

// 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
Попробуйте выполнить бинарный поиск вместо зацикливания 1 символа за раз: см. Мой комментарий к ответу Алекса на stackoverflow.com/questions/536814/…
StanleyH

@StanleyH: Хорошая идея - я выполню ваше предложение как можно скорее.
Течек

2

Лучше всего определить, подходит ли текст прямо перед отображением элемента. Таким образом, вы можете использовать эту функцию, которая не требует, чтобы элемент был на экране.

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

Применение:

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

2

На тот случай, если кто-то еще ищет здесь способ измерения ширины строки и способ узнать, какой самый большой размер шрифта будет соответствовать конкретной ширине, вот функция, основанная на решении @ Domi с бинарным поиском. :

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

Это работает удивительно (в сочетании с кодом из ответа Доми)
r3wt

1

Попробуйте этот код:

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

Ширина и высота текста могут быть получены с помощью clientWidthиclientHeight

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

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

убедитесь, что свойство стиля позиции установлено в абсолют

element.style.position = "absolute";

не обязательно должен быть внутри div, может быть внутри pилиspan


1

Основываясь на ответе Дипака Надара , я изменил параметр функций, чтобы принимать стили текста и шрифта. Вам не нужно ссылаться на элемент. Кроме того, fontOptionsесть значения по умолчанию, поэтому вам не нужно поставлять все из них.

(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

Я думаю, что это похоже на запись Депака, но основано на работе Луи Лазариса, опубликованной в статье на странице впечатляющей сети

(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 используется для немедленного выполнения вызова функции после того, как функция связана с элементом управления.

Например: $ ('input'). autofit (). trigger ("fit");


0

Без 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);

когда вы устанавливаете число, это не работает, потому что пробел не нужен, если вы удалите его, он будет работать нормально: fontSize + "px arial" -> fontSize + "px arial", только это.
Альберто Акунья

0

Скрипка рабочего примера: 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:

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()Метод возвращает коллекцию DOMRectобъектов , которые указывают ограничивающие прямоугольники для каждого пограничного поле CSS в клиенте. Возвращаемое значение представляет собой коллекцию DOMRectобъектов, по одному для каждого поля границы CSS, связанного с элементом. Каждый DOMRectобъект содержит только для чтения left, top, rightи bottomсвойства , описывающие форму границы, в пикселях, с левого верхнего по отношению к верхней левой части окна просмотра.

Element.getClientRects () от Mozilla Contributors лицензируется в соответствии с CC-BY-SA 2.5 .

Суммирование всех возвращенных значений ширины прямоугольника дает общую ширину текста в пикселях.

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

Я сделал крошечный модуль ES6 (использует 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();
}

Легко использовать:

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

Крутая вещь, которую вы можете заметить - она ​​позволяет учитывать любые атрибуты CSS, даже отступы!


0

Вы также можете сделать это с помощью createRange, который является более точным, чем метод клонирования текста:

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'));
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.