Próbuję obliczyć szerokość tekstu za pomocą jQuery. Nie wiem co, ale zdecydowanie robię coś złego.
Oto kod:
var c = $('.calltoaction');
var cTxt = c.text();
var cWidth = cTxt.outerWidth();
c.css('width' , cWidth);
Próbuję obliczyć szerokość tekstu za pomocą jQuery. Nie wiem co, ale zdecydowanie robię coś złego.
Oto kod:
var c = $('.calltoaction');
var cTxt = c.text();
var cWidth = cTxt.outerWidth();
c.css('width' , cWidth);
Odpowiedzi:
To działało lepiej dla mnie:
$.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>', chociaż nie wydaje się to robić różnicy (działało z nim lub bez niego na FF9).
Oto funkcja, która jest lepsza niż inne opublikowane, ponieważ
<input>, <span>lub "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;
};
Zasadniczo ulepszenie w stosunku do Rune, które nie działa .htmltak lekko
/przed nawiasem zamykającym <span>tagu:calculator = $('<span style="display: inline-block;" />'),
Te textWidthfunkcje przewidziane w odpowiedziach i że akceptują stringjako argument nie będą stanowić dla początkowych i końcowych spacji (te, które nie są świadczone w pojemniku manekina). Ponadto nie będą działać, jeśli tekst zawiera jakiekolwiek znaczniki HTML (podłańcuch <br>nie wygeneruje żadnych danych wyjściowych i zwróci długość jednej spacji).
Jest to problem tylko dla textWidthfunkcji, które akceptują a string, ponieważ jeśli podano element DOM i .html()jest on wywoływany dla elementu, to prawdopodobnie nie ma potrzeby naprawiania tego w takim przypadku użycia.
Ale jeśli, na przykład, obliczasz szerokość tekstu, aby dynamicznie modyfikować szerokość inputelementu tekstowego w trakcie pisania przez użytkownika (mój obecny przypadek użycia), prawdopodobnie będziesz chciał zamienić spacje wiodące i końcowe na i zakodować ciąg do html.
Użyłem rozwiązania philfreo, więc tutaj jest wersja, która rozwiązuje ten problem (z komentarzami do dodatków):
$.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. Musiałem dodać css('font-size'), this.css('font-size')), żeby zadziałało. Jakieś pomysły, dlaczego fontsam nie kopiuje tej wartości?
.cssmetoda, ale widzę, że moje nawiasy są nieprawidłowe. Powinien być css('font-size', this.css('font-size')).
Funkcje szerokości jQuery mogą być nieco niewyraźne podczas próby określenia szerokości tekstu z powodu niespójnych modeli ramek. Pewnym sposobem byłoby wstrzyknięcie div wewnątrz elementu, aby określić rzeczywistą szerokość tekstu:
$.fn.textWidth = function(){
var sensor = $('<div />').css({margin: 0, padding: 0});
$(this).append(sensor);
var width = sensor.width();
sensor.remove();
return width;
};
Aby użyć tej mini wtyczki, po prostu:
$('.calltoaction').textWidth();
span, po prostu otrzymasz zero. Wypróbowałem to rozwiązanie w przypadku H2, gdy elementy nadrzędne mają ukryte przepełnienia i otrzymuję tylko obciętą długość tekstu. Być może wyjaśnienie, jak to ma działać , pomogłoby to poprawić?
Okazało się, że to rozwiązanie działa dobrze i dziedziczy czcionkę pochodzenia przed dopasowaniem:
$.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"). Powiedziałbym też, że ta if(!text)część jest nieintuicyjna. Gdybym użył np. jQuery("#someContainer").textWidth("Lorem ipsum")Chciałbym poznać szerokość tekstu "Lorem ipsum" po zastosowaniu w tym konkretnym kontenerze.
Ani Rune, ani Brain nie działały dla mnie w przypadku, gdy element trzymający tekst miał stałą szerokość. Zrobiłem coś podobnego do Okamera. Używa mniej selektorów.
EDYCJA: Prawdopodobnie nie zadziała dla elementów, które używają względnych font-size, ponieważ poniższy kod wstawia htmlCalcelement do, w bodyten sposób tracąc informacje o relacji rodziców.
$.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;
};
thisjest już obiektem jQuery, więc $(this)jest nadmiarowy.
Jeśli próbujesz to zrobić z tekstem w polu wyboru lub jeśli te dwa nie działają, spróbuj zamiast tego:
$.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;
};
lub
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;
};
jeśli chcesz najpierw pobrać tekst
chodzi o to, że robisz źle, że wywołujesz metodę na cTxt, która jest prostym ciągiem znaków, a nie obiektem jQuery. cTxt to naprawdę zawarty tekst.
Niewielka zmiana na wartość Nico, ponieważ .children () zwróci pusty zestaw, jeśli odwołujemy się do elementu tekstowego, takiego jak h1 lub p . Więc zamiast tego użyjemy .contents () i tego zamiast $ (this), ponieważ tworzymy metodę na obiekcie 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;
};
po dwóch dniach ścigania ducha, próbując dowiedzieć się, dlaczego szerokość tekstu jest nieprawidłowa, zdałem sobie sprawę, że jest to spowodowane białymi spacjami w ciągu tekstowym, które zatrzymywały obliczanie szerokości.
więc kolejną wskazówką jest sprawdzenie, czy spacje powodują problemy. posługiwać się
nie działającą przestrzeń i zobacz, czy to naprawi.
inne funkcje, które ludzie sugerowali, również działają dobrze, ale to były białe spacje powodujące problemy.
white-space: nowrapdo wbudowanego CSS, aby tego uniknąć.
Jeśli próbujesz określić szerokość kombinacji węzłów tekstowych i elementów wewnątrz danego elementu, musisz zawinąć całą zawartość metodą wrapInner () , obliczyć szerokość, a następnie rozpakować zawartość.
* Uwaga: Będziesz także musiał rozszerzyć jQuery, aby dodać funkcję unrapInner (), ponieważ nie jest ona dostarczana domyślnie.
$.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;
}
});
Rozwinięcie odpowiedzi @ philfreo:
Dodałem możliwość sprawdzania text-transform, ponieważ rzeczy takie jak text-transform: uppercasezwykle powodują, że tekst jest szerszy.
$.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();
};
Wywołaj getColumnWidth (), aby uzyskać z tekstu. Działa to doskonale.
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;
}
Uwaga: - Jeśli chcesz, aby wbudowane pliki .css przekazywały szczegóły czcionki tylko w stylu.
Zmodyfikowałem kod Nico, aby działał na moje potrzeby.
$.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;
};
Używam .contents (), ponieważ .children () nie zwraca węzłów tekstowych, których potrzebowałem. Odkryłem również, że na zwróconą szerokość wpłynęła szerokość widocznego obszaru, która powodowała zawijanie, więc używam białych znaków: nowrap; aby uzyskać prawidłową szerokość niezależnie od szerokości rzutni.
Nie mogłem sprawić, aby żadne z wymienionych rozwiązań działało w 100%, więc wymyśliłem tę hybrydę , opartą na pomysłach z @chmurson (który z kolei był oparty na @Okamera), a także z @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 wewnątrz metody rozszerzenia jQuery znajduje się już obiekt jQuery, więc nie ma potrzeby stosowania wszystkich dodatkowych $(this) które ma wiele przykładów.white-space: nowrap, aby upewnić się, że mierzy go jako pojedynczą linię (a nie zawijanie wierszy w oparciu o inne style strony).fontsamego i musiałem również wyraźnie skopiować font-size. Jeszcze nie wiem, dlaczego (nadal badam).@philfreo.Czasami trzeba również zmierzyć dodatkowo wysokość i nie tylko tekst , ale także szerokość HTML . Wziąłem odpowiedź @philfreo i uczyniłem ją bardziej elastyczną i użyteczną:
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()
};
}
szerokość tekstu może być różna dla różnych rodziców, na przykład jeśli dodasz tekst do tagu h1, będzie szerszy niż div lub label, więc moje rozwiązanie wygląda następująco:
<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;
}
Miałem problem z rozwiązaniami takimi jak @ rune-kaagaard dla dużych ilości tekstu. Odkryłem to:
$.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;
};
myślę, że powinieneś użyć $('.calltoaction').val;
również użyłbym do tego id (#) zamiast klasy .. jeśli masz więcej niż jedną z takich klas, jak by sobie z tym poradził?