globe: Artikel: Größe eines Textfeldes an dessen Inhalt anpassen

n'abend,

vor Kurzem wurde der neue Artikel Größe eines Textfeldes an dessen Inhalt anpassen veröffentlicht. Beim Überfliegen fielen mir ein paar Problemchen auf, welche ich nicht für mich behielt. Auf meine Hinweise wurde jedoch - dank eines gnadenlosen Flamewars - nicht weiter eingegangen. Am Wochenende setzte sich Stonie mit mir in Verbindung, ob ich dem Autor bei der Lösung der Problemchen unter die Arme greifen könnte.

Ohne das ganze abwertend klingen lassen zu wollen: Die vom Autor gewählte Vorgehensweise verfehlt das Ziel. Deshalb habe ich dem Autor per E-Mail einen anderen Lösungsweg aufgezeigt. Da ich mir über dessen Erfolg aber auch nicht im Klaren war, habe ich das Ding kurzerhand umgesetzt.

Ich habe meine Lösung nicht für einen Artikel aufbereitet, sondern lediglich in meinem Stil "runtergerotzt". Unter anderem setze ich jQuery ein, was in einem Anfänger-Tutorial vielleicht (noch) nicht das Wahre ist. Wie dem auch sei, der Ansatz sollte einfach zu verstehen sein: jQuery.autoHeight() (Achtung: Temporärer Link)

Sieht einer von euch Probleme in meinem Ansatz? Gibt es Verbesserungsvorschläge? Kommentare? Mordgelüste?

Wenn die Vorgehensweise allgemein akzeptiert (und ggf. verfeinert) wurde, setze ich mich gerne mit JeSchnell zusammen, um die Lösung in einen neuen Artikel zu verpacken, sofern er Interesse an der Geschichte hat. Auf meine Mail (zugegeben von gestern) hat er bislang noch nicht geantwortet. Ich hoffe er fühlt sich nicht angegriffen oder so - das wäre jedenfalls nicht meine Absicht gewesen... :/

weiterhin schönen abend...

