LSFR77: Textareagröße dynamisch anpassen

Hallo, gleich mal vorweg: Ich weiß, dass mein Problem leicht lösbar wäre, wenn ich eine nicht-proportionale Schriftart wie Courier verwenden würde, weil dann könnte ich die Zeichen in der Textarea ganz einfach auszählen (wie hier); ich möchte aber lieber die Schriftart Arial verwenden.

Aber nun zu meinem eigentlichen Problem:
Wenn ein Nutzer Text in die Textarea schreibt, soll die Textarea bei einem automatischen (wenn eine Zeile voll ist, wird in die nächste Zeile gewechselt) oder einem manuellen (User drückt Enter) Zeilenumbruch automatisch um eine Zeile ergänzt werden. Außerdem soll, wenn der Nutzer eine Zeile löscht, die Textarea auch um eine Reihe vermindert werden etc.
Ersteres habe ich hingekriegt, ich weiß aber nicht, wie ich zweiteres umsetzen soll.
Hier mein Code (es geht eigentlich nur um die Funktion "TextareaResize()"):

  
<html>  
<head>  
<title>Test</title>  
<style type="text/css">  
h1 {font-family:Arial;font-size:28pt;margin-bottom:0px}  
textarea {font-family:Arial;font-size:12pt;font-style:italic;color:gray;margin-top:10px}  
</style>  
<script type="text/javascript">  

  
function Textarea (Nr) {  
var a = document.getElementsByTagName("textarea")[0]  
if (Nr != "B") {  
if (a.style.color != "black") a.value = ""  
a.style.color = "black"  
a.style.fontStyle = "normal"  
} else if (a.value == "") {  
a.style.fontStyle = "italic"  
a.style.color = "gray"  
a.value = "Hier Text eingeben ..."  
}  
}  
function TextareaResize() {  
var a = document.getElementsByTagName("textarea")[0]  
if (a.clientHeight < a.scrollHeight) {  
a.rows = a.rows + (a.scrollHeight - a.clientHeight) / 19  
}  
}  

  
</script>  
</head>  
<body>  
<h1>Kleiner Chat-Test</h1>  
<textarea id="test" cols="50" rows="1" onfocus="Textarea()" onblur="Textarea('B')" onkeydown="setTimeout('TextareaResize()', 10)" onkeyup="TextareaResize()">Hier Text eingeben ...</textarea>  
</body>  
</html>  

Zur Erklärung: a.rows = a.rows + (a.scrollHeight - a.clientHeight) / 19 deshalb, weil der Differenz zwischen Scroll- und Clientheight (zumindest bei Google Chrome) immer ein Faktor von 19 ist. Wenn z. B. zwei Zeilen auf einmal mittel Strg-V eingefügt werden, ist die Differenz 38 und weil 38 / 19 2 ergibt, werden zwei Zeilen hinzugefügt.
(Man kann auch einfach a.rows = a.rows + 1 schreiben, wenn man außer Acht lässt, dass der Nutzer theoretisch mehr als eine Zeile Text auf einmal einfügen kann).

Es wäre nett, wenn mir jemand sagen könnte, was er von meinem bisherigen Ansatz hält und wie ich mein Problem lösen kann!

