Я намагаюся обчислити ширину тексту за допомогою 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;
};
'</span>'напівкрапки, хоча це, здається, не має значення (працювали з FF9 або без нього).
Ось функція, яка краще, ніж інші, опубліковані, оскільки
<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;
};
В основному, це поліпшення в порівнянні з руною, яке не .htmlтак легко використовується
/перед кінцевою дужкою <span>тегу:calculator = $('<span style="display: inline-block;" />'),
Ці 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один не скопіював це значення?
.cssметоді, але я бачу, що мої дужки неправильні. Повинно бути css('font-size', this.css('font-size')).
Функції ширини 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();
spanви просто отримаєте нуль. Спробував це рішення на тему H2, де батьківські елементи приховують переповнення, і я отримую лише усічену довжину тексту. Можливо, пояснення того, як це повинно працювати , допоможе зробити його краще?
Я виявив, що це рішення працює добре, і він успадковує початковий шрифт перед розміром:
$.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;
}
org.css("font-weight"). Також я б сказав, що if(!text)частина неінтуїтивна. Якщо я використовую, наприклад, jQuery("#someContainer").textWidth("Lorem ipsum")я хотів би знати ширину тексту "Lorem ipsum" при застосуванні до цього конкретного контейнера.
Ні Руна, ні Мозок не працювали на мене в тому випадку, коли елемент, який тримав текст, мав фіксовану ширину. Я зробив щось подібне до Окамери. Тут використовується менше селекторів.
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;
};
thisвже є об’єктом jQuery, тому він $(this)є надмірним.
Якщо ви намагаєтеся зробити це з текстом у вікні вибору або якщо ці два не працюють, спробуйте це замість цього:
$.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 насправді міститься в тексті.
Трохи перейдіть до Ніко, оскільки .children () поверне порожній набір, якщо ми посилаємося на текстовий елемент, як h1 або p . Отже, ми будемо використовувати .contents () замість цього, а використовуватимемо це замість $ (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, щоб уникнути цього.
Якщо ви намагаєтеся визначити ширину поєднання текстових вузлів та елементів всередині певного елемента, вам потрібно обернути весь вміст wrapInner () , обчислити ширину, а потім розгорнути вміст.
* Примітка: Вам також потрібно буде розширити jQuery, щоб додати функцію unrapInner (), оскільки вона не надається за замовчуванням.
$.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();
};
Зателефонуйте 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, передайте деталі шрифту лише у стилі.
Я змінив код Ніко, щоб він працював на мої потреби.
$.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 () не повертає текстові вузли, які мені були потрібні. Я також виявив, що на повернуту ширину впливала ширина вікна перегляду, яка викликала обгортання, тому я використовую пробіл: 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.Іноді також потрібно додатково виміряти висоту і не тільки текст , але і ширину 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()
};
}
Ширина тексту може бути різною для різних батьків, наприклад, якщо ви додасте текст у тег h1, він буде ширшим, ніж div або label, тому моє рішення, як це:
<h1 id="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;
}
У мене виникли проблеми з такими рішеннями, як @ rune-kaagaard's, для великої кількості тексту. Я виявив це:
$.fn.textWidth = function() {
var width = 0;
var calc = '<span style="display: block; width: 100%; overflow-y: scroll; white-space: nowrap;" class="textwidth"><span>' + $(this).html() + '</span></span>';
$('body').append(calc);
var last = $('body').find('span.textwidth:last');
if (last) {
var lastcontent = last.find('span');
width = lastcontent.width();
last.remove();
}
return width;
};
я думаю, ви повинні використовувати $('.calltoaction').val;
Крім того, я б використовував id (#) замість класу для цього .. якщо у вас є більше одного з таких класів, як би це обробити?