Вычисление ширины текста

Я пытаюсь вычислить ширину текста с помощью jQuery. Я не уверен, что, но я определенно что-то не так.

Итак, вот код:

var c = $('.calltoaction');

var cTxt = c.text();

var cWidth =  cTxt.outerWidth();

c.css('width' , cWidth);

Ответ 1

Это помогло мне лучше:

$.fn.textWidth = function(){
  var html_org = $(this).html();
  var html_calc = '<span>' + html_org + '</span>';
  $(this).html(html_calc);
  var width = $(this).find('span:first').width();
  $(this).html(html_org);
  return width;
};

Ответ 2

Здесь функция, которая лучше других, потому что

  • короче
  • он работает при передаче <input>, <span> или "string".
  • быстрее для частого использования, поскольку он повторно использует существующий элемент DOM.

Демо: http://jsfiddle.net/philfreo/MqM76/

// Calculate width of text from DOM element or string. By Phil Freo <http://philfreo.com>
$.fn.textWidth = function(text, font) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
    $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
    return $.fn.textWidth.fakeEl.width();
};

Ответ 3

Мое решение

$.fn.textWidth = function(){
    var self = $(this),
        children = self.children(),
        calculator = $('<span style="display: inline-block;" />'),
        width;

    children.wrap(calculator);
    width = children.parent().width(); // parent = the calculator wrapper
    children.unwrap();
    return width;
};

В основном улучшение по сравнению с Rune's, которое не использует .html так легко

Ответ 4

Функции ширины jQuery могут быть немного тенистыми при попытке определить ширину текста из-за несогласованных моделей ящиков. Верным способом было бы ввести div внутри вашего элемента, чтобы определить фактическую ширину текста:

$.fn.textWidth = function(){
  var sensor = $('<div />').css({margin: 0, padding: 0});
  $(this).append(sensor);
  var width = sensor.width();
  sensor.remove();
  return width;
};

Чтобы использовать этот мини-плагин, просто:

$('.calltoaction').textWidth();

Ответ 5

Функции textWidth, предоставленные в ответах и ​​принимающие string в качестве аргумента, не будут учитывать пробелы в верхнем и концевом пробелах (они не отображаются в контейнере-контейнере). Кроме того, они не будут работать, если текст содержит любую разметку html (подстрока <br> не будет выдавать какой-либо вывод, а &nbsp; вернет длину одного пробела).

Это только проблема для функций textWidth, которые принимают string, потому что, если задан элемент DOM, и .html() вызывается для элемента, то, вероятно, нет необходимости исправлять это для таких использование случай.

Но если, например, вы вычисляете ширину текста, чтобы динамически изменять ширину текстового элемента input в качестве типов пользователей (мой текущий вариант использования), вы, вероятно, захотите заменить ведущие и конечные пробелы с &nbsp; и кодировать строку в html.

Я использовал решение philfreo, поэтому вот его версия, которая исправляет это (с комментариями к дополнениям):

$.fn.textWidth = function(text, font) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').appendTo(document.body);
    var htmlText = text || this.val() || this.text();
    htmlText = $.fn.textWidth.fakeEl.text(htmlText).html(); //encode to Html
    htmlText = htmlText.replace(/\s/g, "&nbsp;"); //replace trailing and leading spaces
    $.fn.textWidth.fakeEl.html(htmlText).css('font', font || this.css('font'));
    return $.fn.textWidth.fakeEl.width();
};

Ответ 6

Я нашел, что это решение работает хорошо, и оно наследует исходный шрифт до калибровки:

$.fn.textWidth = function(text){
  var org = $(this)
  var html = $('<span style="postion:absolute;width:auto;left:-9999px">' + (text || org.html()) + '</span>');
  if (!text) {
    html.css("font-family", org.css("font-family"));
    html.css("font-size", org.css("font-size"));
  }
  $('body').append(html);
  var width = html.width();
  html.remove();
  return width;
}

Ответ 7

Ни Rune, ни Brain не работали для меня, если элемент, содержащий текст, имел фиксированную ширину. Я сделал что-то похожее на Окамера. Он использует меньше селекторов.

EDIT: Вероятно, это не работает для элементов, которые используют относительный font-size, поскольку следующий код вставляет htmlCalc элемент в body, таким образом, теряет информацию о отношении родителей.

$.fn.textWidth = function() {
    var htmlCalc = $('<span>' + this.html() + '</span>');
    htmlCalc.css('font-size', this.css('font-size'))
            .hide()
            .prependTo('body');
    var width = htmlCalc.width();
    htmlCalc.remove();
    return width;
};

Ответ 8

Если вы пытаетесь сделать это с текстом в поле выбора или если эти два arent работают, попробуйте это вместо:

$.fn.textWidth = function(){
 var calc = '<span style="display:none">' + $(this).text() + '</span>';
 $('body').append(calc);
 var width = $('body').find('span:last').width();
 $('body').find('span:last').remove();
 return width;
};

или

function textWidth(text){
 var calc = '<span style="display:none">' + text + '</span>';
 $('body').append(calc);
 var width = $('body').find('span:last').width();
 $('body').find('span:last').remove();
 return width;
};

если вы хотите сначала взять текст

Ответ 9

вещь, вы делаете неправильно, что вы вызываете метод на cTxt, который является простой строкой, а не объектом jQuery. cTxt - действительно содержащий текст.

Ответ 10

Незначительное изменение в Nico, так как .children() вернет пустой набор, если мы ссылаемся на текстовый элемент, например h1 или p. Таким образом, мы будем использовать .contents() вместо этого и используем this вместо $(this), так как мы создаем метод для объекта jQuery.

