Dinamikus textarea
Sziasztok!
Adott egy textarea elem, melynek 1 sora van.
Ha a felhasználó beír egy karaktert az elembe, akkor meghívódik egy függvény.
Ha a karakter ENTER, akkor a feltétel teljesül.
1) kérdés: Hogyan tudnám azt megoldani, hogy az ENTER leütésével egy sorral nagyobb legyen a <textarea> magassága?
2) kérdés: Hogyan tudnám lekérdezni, hogy a fókusz még mindig rajta van-e az elemen?
Eddigi:
■ Adott egy textarea elem, melynek 1 sora van.
Ha a felhasználó beír egy karaktert az elembe, akkor meghívódik egy függvény.
Ha a karakter ENTER, akkor a feltétel teljesül.
1) kérdés: Hogyan tudnám azt megoldani, hogy az ENTER leütésével egy sorral nagyobb legyen a <textarea> magassága?
2) kérdés: Hogyan tudnám lekérdezni, hogy a fókusz még mindig rajta van-e az elemen?
Eddigi:
<textarea id="uzenet" rows="3" cols="20" onKeyPress="sor(event, 'uzenet');">
function sor(e, id)
{
if(e.which == 26)
{
document.getElementById(id).rows = document.getElementById(id).rows + 1;
}
}
Dokumentáció
2, nézd meg, hogy a textarea elemnek milyen eseményei vannak, abból ki tudod találni
Az 1-es elképzelésed egyébként nem teljes, mert nem csak enter leütésével lehet sortörést bevinni.
Fél siker
setAttribute függvény lesz a barátod
Ha már mindenképpen ezzel az
Én azt tanácsolnám, felejtsd
Manapság csak azért találkozni még mindig velük, mert sok ősrégi tutorial még ezeket tanítja.
Javaslom az addEventListener tanulmányozását és a mielőbbi átállást.
A rowsnak meg működnie kéne, gyorsan összedobtam egy kis demót.
A válasz
A válaszolóknak pedig köszönöm, a tanácsaikat pedig megjegyzem! :)
<textarea rows="1"
Anno valamelyik népszerű
Ez arra szolgált, hogy lemásolja a textarea-t, viszont itt nincs overflow és automatikusan növekszik a magassága, ahogyan új sorok kerülnek bele.
A divet a viewportból kimozgattam, hogy ne látszódjon.
Tetszőlegesen definiált event (keyup, change) esetén a textarea tartalmát a div-be kell másolni, majd lemérni a div magasságát, amit utána beállítani a textarea-ra.
Ha esetleg valakinek jól
Ui.: Csak az egyszerűség kedvéért írtam ilyen szájbarágósan
Az inline onkeydown-ért
Nem nagy fejtörő, de direkt
Akkor
Nem értem. Ez miért indokolja
Méret visszacsökkentése
keydown
eseményen kívül pedig sok egyebet is kezel azinput
event, valamint érdemes a kézi méretezés lehetőségét letiltani. Az alábbi kódminta alapján dinamikusan méreteződő textarea-k gyárthatóak – a használt eseménykezeléshez jQuery plugin szükséges.height()
függvényét használjuk, mert az számításba veszi a padding-et és a border-t is. (Ennek hiányában előfordulhatna, hogy nem lesz elég magas az elem, és megjelenik a gördítősáv.) Ez megkerülhető abox-sizing
,border
éspadding
CSS-tulajdonságok figyelembevételével.overflow
ideiglenes átállítására azért van szükség, mert 0 magasság esetén megjelenne a gördítősáv, emiatt már akkor magasságnövelést érezne szükségesnek a kód, amikor még van néhány karakternyi hely a sor végén.resize
CSS-tulajdonság JS-ben került beállításra.Minimális és maximális méret
Elmenthetnénk az elem
scrollTop
tulajdonságát – azonban ez azinput
esemény után történik, így az azonnal lefutó eseménykezelő még a régi értéket fogja megkapni. Tehát szükséges lenne egy nagyon rövidsetTimeout()
, így:setTimeout()
miatt egy nagyon rövid időre fel fog villanni a gördítősáv. Ez a használaton nem ront, mégis zavaró lehet. Ha azonban még asetTimeout()
meghívása előttoverflow: hidden
-t állítunk be, ascrollTop
tulajdonságot nem kapjuk meg.A fentiek afelé mutatnak, hogy a növelési fázis és a
max-height
elérése utáni állapot eltérő megközelítést kíván. A növelési fázisban nem kellsetTimeout()
, hiszen még nincs gördítősávunk, tehát a helyzetét sem kell lekérnünk – így annak felvillanása sem zavar az összképbe. Amax-height
elérése után pedig asetTimeout()
már nem okoz problémát. Tehát az eseménykezelő első lépésében egy feltételvizsgálatra lesz szükség, amiben összehasonlítjuk az elem aktuális és maximális magasságát, figyelembe véve azt az esetet, amikor utóbbi nincs megadva (tehát aparseInt()
függvényNaN
értékkel tér vissza). Továbbá érdemes a túl sűrűn meghívottsetTimeout()
esetéreclearTimeout()
-ot alkalmazni a meghívása előtt, különben előfordulhat, hogy hibásscrollTop
értéket kapunk (ha például lenyomva tartjuk az Enter billentyűt).overflow
tulajdonság módosítása felelős ezért.Emiatt nem tudjuk kiküszöbölni a
TEXTAREA
klónozását, vagyis a szükséges műveleteket a másolt ideiglenes elemen kell végrehajtanunk. Ez azzal az előnnyel is jár, hogy már nincs szükségünk asetTimeout()
-ra, így a kód egyszerűsíthető, mivel az átméretezés függvénybe való kiszervezésére sincs szükség. Ezen felül a gördítősáv pozíciójával sem kell foglalkoznunk, mivel az elemünkoverflow
tulajdonsága érintetlen marad.Természetesen érdemes azzal az esettel is foglalkozni, ha nem adtunk meg
min-height
-et (illetve eltér az eredeti magasságtól). Ekkor ugyanis az első leütött karakternél a dobozunk mérete minimálisra csökken, ami a felhasználói élmény szempontjából zavaró lehet.A végleges kód tehát:
A hozzászólásod számomra