--
#selfhtml hat ein Forum?
sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
  1. Hallo!

    Erst mal: Toll, dass du die Sache in die Hand nimmst und zusammen mit dem Autor den Artikel verbessern willst.
    Ohne mir anzuschauen, was du da gebaut hast, wollte ich fragen, ob du dir bewusst bist, dass es schon ein entsprechendes jQuery-Plugin gibt:
    http://plugins.jquery.com/project/autogrow
    Ich weiß (noch) nicht, wie gut das umgesetzt ist, ob deines nun besser ist, aber es lohnt sich sicher, einen Blick darauf zu werfen.

    Mathias

    1. n'abend,

      Ohne mir anzuschauen, was du da gebaut hast, wollte ich fragen, ob du dir bewusst bist, dass es schon ein entsprechendes jQuery-Plugin gibt:
      http://plugins.jquery.com/project/autogrow

      das war mir nicht bewusst. Ich hatte allerdings auch nicht nach einer fertigen Lösung gesucht. Obwohl ich jQuery sehr zu schätzen und lieben gelernt habe, sind mir 99.99% der Plugins suspekt. Ich schaue mir - wenn ich gerade mal nichts zu tun habe - öfter mal neue Plugins an. Meist jedoch weniger um sie zu nutzen, mehr um eigene Ideen anzureichern. jQuery: ja, Fremd-Plugins: (mit Ausnahmen) eher nicht so.

      Ich weiß (noch) nicht, wie gut das umgesetzt ist, ob deines nun besser ist, aber es lohnt sich sicher, einen Blick darauf zu werfen.

      === Ähnlichkeiten: ===

      * Sowohl autoHeight() als auch autogrow() kopieren den Inhalt der <textarea> in ein zweites (verstecktes) Element, von welchem dann die (computedStyle) Höhe ausgelesen werden können.

      === Unterschiede: ===

      * Während mein Ansatz durch (keyup-)Events ausgelöst wird, setzt autogrow() auf einen Intervall.
       * autoHeight() kann neben minimaler und maximaler Höhe auch noch die Anzahl freier Zeilen am Ende als Parameter entgegen nehmen.
       * autogrow() beachtet padding, autoHeight() nicht.
       * autogrow() berücksichtigt overflow-x und overflow-y (um das Aufflackern der Scrollbar zu verhindern)
       * autogrow() escaped HTML-Steuerzeichen
       * autogrow() ignoriert eine ganze Reihe von font-relevanten Styles
       * autogrow() arbeitet mit jQuery.animate()
       * autogrow() nutzt die Styles min-height und max-height, statt diese als Parameter zu übergeben

      === Schlussfolgerungen ===

      * <br> vs. <BR> (IE workaround) [bug]
       * <,& und > durch Entitäten ersetzen (ich depp™) [bug]
       * overflow-x/y entsprechend setzen [optimierung]
       * nochmal mit jQuery.animate() experimentieren [optimierung]
       * prüfen welche Auswirkungen das Ignorieren von padding mit sich bringt [possible bug]
       * Intervall gegenüber keyup-Event prüfen [optimierung]
       * min/max Höhe möglicherweise ebenfalls mittels CSS, statt JS spezifizieren [optimierung]

      weiterhin schönen abend...

      --
      #selfhtml hat ein Forum?
      sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
      1. n'abend,

        Beim weiteren experimentieren ist mit aufgefallen, dass sowohl bei autogrow(), als auch bei autoHeight() der Mirror-Container höher als das eigentliche Dokument werden kann. Das führt zu merkwürdigem gehopse und der ungewollten Veränderung des Window-Scrollbar.

        Vermutlich müsste man einfach den Mirror in einen dimensional limitierten Container verfrachten, dem man darüber hinaus ein overlow:hidden; verpasst hat. Dabei würde aber der momentan sichtbare Mirror versteckt werden, weshalb das mal hinten angestellt wird.

        * <br> vs. <BR> (IE workaround) [bug]

        [x] fixed

        * <,& und > durch Entitäten ersetzen (ich depp™) [bug]

        [x] fixed

        Hierbei habe ich festgestellt, dass autogrow() "&" nicht nach "&amp;" konvertiert und dadurch (minimale) Abweichungen in der tatsächlichen Größe entstehen können. z.B. wenn man ein paar Hundert " &nbsp;" reinkopiert...

        * prüfen welche Auswirkungen das Ignorieren von padding mit sich bringt [possible bug]

        [x] fixed

        jetzt hab ich nur noch das Phänomen, dass zwei Leerzeichen in der <textarea> anders umbrechen als " &nbsp;". Ideen?

        weiterhin schönen abend...

        --
        #selfhtml hat ein Forum?
        sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
      2. n'abend,

        autoHeight() updated darf gerne noch mal angeschaut werden... Neuerungen bringen nur all zu gerne neue Bugs mit sich...

        * overflow-x/y entsprechend setzen [optimierung]

        [x] umgesetzt

        * nochmal mit jQuery.animate() experimentieren [optimierung]

        Irgendein Detail fällt hier durchs Sieb. Ich finde den Grund nicht, weshalb der Cursor nach einem .animate() auf einmal am Ende der Textarea steht. Falls jemand drauf kommt, melden, andernfalls: aufgegeben.

        * prüfen welche Auswirkungen das Ignorieren von padding mit sich bringt [possible bug]

        nun auch für overflow-y behoben.

        * Intervall gegenüber keyup-Event prüfen [optimierung]

        Test zu Höhenausgleich per Interval. Damit der Interval nicht dauernd läuft, wird er beim Focus gestartet, bei Blur gestoppt. Damit auch zwischendrin nichts unnötiges gemacht wird, setzen KeyUp und MouseUp ein Flag, nach welchem der Interval läuft oder abgebrochen wird. Hierbei habe ich mich entweder verheddert, oder die eigentlich nette Idee geht so schlicht nicht auf - mein Browser wurde tödlich lahm.

        * min/max Höhe möglicherweise ebenfalls mittels CSS, statt JS spezifizieren [optimierung]

        [x] umgesetzt

        weiterhin schönen abend...

        --
        #selfhtml hat ein Forum?
        sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
  2. Hallo,

    Sieht einer von euch Probleme in meinem Ansatz? Gibt es Verbesserungsvorschläge? Kommentare? Mordgelüste?

    Mit den von Dir bereits eingearbeiteten Korrekturen aus dem Teilthread finde ich Deinen Ansatz sehr gut gelungen und bin der Auffassung, dass daher lieber Dein Ansatz (abzüglich jQuery wg. Anfängerverständlichkeit) als der bisherige im Artikel beschrieben werden sollte.

    Viele Grüße,
    Christian

    --
    Mein "Weblog" [RSS]
    Using XSLT to create JSON output (Saxon-B 9.0 for Java)
    »I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
                -- Kommentar bei TDWTF
    1. n'abend,

      Mit den von Dir bereits eingearbeiteten Korrekturen aus dem Teilthread finde ich Deinen Ansatz sehr gut gelungen und bin der Auffassung, dass daher lieber Dein Ansatz (abzüglich jQuery wg. Anfängerverständlichkeit) als der bisherige im Artikel beschrieben werden sollte.

      Erhebt man den Anspruch dem Leser _Javascript_ beibringen zu wollen, stimme ich dir zu. Möchte man aber vielmehr die Vorgehensweise erläutern, also mehr das Ziel als den Weg vermitteln, würde ich die jQuery-Variante dank des krassen "write less, do more" vorziehen.

      Um den jQuery-Kram zu ersetzen sehe ich jedoch allenfalls die folgenden, überschaubaren, Problempunkte:
       * computedStyle() (wie es in den verschiedenen Browsern zur Verfügung steht)
       * elaborater™ code um die Elemente zu finden
       * onDomReady wegen der unterschiedlichen Implementierung durch onLoad ersetzen
       * metadata (dieser JSON-Kram im style-Attribut) rauswerfen, um das ganze so simpel wie möglich zu halten
       * zurück zu "simplen" EventHandling a la node.onkeyup = function(e){ e = e || window.event; /*....*/ };

      weiterhin schönen abend...

      --
      #selfhtml hat ein Forum?
      sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
  3. Hallo,

    Der Mirror ist in Screenreader »sichtbar«. Wäre es schlimm, ihm zumindest visibility:hidden zu geben? Oder ihn beim Blur zu entfernen?

    Mathias

    1. n'abend,

      Der Mirror ist in Screenreader »sichtbar«. Wäre es schlimm, ihm zumindest visibility:hidden zu geben? Oder ihn beim Blur zu entfernen?

      Das würde ich in der finalen Variante (wenn auch der Mirror außerhalb des Viewports verschoben wurde) auf jeden Fall noch einbauen. Danke für den Hinweis :)

      Ich habe das aktuell ausgelassen, damit man ein visuelles Feedback bekommt, was denn da gerade passiert...

      weiterhin schönen abend...

      --
      #selfhtml hat ein Forum?
      sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|