Я пытаюсь вычислить ширину текста с помощью jQuery. Я не уверен, что, но я определенно что-то не так.
Итак, вот код:
var c = $('.calltoaction');
var cTxt = c.text();
var cWidth = cTxt.outerWidth();
c.css('width' , cWidth);
Я пытаюсь вычислить ширину текста с помощью jQuery. Я не уверен, что, но я определенно что-то не так.
Итак, вот код:
var c = $('.calltoaction');
var cTxt = c.text();
var cWidth = cTxt.outerWidth();
c.css('width' , cWidth);
Это помогло мне лучше:
$.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;
};
Здесь функция, которая лучше других, потому что
<input>
, <span>
или "string"
.Демо: 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();
};
$.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
так легко
Функции ширины 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();
Функции textWidth
, предоставленные в ответах и принимающие string
в качестве аргумента, не будут учитывать пробелы в верхнем и концевом пробелах (они не отображаются в контейнере-контейнере). Кроме того, они не будут работать, если текст содержит любую разметку html (подстрока <br>
не будет выдавать какой-либо вывод, а
вернет длину одного пробела).
Это только проблема для функций textWidth
, которые принимают 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();
};
Я нашел, что это решение работает хорошо, и оно наследует исходный шрифт до калибровки:
$.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;
}
Ни 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;
};
Если вы пытаетесь сделать это с текстом в поле выбора или если эти два 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;
};
если вы хотите сначала взять текст
вещь, вы делаете неправильно, что вы вызываете метод на cTxt, который является простой строкой, а не объектом jQuery. cTxt - действительно содержащий текст.
Незначительное изменение в 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;
};
после преследования призрака в течение двух дней, пытаясь понять, почему ширина текста была неправильной, я понял, что это из-за белых пробелов в текстовой строке, которая остановит вычисление ширины.
Итак, еще один совет - проверить, не создают ли проблемы пробелы. используйте
неразрывное пространство и посмотреть, исправляет ли он это.
другие функции, которые люди предлагали хорошо работать, но это были пробелы, вызывающие проблемы.
Если вы пытаетесь определить ширину сочетания текстовых узлов и элементов внутри данного элемента, вам необходимо обернуть все содержимое 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;
}
});
Расширение ответа @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();
};
var calc = '<span style="display:none; margin:0 0 0 -999px">' + $('.move').text() + '</span>';
Вызовите 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 передавали только шрифты в стиле.
Я изменил код 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; для получения правильной ширины, независимо от ширины видового экрана.
$.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;
};
почти один лайнер. Дает вам символ первого символа
Я не мог заставить ни одно из перечисленных решений работать на 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
.Иногда вам также необходимо дополнительно измерить высоту, а не только текст, но и ширину 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()
};
}
Я думаю, вы должны использовать $('.calltoaction').val;
также, я бы использовал id (#) вместо класса для этого. Если u имеет более одного из таких классов, как бы он справился с этим?