+1 - это действительно измеряет текст, а не только содержащий элемент блока, как решение brainreavis.
Бен
Slick. +1. Похоже, вам не хватает точки с запятой в третьей строке после '</span>', хотя это, похоже, не имеет значения (работает с ней или без нее на FF9).
shmeeps
21
Однако будьте осторожны ... этот метод отвяжет любые события дочерних элементов.
brianreavis 03
Я пытался использовать эту функцию разными способами, но она продолжает возвращать значение null. Может ли кто-нибудь опубликовать синтаксис того, как на самом деле используется эта функция? Могу ли я запустить функцию .textWidth () для объекта jQuery? Могу ли я передать текст в эту функцию? Могу ли я запускать эту функцию как функцию jQuery (например, $ .textWidth (jqObject)? Потому что ни один из этих параметров, похоже, не работает. Спасибо ...
// 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();};
Отличное решение, я думаю, должен быть принят ответ! Спасибо, приятель!
Илья Ростовцев
Фантастико! Просто и чисто.
Кэри Эстес
Это хорошо, но не обрабатывает пробелы. См. Ответ @ edsioufi для улучшения этого решения.
Badgerpot
Если внутри элемента есть скрытый текст, он будет искажать вашу ширину. Чтобы учесть это, не забудьте удалить скрытые узлы перед вычислением ширины текста. Чтобы безопасно удалить скрытые узлы, вам, вероятно, следует сначала создать клон и выполнить удаление там.
Автор Ajarn Gerhard, который разместил это в качестве ответа: Это не работает в IE8, потому что вам не хватает /перед закрывающей скобкой <span>тега:calculator = $('<span style="display: inline-block;" />'),
Петр Р.
1
Кажется, что это возвращает null, если под измеряемым элементом есть дочерний элемент. Можно ли заставить его работать без дочернего элемента? См. Jsfiddle.net/h22tj/41
Casper
+1 - Я никогда не знал, что есть разворачивание (), которое доставило мне бесконечное горе.
Orwellophile
Он всегда возвращает null в Chrome.
emeraldhieu
12
Эти textWidthфункции , предусмотренные в ответах , и которые принимают в stringкачестве аргумента , не будет составлять начальную и конечные пробела (те , которые не отображаются в контейнере фиктивного). Кроме того, они не будут работать, если текст содержит какую-либо разметку html (подстрока <br>не будет производить никакого вывода и вернет длину одного пробела).
Это проблема только для textWidthфункций, которые принимают a string, потому что, если элемент DOM задан и .html()вызывается элементом, то, вероятно, нет необходимости исправлять это для такого варианта использования.
Но если, например, вы вычисляете ширину текста для динамического изменения ширины текстового inputэлемента в зависимости от типов пользователей (мой текущий вариант использования), вы, вероятно, захотите заменить начальные и конечные пробелы на и закодировать строку в 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," ");//replace trailing and leading spaces
$.fn.textWidth.fakeEl.html(htmlText).css('font', font ||this.css('font'));return $.fn.textWidth.fakeEl.width();};
Как ни странно, когда я попробовал этот, он неправильно скопировал font-size. Пришлось добавить, css('font-size'), this.css('font-size'))чтобы он заработал. Любые идеи, почему fontодно не копирует это значение?
Gone Coding
@GoneCoding Где вы добавили эти дополнения?
webmagnets 05
@webmagnets: то же место, что и существующий .cssметод, но я вижу, что мои скобки неправильные. Должно быть css('font-size', this.css('font-size')).
Gone Coding
11
Функции ширины jQuery могут быть немного сомнительными при попытке определить ширину текста из-за несовместимых блочных моделей. Верным способом было бы вставить div внутри вашего элемента, чтобы определить фактическую ширину текста:
-1 Это действительно похоже на измерение ширины поля, а не ширины текста.
Натан Артур
1
Разве простое использование диапазона вместо div не решит проблему ширины? Если да, то эта функция немного лучше принятого ответа.
Джош
@Josh: Если вы замените его на, spanвы просто получите ноль. Пробовал это решение на H2, где у родительских элементов скрыто переполнение, и я получаю только усеченную длину текста. Возможно, объяснение того, как это должно работать , поможет улучшить его работу?
Gone Coding
8
Я обнаружил, что это решение работает хорошо, и оно наследует исходный шрифт перед изменением размера:
В итоге я использовал это, но добавил org.css("font-weight"). Также я бы сказал, что эта if(!text)часть не интуитивно понятна. Если я использую, например, jQuery("#someContainer").textWidth("Lorem ipsum")я хотел бы знать ширину текста «Lorem ipsum» при применении в этом конкретном контейнере.
Sleavely
8
Ни Rune, ни Brain у меня не работали в том случае, если элемент, содержащий текст, имел фиксированную ширину. Я сделал что-то похожее на Окамеру. Он использует меньше селекторов.
РЕДАКТИРОВАТЬ: это, вероятно, не сработает для элементов, которые используют относительные font-size, поскольку следующий код вставляет htmlCalcэлемент в, bodyтаким образом, теряет информацию о родительских отношениях.
дело в том, что вы делаете неправильно, что вы вызываете метод cTxt, который представляет собой простую строку, а не объект jQuery. cTxt - это действительно содержащийся текст.
Небольшое изменение для Нико, поскольку .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;};
после двух дней погони за призраком, пытаясь понять, почему ширина текста была неправильной, я понял, что это было из-за пробелов в текстовой строке, которые остановили вычисление ширины.
Итак, еще один совет - проверить, не вызывают ли пробелы проблемы. использовать
неразрывное пространство и посмотрите, исправит ли это его.
другие функции, которые люди предлагали, тоже работают хорошо, но проблемы вызывают пробелы.
Просто временно добавьте white-space: nowrapвстроенный CSS, чтобы избежать этого.
Gone Coding
1
Если вы пытаетесь определить ширину комбинации текстовых узлов и элементов внутри данного элемента, вам необходимо обернуть все содержимое с помощью wrapInner () , вычислить ширину, а затем развернуть содержимое.
* Примечание. Вам также потребуется расширить jQuery, чтобы добавить функцию unwrapInner (), поскольку она не предоставляется по умолчанию.
$.fn.extend({
unwrapInner:function(selector){returnthis.each(function(){var t =this,
c = $(t).children(selector);if(c.length ===1){
c.contents().appendTo(t);
c.remove();}});},
textWidth:function(){varself= $(this);
$(this).wrapInner('<span id="text-width-calc"></span>');var width = $(this).find('#text-width-calc').width();
$(this).unwrapInner();return width;}});
+1 за .wrapInner. Как вы, наверное, знаете, работать с чистыми текстовыми элементами в jQuery - ад. Если есть какие-либо другие подходящие методы jQuery, сообщите мне. Мне пришлось прибегнуть к .get (0) .children, и это некрасиво.
Orwellophile
1
Расширение ответа @ philfreo:
Я добавил возможность проверки text-transform, так как такие вещи text-transform: uppercaseобычно делают текст шире.
Я использую .contents (), поскольку .children () не возвращает текстовые узлы, которые мне нужны. Я также обнаружил, что на возвращаемую ширину влияет ширина области просмотра, которая вызвала перенос, поэтому я использую white-space: nowrap; чтобы получить правильную ширину независимо от ширины области просмотра.
Я не смог заставить ни одно из перечисленных решений работать на 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.
ширина текста может быть разной для разных родителей, например, если вы добавляете текст в тег h1, он будет шире, чем div или label, поэтому мое решение вроде этого:
<h1id="header1"></h1>
alert(calcTextWidth("bir iki", $("#header1")));
function calcTextWidth(text, parentElem){
var Elem = $("<label></label>").css("display", "none").text(text);
parentElem.append(Elem);
var width = Elem.width();
Elem.remove();
return width;
}
Ответы:
У меня это сработало лучше:
источник
'</span>'
, хотя это, похоже, не имеет значения (работает с ней или без нее на FF9).Вот функция, которая лучше, чем другие опубликованные, потому что
<input>
,<span>
или"string"
.Демо: http://jsfiddle.net/philfreo/MqM76/
источник
Мое решение
По сути, улучшение по сравнению с Рунами, которое не
.html
так легко использоватьисточник
/
перед закрывающей скобкой<span>
тега:calculator = $('<span style="display: inline-block;" />'),
Эти
textWidth
функции , предусмотренные в ответах , и которые принимают вstring
качестве аргумента , не будет составлять начальную и конечные пробела (те , которые не отображаются в контейнере фиктивного). Кроме того, они не будут работать, если текст содержит какую-либо разметку html (подстрока<br>
не будет производить никакого вывода и
вернет длину одного пробела).Это проблема только для
textWidth
функций, которые принимают astring
, потому что, если элемент DOM задан и.html()
вызывается элементом, то, вероятно, нет необходимости исправлять это для такого варианта использования.Но если, например, вы вычисляете ширину текста для динамического изменения ширины текстового
input
элемента в зависимости от типов пользователей (мой текущий вариант использования), вы, вероятно, захотите заменить начальные и конечные пробелы на
и закодировать строку в html.Я использовал решение philfreo, поэтому вот его версия, которая это исправляет (с комментариями к дополнениям):
источник
font-size
. Пришлось добавить,css('font-size'), this.css('font-size'))
чтобы он заработал. Любые идеи, почемуfont
одно не копирует это значение?.css
метод, но я вижу, что мои скобки неправильные. Должно бытьcss('font-size', this.css('font-size'))
.Функции ширины jQuery могут быть немного сомнительными при попытке определить ширину текста из-за несовместимых блочных моделей. Верным способом было бы вставить div внутри вашего элемента, чтобы определить фактическую ширину текста:
Чтобы использовать этот мини-плагин, просто:
источник
span
вы просто получите ноль. Пробовал это решение наH2
, где у родительских элементов скрыто переполнение, и я получаю только усеченную длину текста. Возможно, объяснение того, как это должно работать , поможет улучшить его работу?Я обнаружил, что это решение работает хорошо, и оно наследует исходный шрифт перед изменением размера:
источник
org.css("font-weight")
. Также я бы сказал, что этаif(!text)
часть не интуитивно понятна. Если я использую, например,jQuery("#someContainer").textWidth("Lorem ipsum")
я хотел бы знать ширину текста «Lorem ipsum» при применении в этом конкретном контейнере.Ни Rune, ни Brain у меня не работали в том случае, если элемент, содержащий текст, имел фиксированную ширину. Я сделал что-то похожее на Окамеру. Он использует меньше селекторов.
РЕДАКТИРОВАТЬ: это, вероятно, не сработает для элементов, которые используют относительные
font-size
, поскольку следующий код вставляетhtmlCalc
элемент в,body
таким образом, теряет информацию о родительских отношениях.источник
this
уже является объектом jQuery, поэтому$(this)
он избыточен.Если вы пытаетесь сделать это с текстом в поле выбора или если эти два не работают, попробуйте это вместо этого:
или
если вы хотите сначала схватить текст
источник
дело в том, что вы делаете неправильно, что вы вызываете метод cTxt, который представляет собой простую строку, а не объект jQuery. cTxt - это действительно содержащийся текст.
источник
Небольшое изменение для Нико, поскольку .children () вернет пустой набор, если мы ссылаемся на текстовый элемент, такой как h1 или p . Поэтому мы будем использовать .contents () вместо этого и использовать this вместо $ (this), поскольку мы создаем метод для объекта jQuery.
источник
после двух дней погони за призраком, пытаясь понять, почему ширина текста была неправильной, я понял, что это было из-за пробелов в текстовой строке, которые остановили вычисление ширины.
Итак, еще один совет - проверить, не вызывают ли пробелы проблемы. использовать
неразрывное пространство и посмотрите, исправит ли это его.
другие функции, которые люди предлагали, тоже работают хорошо, но проблемы вызывают пробелы.
источник
white-space: nowrap
встроенный CSS, чтобы избежать этого.Если вы пытаетесь определить ширину комбинации текстовых узлов и элементов внутри данного элемента, вам необходимо обернуть все содержимое с помощью wrapInner () , вычислить ширину, а затем развернуть содержимое.
* Примечание. Вам также потребуется расширить jQuery, чтобы добавить функцию unwrapInner (), поскольку она не предоставляется по умолчанию.
источник
Расширение ответа @ philfreo:
Я добавил возможность проверки
text-transform
, так как такие вещиtext-transform: uppercase
обычно делают текст шире.источник
источник
Вызовите getColumnWidth (), чтобы получить содержание текста. Это прекрасно работает.
Примечание: - Если вы хотите, чтобы встроенный .css передавал детали шрифта только в стиле.
источник
Я изменил код Нико для своих нужд.
Я использую .contents (), поскольку .children () не возвращает текстовые узлы, которые мне нужны. Я также обнаружил, что на возвращаемую ширину влияет ширина области просмотра, которая вызвала перенос, поэтому я использую white-space: nowrap; чтобы получить правильную ширину независимо от ширины области просмотра.
источник
почти один лайнер. Дает вам знак первого символа
источник
Я не смог заставить ни одно из перечисленных решений работать на 100%, поэтому придумал этот гибрид , основанный на идеях от @chmurson (который, в свою очередь, был основан на @Okamera), а также от @philfreo:
Ноты:
this
внутри метода расширения jQuery уже есть объект jQuery, поэтому нет необходимости во всех дополнительных$(this)
которые есть во многих примерах.white-space: nowrap
, чтобы убедиться, что он измеряется как одна строка (а не перенос строки на основе других стилей страницы).font
один, и мне также пришлось явно копироватьfont-size
. Пока не уверен, почему (все еще исследую).@philfreo
.источник
Иногда нужно дополнительно измерить высоту и не только текст , но и ширину HTML . Я взял ответ @philfreo и сделал его более гибким и полезным:
источник
ширина текста может быть разной для разных родителей, например, если вы добавляете текст в тег h1, он будет шире, чем div или label, поэтому мое решение вроде этого:
источник
У меня были проблемы с решениями типа @ rune-kaagaard для больших объемов текста. Я обнаружил это:
JSFiddle GitHub
источник
я думаю, тебе стоит использовать
$('.calltoaction').val;
Кроме того, я бы использовал id (#) вместо класса для этого ... если у вас есть несколько таких классов, как бы он с этим справился?
источник