+1 - to naprawdę mierzy tekst, a nie tylko zawierający element blokowy, taki jak rozwiązanie brainreavis.
Ben
Przysiek. +1. Wygląda na to, że brakuje średnika w trzecim wierszu po '</span>', chociaż nie wydaje się to robić różnicy (działało z nim lub bez niego na FF9).
shmeeps
21
Uważaj jednak ... ta metoda usunie powiązania wszystkich zdarzeń na elementach potomnych.
brianreavis
Próbowałem użyć tej funkcji na wiele sposobów, ale zwraca ona wartość null. Czy ktoś mógłby opublikować składnię opisującą, jak ta funkcja jest faktycznie używana? Czy uruchamiam funkcję .textWidth () na obiekcie jQuery? Czy przekazuję tekst do tej funkcji? Czy uruchamiam tę funkcję jako funkcję jQuery (tj. $ .TextWidth (jqObject)? Ponieważ żadna z tych opcji nie wydaje się działać. Dzięki ...
// 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();};
Świetne rozwiązanie, myślę, że należy przyjąć odpowiedź! Dzięki kolego!
Ilia Rostovtsev
Fantastico! Proste i czyste.
Carey Estes,
Chociaż dobrze, to nie obsługuje spacji. Zobacz odpowiedź @ edsioufi, aby uzyskać informacje na temat ulepszenia tego rozwiązania.
Badgerspot,
Jeśli wewnątrz elementu znajduje się ukryty tekst, spowoduje to odchylenie szerokości. Aby to uwzględnić, pamiętaj o usunięciu ukrytych węzłów przed obliczeniem szerokości tekstu. Aby bezpiecznie usunąć ukryte węzły, prawdopodobnie powinieneś najpierw utworzyć klon i tam usunąć.
Autor: Ajarn Gerhard, który opublikował to jako odpowiedź: To nie działa w IE8, ponieważ brakuje ci /przed nawiasem zamykającym <span>tagu:calculator = $('<span style="display: inline-block;" />'),
Petr R.
1
Wydaje się, że zwraca wartość null, jeśli pod elementem, który mierzysz, znajduje się element potomny. Czy może działać bez elementu podrzędnego? Zobacz jsfiddle.net/h22tj/41
Casper
+1 - Nigdy nie wiedziałem, że było rozpakowanie (), które wywołało u mnie niekończący się smutek.
Orwellophile
W Chrome zawsze zwraca wartość null.
emeraldhieu
12
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();};
Co dziwne, kiedy wypróbowałem ten, nie skopiował poprawnie pliku 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?
Gone Coding,
@GoneCoding Gdzie dodałeś te dodatki?
webmagnets
@webmagnets: To samo miejsce co dotychczasowa .cssmetoda, ale widzę, że moje nawiasy są nieprawidłowe. Powinien być css('font-size', this.css('font-size')).
Gone Coding
11
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:
Czy nie dałoby to raczej szerokości bloku niż tekstu?
Josh Rickard,
-1 To rzeczywiście wydaje się mierzyć szerokość ramki, a nie szerokość tekstu.
Nathan Arthur
1
Czy użycie rozpiętości zamiast elementu div nie rozwiązałoby problemu z szerokością? Jeśli tak, to ta funkcja jest nieco lepsza niż zaakceptowana odpowiedź.
Josh
@Josh: Jeśli zastąpisz to a 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ć?
Gone Coding
8
Okazało się, że to rozwiązanie działa dobrze i dziedziczy czcionkę pochodzenia przed dopasowaniem:
Skończyło się na tym, że użyłem tego, ale dodałem 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.
Urocze
8
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.
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.
Po prostu tymczasowo dodaj white-space: nowrapdo wbudowanego CSS, aby tego uniknąć.
Gone Coding
1
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){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 dla .wrapInner. Jak zapewne wiesz, zajmowanie się czystymi elementami tekstowymi w jQuery to piekło. Jeśli istnieją inne metody jQuery, które mają zastosowanie, daj mi znać. Musiałem uciec się do .get (0) .children i nie jest to ładne.
Orwellophile
1
Rozwinięcie odpowiedzi @ philfreo:
Dodałem możliwość sprawdzania text-transform, ponieważ rzeczy takie jak text-transform: uppercasezwykle powodują, że tekst jest szerszy.
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);
Uwagi:
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.
Dodaje element atrapy do ciała tylko raz i używa go ponownie.
Powinieneś również określić white-space: nowrap, aby upewnić się, że mierzy go jako pojedynczą linię (a nie zawijanie wierszy w oparciu o inne style strony).
Nie mogłem zmusić tego do pracy, używając fontsamego i musiałem również wyraźnie skopiować font-size. Jeszcze nie wiem, dlaczego (nadal badam).
To nie obsługuje pól wejściowych w ten sposób @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ą:
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:
<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;
}
Odpowiedzi:
To działało lepiej dla mnie:
źródło
'</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/
źródło
Moje rozwiązanie
Zasadniczo ulepszenie w stosunku do Rune, które nie działa
.html
tak lekkoźródło
/
przed nawiasem zamykającym<span>
tagu:calculator = $('<span style="display: inline-block;" />'),
Te
textWidth
funkcje przewidziane w odpowiedziach i że akceptująstring
jako 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
textWidth
funkcji, które akceptują astring
, 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ść
input
elementu 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):
źródło
font-size
. Musiałem dodaćcss('font-size'), this.css('font-size'))
, żeby zadziałało. Jakieś pomysły, dlaczegofont
sam nie kopiuje tej wartości?.css
metoda, 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:
Aby użyć tej mini wtyczki, po prostu:
źródło
span
, po prostu otrzymasz zero. Wypróbowałem to rozwiązanie w przypadkuH2
, 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:
źródło
org.css("font-weight")
. Powiedziałbym też, że taif(!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 wstawiahtmlCalc
element do, wbody
ten sposób tracąc informacje o relacji rodziców.źródło
this
jest 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:
lub
jeśli chcesz najpierw pobrać tekst
źródło
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.
źródło
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.
źródło
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.
źródło
white-space: nowrap
do 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.
źródło
Rozwinięcie odpowiedzi @ philfreo:
Dodałem możliwość sprawdzania
text-transform
, ponieważ rzeczy takie jaktext-transform: uppercase
zwykle powodują, że tekst jest szerszy.źródło
źródło
Wywołaj getColumnWidth (), aby uzyskać z tekstu. Działa to doskonale.
Uwaga: - Jeśli chcesz, aby wbudowane pliki .css przekazywały szczegóły czcionki tylko w stylu.
źródło
Zmodyfikowałem kod Nico, aby działał na moje potrzeby.
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.
źródło
prawie jedna wkładka. Daje ci pierwszy znak
źródło
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:
Uwagi:
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).font
samego i musiałem również wyraźnie skopiowaćfont-size
. Jeszcze nie wiem, dlaczego (nadal badam).@philfreo
.źródło
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ą:
źródło
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:
źródło
Miałem problem z rozwiązaniami takimi jak @ rune-kaagaard dla dużych ilości tekstu. Odkryłem to:
JSFiddle GitHub
źródło
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ł?
źródło