LG LSFR77

  1. Hallo,

    Hallo, gleich mal vorweg: Ich weiß, dass mein Problem leicht lösbar wäre, wenn ich eine nicht-proportionale Schriftart wie Courier verwenden würde

    nein, das würde die Aufgabe kein bisschen erleichtern.

    weil dann könnte ich die Zeichen in der Textarea ganz einfach auszählen

    Könnte man. Das ändert aber nichts daran, dass du die Schrift, die beim Besucher *wirklich* verwendet wird, nicht kennst. Weder die Schriftart, noch die Größe - denn dein Stylesheet gibt ja nur eine Darstellungsempfehlung, auf deren Gültigkeit du dich nicht verlassen kannst. Was, wenn die gewünschte Schrift auf dem System des Besuchers nicht verfügbar ist und automatisch eine passende Ersatzschrift gewählt wird? Was, wenn der Nutzer eine wesentlich größere Mindest-Schriftgröße in seinen Browsereinstellungen gesetzt hat? Was, wenn das Styling von Formularelementen aus Gründen der Usability generell stark eingeschränkt ist?

    Wenn ein Nutzer Text in die Textarea schreibt, soll die Textarea bei einem automatischen (wenn eine Zeile voll ist, wird in die nächste Zeile gewechselt) oder einem manuellen (User drückt Enter) Zeilenumbruch automatisch um eine Zeile ergänzt werden. Außerdem soll, wenn der Nutzer eine Zeile löscht, die Textarea auch um eine Reihe vermindert werden etc.

    Warum? Wer möchte sowas?
    Ganz ehrlich: Mich würde ein solches Verhalten eher stören oder sogar verunsichern, weil es unüblich ist.

    Zur Erklärung: a.rows = a.rows + (a.scrollHeight - a.clientHeight) / 19 deshalb, weil der Differenz zwischen Scroll- und Clientheight (zumindest bei Google Chrome) immer ein Faktor von 19 ist.

    Das mag auf *deinem* System so sein. Das ist aber mehr oder weniger Zufall und hängt von den auf deinem Rechner festgelegten Schriftdimensionen ab. Wenn du den konstanten Faktor wirklich allgemein halten willst, müsstest du die Höhendifferenz eines garantiert einzeiligen und eines garantiert zweizeiligen textarea-Elements mit gleicher Formatierung ausmessen. Die Elemente müssen ja dabei nicht sichtbar sein.

    Es wäre nett, wenn mir jemand sagen könnte, was er von meinem bisherigen Ansatz hält und wie ich mein Problem lösen kann!

    Tja, wie gesagt: Ich kann mich für die Idee nicht begeistern und hätte lieber ein scrollendes textarea-Element mit gleichbleibender Höhe.

    Ciao,
     Martin

    --
    Kopflosigkeit schützt nicht vor Migräne.
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Okay, danke für die Antwort.

      Dann werde ich wohl wie von Dir empfohlen ein scrollendes textarea-Element verwenden.

      Ich habe mich nur gefragt, wie z. B. Facebook diesen Effekt hinbekommt.
      Wenn man dort nämlich bei einem Kommentar einen Zeilenumbruch erzeugt, kommt auch eine Zeile dazu bzw. umgekehrt. Vermutlich haben die die Breiten jedes Buchstabens der von ihnen verwendeten Schrifart ausgemessen und irgendein hochkompliziertes Skript dafür geschrieben ...

      LG LSFR77

      1. Om nah hoo pez nyeetz, LSFR77!

        Vermutlich haben die die Breiten jedes Buchstabens der von ihnen verwendeten Schrifart ausgemessen und irgendein hochkompliziertes Skript dafür geschrieben ...

        Ich würde einfach schauen, ob sich der Textcursor jenseits der Mitte befindet und dann eine neue Zeile dranhängen und auf die Entertaste lässt sich ja gesondert reagieren.

        Matthias

        --
        1/z ist kein Blatt Papier.

        1. Wäre auch eine Möglichkeit, aber (wenn ich Deine Idee richtig verstanden habe) würde die neue Zeile dann schon sehr früh (ich meine, während der Cursor des Nutzers noch mitten in der Zeile ist - das könnte stören) erscheinen und die Idee lässt sich nicht wirklich auf die Zeilen-Lösch-Sache umsetzen: In diesem Fall würde die Zeile nämlich auch gelöscht werden, wenn der Nutzer mehr als die Hälfte der in einer Zeile vorkommenden Zeichen löscht. Da bleiben dann aber immer noch einige Zeichen, und diese verschwinden vermutlich entweder ganz, oder werden in die höherliegende Zeile verschoben (was schlecht wäre, wenn der Nutzer bewusst einen Zeilenumbruch gesetzt hat), oder erzwingen einen Scrollbalken.

          LG LSFR77

          1. Om nah hoo pez nyeetz, LSFR77!

            Wäre auch eine Möglichkeit, aber (wenn ich Deine Idee richtig verstanden habe) würde die neue Zeile dann schon sehr früh (ich meine, während der Cursor des Nutzers noch mitten in der Zeile ist - das könnte stören) erscheinen

            nimm statt 50 eine dir genehme Prozentzahl.

            Matthias

            --
            1/z ist kein Blatt Papier.

      2. Ich habe mich nur gefragt, wie z. B. Facebook diesen Effekt hinbekommt.
        Wenn man dort nämlich bei einem Kommentar einen Zeilenumbruch erzeugt, kommt auch eine Zeile dazu bzw. umgekehrt. Vermutlich haben die die Breiten jedes Buchstabens der von ihnen verwendeten Schrifart ausgemessen und irgendein hochkompliziertes Skript dafür geschrieben ...

        Nein. Es gibt verschiedene Dinge, auf die solche Scripte reagieren können. Dazu ist verwendete Schriftart in der Regel nicht relevant.

        Beispielsweise kann man die Scroll-Höhe abfragen bzw. testen, ob ein Scrollen möglich ist und wie hoch die Höhe sein muss, damit keine Scrollbar mehr gezeigt wird. Diese Logik kommt ohne Schriftgrößen- und Zeilenhöhen-Berechnungen aus. Siehe etwa https://github.com/padolsey/jQuery.fn.autoResize/blob/master/jquery.autoresize.js.

        Mathias

        1. Beispielsweise kann man die Scroll-Höhe abfragen bzw. testen, ob ein Scrollen möglich ist und wie hoch die Höhe sein muss, damit keine Scrollbar mehr gezeigt wird. Diese Logik kommt ohne Schriftgrößen- und Zeilenhöhen-Berechnungen aus. Siehe etwa https://github.com/padolsey/jQuery.fn.autoResize/blob/master/jquery.autoresize.js.

          Darauf basiert mein Script eigentlich eh bereits. Ich weiß nur nicht, wie ich diese Idee für das Löschen von Zeilen umsetzen soll. Aber ich werde mir mal den Link ansehen, vielleicht finde ich ja dort die Antwort ...

          LG LSFR77

          1. Om nah hoo pez nyeetz, LSFR77!

            Ich weiß nur nicht, wie ich diese Idee für das Löschen von Zeilen umsetzen soll.

            Merke dir bei wievielen Zeichen du eine Zeile hinzugeben musstest. Mach das wieder rückgängig, wenn der Inhalt des Textfeldes diese Zeichenzahl unterschreitet.

            Matthias

            --
            1/z ist kein Blatt Papier.

            1. Ah, stimmt!

              LG LSFR77

    2. Ganz ehrlich: Mich würde ein solches Verhalten eher stören oder sogar verunsichern, weil es unüblich ist.

      Was ich im Firefox cool finde, da kriegt eine Textbox rechts unten einen Bereich zum Größe ändern, man kann sie verziehen.
      Das bringt zwar das Layout durcheinander, aber damit kann man leben wenn man wirklich mal was größeres schreiben will. Und man machts dann selbst, es passiert nicht automatisch. Das würd mich nämlich auch irgendwie irritieren.

      1. Om nah hoo pez nyeetz, Encoder!

        Was ich im Firefox cool finde, da kriegt eine Textbox rechts unten einen Bereich zum Größe ändern, man kann sie verziehen.
        Das bringt zwar das Layout durcheinander,

        Wenn du ihr minimale und maximale Abmessungen mitgibst, tut sie das nur in von dir vorgegebenen Grenzen.

        Matthias

        --
        1/z ist kein Blatt Papier.

    3. Eine Menge rhetorischer Fragen in den Raum zu werfen ist das eine, sie auch fachlich korrekt beantworten zu können, ist etwas anders.

      Könnte man. Das ändert aber nichts daran, dass du die Schrift, die beim Besucher *wirklich* verwendet wird, nicht kennst.

      Muss man für diese Logik auch nicht.

      Weder die Schriftart, noch die Größe - denn dein Stylesheet gibt ja nur eine Darstellungsempfehlung, auf deren Gültigkeit du dich nicht verlassen kannst.

      Man kann sich weitgehend auf die computed values verlassen, die man mit JavaScript misst.

      Was, wenn die gewünschte Schrift auf dem System des Besuchers nicht verfügbar ist und automatisch eine passende Ersatzschrift gewählt wird?

      Nichts ist dann. Der Font spielt keine Rolle für solche Berechnungen.

      Was, wenn der Nutzer eine wesentlich größere Mindest-Schriftgröße in seinen Browsereinstellungen gesetzt hat? Was, wenn das Styling von Formularelementen aus Gründen der Usability generell stark eingeschränkt ist?

      Was, wenn im Nutzerstylesheet * { color: red !important; background: red !important; } steht – wie soll der Nutzer dann noch die Seite lesen können?

      Nicht. Wenn der Nutzer die Seite kaputt macht, ist sie kaputt. Dann hat er Pech gehabt und ist selbst schuld.

      Ganz ehrlich: Mich würde ein solches Verhalten eher stören oder sogar verunsichern, weil es unüblich ist.

      Es ist nicht unüblich. Von »Facebook« auf »unüblich« zu kommen ist ein merkwürdiger argumentativer Kniff.

      Das mag auf *deinem* System so sein. Das ist aber mehr oder weniger Zufall und hängt von den auf deinem Rechner festgelegten Schriftdimensionen ab.

      Nein, es hängt von der line-height ab.

      Schau dir einmal mal an, wie solche ausgereiften Scripte arbeiten, und versuche sie kaputtzukriegen durch realistische, nicht hypothetische Fälle. Diese kannst du gerne gegen die Nutzung solcher Scripte einwenden.

      Mathias

      1. Hallo,

        Eine Menge rhetorischer Fragen in den Raum zu werfen ist das eine, sie auch fachlich korrekt beantworten zu können, ist etwas anders.

        ja, ich weiß, dass du gut darin bist, unangebrachte Kritik zu üben.

        Könnte man. Das ändert aber nichts daran, dass du die Schrift, die beim Besucher *wirklich* verwendet wird, nicht kennst.
        Muss man für diese Logik auch nicht.

        Richtig, und du hast geflissentlich ignoriert, dass ich das weiter unten auch ausgeführt und einen Lösungsansatz angeboten habe. Nur wenn man -wie der OP- konstante, feste Werte verwendet, fällt man auf die Nase.

        Ganz ehrlich: Mich würde ein solches Verhalten eher stören oder sogar verunsichern, weil es unüblich ist.
        Es ist nicht unüblich. Von »Facebook« auf »unüblich« zu kommen ist ein merkwürdiger argumentativer Kniff.

        Von facebook auf üblich zu kommen, halte ich für noch viel gewagter.
        Gerade solche heiß angepriesenen Portale verwenden gern Unübliches und Fragwürdiges. Abgesehen davon, dass ich facebook, youtube, twitter und ähnlichen Unfug meide und daher nicht immer über deren neue Ideen informiert bin. Will ich auch gar nicht.

        Das mag auf *deinem* System so sein. Das ist aber mehr oder weniger Zufall und hängt von den auf deinem Rechner festgelegten Schriftdimensionen ab.
        Nein, es hängt von der line-height ab.

        Ja. Und die berechnet sich aus der Schriftgröße, wenn man sie nicht explizit anders setzt.

        Schau dir einmal mal an, wie solche ausgereiften Scripte arbeiten, und versuche sie kaputtzukriegen durch realistische, nicht hypothetische Fälle. Diese kannst du gerne gegen die Nutzung solcher Scripte einwenden.

        Mathias, ich würde mir wirklich wünschen, du würdest etwas sachlicher argumentieren, und nicht immer wieder mit provozierender Polemik aus der Hüfte schießen. Kein Wunder, dass der Ton so oft ins Aggressive umschlägt, wenn du dich einschaltest.

        Und tschüss,
         Martin

        --
        Fettflecke werden wieder wie neu, wenn man sie regelmäßig mit etwas Butter einschmiert.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Ganz ehrlich: Mich würde ein solches Verhalten eher stören oder sogar verunsichern, weil es unüblich ist.
          Es ist nicht unüblich. Von »Facebook« auf »unüblich« zu kommen ist ein merkwürdiger argumentativer Kniff.

          Von facebook auf üblich zu kommen, halte ich für noch viel gewagter.

          Ich weiß nicht, was du unter »üblich« verstehst. Ich meine damit »verbreitet und daher vielen Nutzern bekannt«. Fakt ist, solche Scripte sind verbreitet und vielen Nutzern bekannt, auch wenn du sie nicht kennst und magst.

          Schau dir einmal mal an, wie solche ausgereiften Scripte arbeiten, und versuche sie kaputtzukriegen durch realistische, nicht hypothetische Fälle. Diese kannst du gerne gegen die Nutzung solcher Scripte einwenden.

          Mathias, ich würde mir wirklich wünschen, du würdest etwas sachlicher argumentieren, und nicht immer wieder mit provozierender Polemik aus der Hüfte schießen.

          Ich argumentierevsachlich. Was hältst du an obigem Hinweis für unsachlich? Es ist einfach, mit rhetorischen Fragen Verunsicherung zu erzeugen, aber etwas anderes, eine Problemstellung technisch zu erörtern, indem man konkrete Implementierungen diskutiert und auf dem gegenwärtigen Stand des Wissens Einwände zu formulieren. Eine wahrlich provokante Forderung.

          Mathias

  2. CSS resize ist (m|d)ein Freund!
    Keine Angst mehr vor zu kleinen oder zu grossen Area-Inputfeldern.

    mfg Beat

    --
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o
    Der Valigator leibt diese Fische
  3. Danke für all die (hilfreichen) Antworten.

    Um zu vermeiden, auch etwas für den Fall schreiben zu müssen, dass der Nutzer eine Zeile löscht, habe ich mein Problem jetzt so gelöst:

    Die Textarea ist zu Beginn eine Zeile groß, wenn der Nutzer jetzt einen Zeilenumbruch erzeugt, kommen fünf Zeilen hinzu, wenn diese fünf Zeilen aufgebraucht sind und der Nutzer noch einen Zeilenumbruch erzeugt, kommen abermals fünf Zeilen dazu etc.
    Wenn der Nutzer nur eine Zeile löscht, weil er z. B. versehentlich an der Enter-Taste angekommen ist, macht dies nichts, weil er quasi einen "Spielraum" von sechs/elf/sechzehn/... Zeilen hat.
    Ansonsten kann der Nutzer die Größe der Textarea ja auch immer noch händisch regulieren.

    LG LSFR77