Automatická výška prvku textarea podle textu - javascript

Během práce na nové verzi administrace jsem se dostal k problému - jak nastavit prvku textarea, aby dynamicky měnil velikost podle toho, co do něj píšu? Nejdřív mi to přišlo jako oříšek, ale ve finále jsem udělal/našel celkem 3 způsoby. Vyberte si sami :-)

Metoda 1:

Nejdřív mě nenapadl lepší způsob, než parsovat celý text po jednom znaku a ověřovat, jestli se daný znak nerovná \n nebo jestli již se počet znaků v řádku nerovná velikosti cols. Docela to fungovalo až na to, že je zapotřebí mít v textarea font, který má všechny znaky stejně široké (např.: Courier New). Další problém nastává u zalamování, v případě, že skript zjistí, že počet znaků = počtu cols, najde první mezeru od konce řádku a odsud počítá nový řádek. To ale bohužel neplatí vždy. Každý prohlížeč zalamuje podle jiných kriterií a tak by nakonec, z toho zatím snadného kódu byl script, hoden vlastního souboru, jak by byl dlouhý.

Výhody:
+ správně počítá řádky, za předpokladu, že nebude zalamováno jinak než mezerou

Nevýhody:
- nedořešené zalamování podle jiných znaků než mezer
- není možno použít libovolný font
- poměrně velká zátěž kvůli cyklení (samozřejmě že nový počítač to zvládne tak rychle, že si toho ani nevšimnete, ale na starších strojích by se to mohlo podepsat)

Metoda 1
radku=1;
cols=0;
        
for(var i2=0; textarea.value.length > i2; )
{
       if(textarea.cols>=cols)
       {
            cols++;
            if(textarea.value.charAt(i2)=='\n')
            {
                  radku++;
                  cols=0;
            }
            i2++;
       }
       else
       {
            i3=i2;
            while(textarea.value.charAt(i3)!=' ')
            {
                  i3--;
            }
            i2-=(i2-i3);
            cols=0;
            radku++;
       }
}
textarea.rows = radku;

Metoda 2:

automaticka-vyska-prvku-textarea-podle-textu---javascriptNa zbylé metody mě přivedla diskuze na serveru jakpsatweb.cz, zde byla hlavní myšlenka kopírovat text z textarey do nějakého schovaného divu se stejnými parametry jako textarea, stejný font, stejná šířka a umístění takové, aby to uživatel neviděl, tzn. v mém případě, kde textarea nemá viditelné pozadí (takže umístit div pod ní neni možné), tak někam daleko za hranice vidění. Takže opět na onclick(), onkeypress(), onkeyup() u textarey navolit funkci, která při každém spuštění zkopíruje text do divu, a spočte pomocí offsetHeight jeho výšku, takovou pak nastaví i textaree. Zde žádný podstatný problem nevzniká, dle mého je to nejlepší metoda z těch co jsou zde uvedeny.

Výhody:
+ správně počítá řádky
+ libovolný font
+ mnohem menší zátěž než metoda 1

Nevýhody:
- o žádných nevím

Metoda 2
var text = textarea.value;
text = text.replace(/  /g,"  ");
text = text.replace(/\n/g,"
 "); document.getElementById("odkladny-textarea").innerHTML = text + "
"; var vyska=document.getElementById("odkladny-textarea").offsetHeight; if(text == "" || vyska < 18) {       textarea.style.height = "18px"; } else {       vyska+=2;       textarea.style.height = vyska + "px"; }

Metoda 3:

Tato metoda také nepracuje s cols a rows, ale také určuje výšku, tentokrát však podle výšky scrollu. Na pochopení je úplně nejsnazší, na úspornost kódu také, ale tento dokonalý způsob má také chybičku. V případě, že máte textareu mimo základní část (příklad, výška display: 800px, výška webu 2000px, textarea se nachází od 1200-1400px), tak při každém spuštění tohoto kódu, se vám pozice vyresetuje na počáteční hodnotu - 0. Problém by byl řešitelný pomocí zjištění pozice scrollu před započetím fce a jeho určení po dokončení. Dále by bylo zapotřebí nějak zjišťovat, jestli řádka, do které uživatel píše, není na konci stránky, protože pak by mu sice scroll nelítal, ale jakmile by napsal další řádku, už by ji neviděl, dokud by si ručně nezarolloval dolu.

Výhody:
+ správně počítá řádky
+ libovolný font
+ nezatěžuje

Nevýhody:
- problémy se scrollem

Metoda 3
textarea.style.height = 0;
textarea.style.height = textarea.scrollHeight + 4 + "px";

Když se zpětně podíváte na délky jednotlivých kódů, dalo by se říci - zlatá střední cesta. Osobně doporučuji ten druhý, jelikož není ani složitý na zpracování a funguje jak má. Nebo si můžete pohrát a dopsat chybějící části 3. metody, které by obstarávali správné pozicování scrollbaru, ale podle mě je to zbytečné, když jsou i jiné, lépe funkční metody.

Komentáře

Nick Příspěvek *
Email
Webové stránky
12 + 15 =
SuGi | MAIL | WEB19:52 07.10.2010
Poznatky co jsem získal po delší době jsem sem již nenapsal. Ve finále používám místo divu table, přišlo mi to lepší s ohledem na zalamování, jelikož počítání používám pouze na textareu s wrap="soft". A samozřejmě mam tuto tabulku s css visibility:hidden přímo vlevo nahoře :-). Zatím půl roku testu v praxi a vše funguje jak má.
Vlasec | MAIL | WEB23:36 06.10.2010
Použil jsem druhou metodu. Výsledek potřebuji k jiným účelům - zjišťuju, jak vysoké to bude coby hotový příspěvek. Proto do DIVu přidávám například obrázky daných rozměrů místo smajlíků. Myslím, že myšlenka "skrytý div" možná znamenal, že visibility:hidden. Je to určitě lepší řešení, než umístit DIV někam hodně daleko. V tom případě bych ale doporučoval do mínusových souřadnic, nezobrazí se scrollbar. Metoda 3 zní zajímavě a možná ji někdy trochu prozkoumám.

Created & Designed by © SuGi 2007-2011 | PWRD BY Veriana (2.0.1450)
Provozovatel nenese žádnou zodpovědnost za škody způsobené používáním tohoto webu