$.fn.textWidth = function(){
    var contents = this.contents(),
        wrapper  = '<span style="display: inline-block;" />',
        width    = '';

    contents.wrapAll(wrapper);
    width = contents.parent().width(); // parent is now the wrapper
    contents.unwrap();
    return width;
    };

Ответ 11

после преследования призрака в течение двух дней, пытаясь понять, почему ширина текста была неправильной, я понял, что это из-за белых пробелов в текстовой строке, которая остановит вычисление ширины.

Итак, еще один совет - проверить, не создают ли проблемы пробелы. используйте

&nbsp;

неразрывное пространство и посмотреть, исправляет ли он это.

другие функции, которые люди предлагали хорошо работать, но это были пробелы, вызывающие проблемы.

Ответ 12

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

* Примечание. Вам также нужно будет расширить jQuery, чтобы добавить функцию unwrapInner(), поскольку она не предоставляется по умолчанию.

$.fn.extend({
  unwrapInner: function(selector) {
      return this.each(function() {
          var t = this,
              c = $(t).children(selector);
          if (c.length === 1) {
              c.contents().appendTo(t);
              c.remove();
          }
      });
  },
  textWidth: function() {
    var self = $(this);
    $(this).wrapInner('<span id="text-width-calc"></span>');
    var width = $(this).find('#text-width-calc').width();
    $(this).unwrapInner();
    return width;
  }
});

Ответ 13

Расширение ответа @philfreo:

Я добавил возможность проверить text-transform, поскольку такие вещи, как text-transform: uppercase, обычно имеют тенденцию расширять текст.

$.fn.textWidth = function (text, font, transform) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
    $.fn.textWidth.fakeEl.text(text || this.val() || this.text())
        .css('font', font || this.css('font'))
        .css('text-transform', transform || this.css('text-transform'));
    return $.fn.textWidth.fakeEl.width();
};

Ответ 14

var calc = '<span style="display:none; margin:0 0 0 -999px">' + $('.move').text() + '</span>';

Ответ 15

Вызовите getColumnWidth(), чтобы получить совпадение текста. Это прекрасно работает.

someFile.css
.columnClass { 
    font-family: Verdana;
    font-size: 11px;
    font-weight: normal;
}


function getColumnWidth(columnClass,text) { 
    tempSpan = $('<span id="tempColumnWidth" class="'+columnClass+'" style="display:none">' + text + '</span>')
          .appendTo($('body'));
    columnWidth = tempSpan.width();
    tempSpan.remove();
return columnWidth;
}

Примечание. - Если вы хотите, чтобы встроенные .css передавали только шрифты в стиле.

Ответ 16

Я изменил код Nico для работы для моих нужд.

$.fn.textWidth = function(){
    var self = $(this),
        children = self.contents(),
        calculator = $('<span style="white-space:nowrap;" />'),
        width;

    children.wrap(calculator);
    width = children.parent().width(); // parent = the calculator wrapper
    children.unwrap();
    return width;
};

Я использую . contents(), поскольку .children() не возвращает текстовые узлы, которые мне нужны. Я также обнаружил, что на возвращаемую ширину повлияла ширина окна просмотра, которая вызывала обертку, поэтому я использую white-space: nowrap; для получения правильной ширины, независимо от ширины видового экрана.

Ответ 17

$.fn.textWidth = function(){
        var w = $('body').append($('<span stlye="display:none;" id="textWidth"/>')).find('#textWidth').html($(this).html()[0]).width();
        $('#textWidth').remove();
        console.log(w);
        return w;
    };

почти один лайнер. Дает вам символ первого символа

Ответ 18

Я не мог заставить ни одно из перечисленных решений работать на 100%, поэтому появился этот гибрид, основанный на идеях от @chmurson (который в свою очередь был основан на @Okamera), а также от @philfreo:

(function ($)
{
    var calc;
    $.fn.textWidth = function ()
    {
        // Only create the dummy element once
        calc = calc || $('<span>').css('font', this.css('font')).css({'font-size': this.css('font-size'), display: 'none', 'white-space': 'nowrap' }).appendTo('body');
        var width = calc.html(this.html()).width();
        // Empty out the content until next time - not needed, but cleaner
        calc.empty();
        return width;
    };
})(jQuery);

Примечания:

  • this внутри метода расширения jQuery уже является объектом jQuery, поэтому нет необходимости во всех дополнительных $(this), которые есть во многих примерах.
  • Он только добавляет фиктивный элемент в тело один раз и повторно использует его.
  • Вы также должны указать white-space: nowrap, чтобы убедиться, что он измеряет его как одну строку (а не перенос строки на основе другого стиля страницы).
  • Я не мог заставить это работать, используя только font и должен был явно скопировать font-size. Не уверен, почему еще (все еще расследуется).
  • Это не поддерживает поля ввода таким образом @philfreo.

Ответ 19

Иногда вам также необходимо дополнительно измерить высоту, а не только текст, но и ширину HTML. Я принял @philfreo ответ и сделал его более гибким и полезным:

function htmlDimensions(html, font) {
  if (!htmlDimensions.dummyEl) {
    htmlDimensions.dummyEl = $('<div>').hide().appendTo(document.body);
  }
  htmlDimensions.dummyEl.html(html).css('font', font);
  return {
    height: htmlDimensions.dummyEl.height(),
    width: htmlDimensions.dummyEl.width()
  };
}

Ответ 20

Я думаю, вы должны использовать $('.calltoaction').val;

также, я бы использовал id (#) вместо класса для этого. Если u имеет более одного из таких классов, как бы он справился с этим?