JQuery kullanarak metin genişliğini hesaplamaya çalışıyorum. Ne olduğundan emin değilim ama kesinlikle yanlış bir şey yapıyorum.
İşte kod:
var c = $('.calltoaction');
var cTxt = c.text();
var cWidth = cTxt.outerWidth();
c.css('width' , cWidth);
JQuery kullanarak metin genişliğini hesaplamaya çalışıyorum. Ne olduğundan emin değilim ama kesinlikle yanlış bir şey yapıyorum.
İşte kod:
var c = $('.calltoaction');
var cTxt = c.text();
var cWidth = cTxt.outerWidth();
c.css('width' , cWidth);
Yanıtlar:
Bu benim için daha iyi çalıştı:
$.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>'noktalı virgül eksik görünüyor , ancak bir fark yaratmıyor gibi görünüyor (FF9'da onunla veya onsuz çalıştı).
İşte diğerlerinden daha iyi olan bir işlev çünkü
<input>, <span>ya da "string".Demo: 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;
};
Temelde Rune bitti bir gelişme olduğunu kullanmaz .htmlbu yüzden hafifçe
/kapanış parantez önce <span>: tagcalculator = $('<span style="display: inline-block;" />'),
textWidthCevap sağlanır ve işlevleri bir kabul string, boşluk, ön ve arka için hesap değil, bağımsız değişken (o kukla kapta işlenmez) elde edilir. Ayrıca, metin herhangi bir html biçimlendirmesi içeriyorsa çalışmazlar (bir alt dizge <br>herhangi bir çıktı üretmez ve bir boşluk uzunluğunu döndürür).
Bu yalnızca textWidtha'yı kabul eden işlevler için bir sorundur string, çünkü bir DOM öğesi verilmişse ve .html()öğeye çağrılmışsa, bu tür bir kullanım durumu için muhtemelen bunu düzeltmeye gerek yoktur.
Ancak, örneğin, kullanıcı yazarken bir metin inputöğesinin genişliğini dinamik olarak değiştirmek için metnin genişliğini hesaplıyorsanız (benim mevcut kullanım durumum), muhtemelen baştaki ve sondaki boşlukları dizeyle değiştirip kodlamak isteyeceksiniz. html için.
Philfreo'nun çözümünü kullandım, bu yüzden işte bunu düzelten bir sürümü var (eklemelerle ilgili yorumlarla):
$.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'))Çalışması için eklemek zorunda kaldım . Neden fonttek başına bu değeri kopyalamadığına dair bir fikrin var mı?
.cssyöntemle aynı yerde , ancak parantezlerimin yanlış olduğunu görüyorum. Olmalı css('font-size', this.css('font-size')).
Tutarsız kutu modelleri nedeniyle metin genişliğini belirlemeye çalışırken jQuery'nin genişlik işlevleri biraz gölgeli olabilir. Kesin olan yol, gerçek metin genişliğini belirlemek için öğenizin içine div enjekte etmektir:
$.fn.textWidth = function(){
var sensor = $('<div />').css({margin: 0, padding: 0});
$(this).append(sensor);
var width = sensor.width();
sensor.remove();
return width;
};
Bu mini eklentiyi kullanmak için basitçe:
$('.calltoaction').textWidth();
spansadece sıfır elde edersiniz. Bu çözümü, H2üst öğelerin gizlendiği bir yerde denedim ve yalnızca metnin kesilmiş uzunluğunu elde ettim. Belki de bunun nasıl çalışacağına dair bir açıklama daha iyi çalışmasına yardımcı olabilir mi?
Bu çözümün iyi çalıştığını ve boyutlandırmadan önce kaynak yazı tipini miras aldığını buldum:
$.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"). Ayrıca, if(!text)bölümün sezgisel olmadığını söyleyebilirim . Örneğin kullanırsam jQuery("#someContainer").textWidth("Lorem ipsum"), söz konusu konteynere uygulandığında "Lorem ipsum" un metin genişliğini bilmek isterim.
Metni tutan öğenin sabit genişliğe sahip olması durumunda ne Rune ne de Brain benim için çalışmıyordu. Okamera'ya benzer bir şey yaptım. Daha az seçici kullanır.
DÜZENLEME: Muhtemelen göreli kullanan elemanlar için çalışmayacaktır font-size, çünkü aşağıdaki kod htmlCalceleman eklediği bodyiçin ebeveyn ilişkisi hakkındaki bilgileri kaybedecektir.
$.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;
};
thiszaten bir jQuery nesnesi $(this)olduğundan fazlalıktır.
Bunu bir seçim kutusundaki metinle yapmaya çalışıyorsanız veya bu ikisi çalışmıyorsa, bunun yerine şunu deneyin:
$.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;
};
veya
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;
};
önce metni almak istersen
yanlış yapıyorsunuz, basit bir dize olan ve bir jQuery nesnesi olmayan cTxt'de bir yöntem çağırıyorsunuz. cTxt gerçekten içerilen metindir.
.Children (), h1 veya p gibi bir metin öğesine başvuruyorsak boş bir küme döndüreceğinden, Nico'ya küçük bir değişiklik . Onun yerine .contents () kullanacağız ve bunu $ (this) yerine kullanacağız çünkü jQuery nesnesinde bir metot oluşturuyoruz.
$.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;
};
İki gün boyunca bir hayaletin peşinden koşarak, bir metnin genişliğinin neden yanlış olduğunu anlamaya çalıştıktan sonra, metin dizesindeki beyaz boşlukların genişlik hesaplamasını durduracağını fark ettim.
Bu nedenle, başka bir ipucu, boşlukların sorunlara neden olup olmadığını kontrol etmektir. kullanım
bölünmeyen boşluk ve bunun düzeltip düzeltmediğine bakın.
İnsanların önerdiği diğer işlevler de iyi çalışıyordu, ancak sorun yaratan beyaz boşluklardı.
white-space: nowrapkaçınmak için yalnızca geçici olarak satır içi CSS'ye ekleyin .
Belirli bir öğe içindeki metin düğümleri ve öğelerin karışımının genişliğini belirlemeye çalışıyorsanız, tüm içeriği wrapInner () ile sarmalısınız. , genişliği hesaplamanız ve ardından .
* Not: Ayrıca, varsayılan olarak sağlanmadığından, bir wrapsInner () işlevi eklemek için jQuery'yi genişletmeniz gerekecektir.
$.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'nun cevabını genişleterek:
Bu tür text-transformşeyler text-transform: uppercasegenellikle metni daha geniş yapma eğiliminde olduğundan , kontrol etme yeteneği ekledim .
$.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();
};
Metni almak için getColumnWidth () çağırın. Bu gayet iyi çalışıyor.
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;
}
Not: - Satır içi .css'nin font ayrıntılarını yalnızca stilde iletmesini istiyorsanız.
Nico'nun kodunu ihtiyaçlarımı karşılayacak şekilde değiştirdim.
$.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;
};
Kullandığım .contents () Ben gerekli metin düğümleri dönmez .Children olarak (). Ayrıca döndürülen genişliğin, kaydırmaya neden olan görüntü alanı genişliğinden etkilendiğini buldum, bu nedenle beyaz boşluk kullanıyorum: nowrap; görüntü alanı genişliğinden bağımsız olarak doğru genişliği elde etmek için.
% 100 işe yarayacak şekilde listelenen çözümlerden hiçbirini alamadım, bu nedenle , @chmurson'dan (@Okamera'ya dayanıyordu) ve ayrıca @filfreo'dan gelen fikirlere dayanarak bu hibrit ile geldim:
(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 bir jQuery genişletme yönteminin içinde zaten bir jQuery nesnesi olduğundan, tüm fazlalıklara gerek yoktur. $(this) birçok örneğin sahip .white-space: nowrap, tek bir satır olarak ölçüldüğünden emin olmak için de belirtmelisiniz (ve diğer sayfa stiline göre satır kaydırmayı değil).fonttek başıma kullanmak için yapamadım ve açıkça kopyalamak zorunda kaldım font-size. Henüz neden olduğundan emin değilim (hala araştırıyor).@philfreo.Bazen de ayrıca ölçmek için gereken yükseklik ve sadece metin değil, aynı zamanda, HTML genişliği . @Filfreo cevabını aldım ve daha esnek ve kullanışlı hale getirdim:
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()
};
}
metin genişliği farklı ebeveynler için farklı olabilir, örneğin h1 etiketine bir metin eklerseniz, div veya etiketten daha geniş olacaktır, dolayısıyla benim çözümüm şöyle:
<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;
}
Büyük miktarda metin için @ rune-kaagaard's gibi çözümlerle sorun yaşadım. Bunu keşfettim:
$.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;
};
bence kullanmalısın $('.calltoaction').val;
ayrıca, bunun için bir sınıf yerine id (#) kullanırdım .. eğer böyle sınıflardan birden fazlasına sahipseniz, bunu nasıl idare ederdi?