javascript - textarea stretch to fit




Autosizing Textarea mit Prototype (12)

Überprüfen Sie den folgenden Link: http://james.padolsey.com/javascript/jquery-plugin-autoresize/

$(document).ready(function () {
    $('.ExpandableTextCSS').autoResize({
        // On resize:
        onResize: function () {
            $(this).css({ opacity: 0.8 });
        },
        // After resize:
        animateCallback: function () {
            $(this).css({ opacity: 1 });
        },
        // Quite slow animation:
        animateDuration: 300,
        // More extra space:
        extraSpace:20,
        //Textarea height limit
        limit:10
    });
});

Ich arbeite gerade an einer internen Verkaufsanwendung für die Firma, für die ich arbeite, und ich habe ein Formular, das es dem Benutzer ermöglicht, die Lieferadresse zu ändern.

Jetzt würde es viel schöner aussehen, wenn das Textfeld, das ich für die Hauptadressdetails verwende, nur den Bereich des Textes einnimmt und die Größe automatisch ändert, wenn der Text geändert wird.

Hier ist ein Screenshot davon.

Irgendwelche Ideen?

@Chris

Ein guter Punkt, aber es gibt Gründe, warum ich es verkleinern möchte. Ich möchte, dass der Bereich, den es einnimmt, der Bereich der darin enthaltenen Informationen ist. Wie Sie im Screenshot sehen können, braucht ich einen festen vertikalen Bereich, wenn ich einen festen Textbereich habe.

Ich kann die Schriftart reduzieren, aber ich brauche eine große und lesbare Adresse. Jetzt kann ich die Größe des Textbereichs verringern, aber dann habe ich Probleme mit Leuten, die eine Adressenzeile haben, die 3 oder 4 (eine nimmt 5) Linien nimmt. Die Notwendigkeit, den Benutzer eine Bildlaufleiste verwenden zu müssen, ist ein wichtiges No-No.

Ich denke, ich sollte etwas genauer sein. Ich bin nach vertikaler Größenanpassung und die Breite ist nicht so wichtig. Das einzige Problem, das damit passiert, ist die ISO-Nummer (die große "1") wird unter der Adresse gedrückt, wenn die Fensterbreite zu klein ist (wie Sie auf dem Screenshot sehen können).

Es geht nicht darum, einen Gimick zu haben; Es geht darum, ein Textfeld zu haben, das der Benutzer bearbeiten kann und das nicht unnötig Platz einnimmt, sondern den gesamten Text darin anzeigt.

Aber wenn jemand eine andere Möglichkeit hat, sich dem Problem zu nähern, bin ich auch dafür offen.

Ich habe den Code ein wenig modifiziert, weil er etwas merkwürdig wirkt. Ich habe es so geändert, dass es bei der Schlüsseleingabe aktiviert wurde, weil das Zeichen, das gerade eingegeben wurde, nicht berücksichtigt würde.

resizeIt = function() {
  var str = $('iso_address').value;
  var cols = $('iso_address').cols;
  var linecount = 0;

  $A(str.split("\n")).each(function(l) {
    linecount += 1 + Math.floor(l.length / cols); // Take into account long lines
  })

  $('iso_address').rows = linecount;
};

Benutzer von Internet Explorer, Safari, Chrome und Opera müssen daran denken, den Wert für die Zeilenhöhe explizit in CSS festzulegen. Ich mache ein Stylesheet, das die anfänglichen Eigenschaften für alle Textfelder wie folgt einstellt.

<style>
    TEXTAREA { line-height: 14px; font-size: 12px; font-family: arial }
</style>

Für diejenigen, die für IE codieren und auf dieses Problem stoßen. IE hat einen kleinen Trick, der es zu 100% CSS macht.

<TEXTAREA style="overflow: visible;" cols="100" ....></TEXTAREA>

Sie können sogar einen Wert für rows = "n" angeben, den der IE ignoriert, aber andere Browser verwenden. Ich hasse wirklich Kodierung, die IE Hacks implementiert, aber dieser ist sehr hilfreich. Es ist möglich, dass es nur im Quirks-Modus funktioniert.


Facebook macht es, wenn man an die Wände von Menschen schreibt, aber nur vertikal skaliert.

Die horizontale Größenänderung erscheint mir aufgrund von Wortumbruch, langen Zeilen und so weiter als Unordnung, aber die vertikale Größenänderung scheint ziemlich sicher und nett zu sein.

Keiner der Facebook-nowing-newbies, die ich kenne, hat jemals etwas darüber erwähnt oder war verwirrt. Ich würde das als Anekdotenbeweis verwenden, um zu sagen "mach weiter, realisiere es".

Etwas JavaScript-Code, um es zu tun, mit Prototype (weil mir das vertraut ist):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <script src="http://www.google.com/jsapi"></script>
        <script language="javascript">
            google.load('prototype', '1.6.0.2');
        </script>
    </head>

    <body>
        <textarea id="text-area" rows="1" cols="50"></textarea>

        <script type="text/javascript" language="javascript">
            resizeIt = function() {
              var str = $('text-area').value;
              var cols = $('text-area').cols;

              var linecount = 0;
              $A(str.split("\n")).each( function(l) {
                  linecount += Math.ceil( l.length / cols ); // Take into account long lines
              })
              $('text-area').rows = linecount + 1;
            };

            // You could attach to keyUp, etc. if keydown doesn't work
            Event.observe('text-area', 'keydown', resizeIt );

            resizeIt(); //Initial on load
        </script>
    </body>
</html>

PS: Offensichtlich ist dieser JavaScript-Code sehr naiv und nicht gut getestet, und Sie möchten ihn wahrscheinlich nicht in Textboxen mit Romanen verwenden, aber Sie erhalten die allgemeine Idee.


Hier ist eine Erweiterung des Prototype-Widgets, das Jeremy am 4. Juni veröffentlicht hat:

Es verhindert, dass der Benutzer mehr Zeichen eingibt, wenn Sie Limits in Textareas verwenden. Es prüft, ob noch Zeichen vorhanden sind. Wenn der Benutzer Text in den Textbereich kopiert, wird der Text maximal abgeschnitten. Länge:

/**
 * Prototype Widget: Textarea
 * Automatically resizes a textarea and displays the number of remaining chars
 * 
 * From: http://.com/questions/7477/autosizing-textarea
 * Inspired by: http://github.com/jaz303/jquery-grab-bag/blob/63d7e445b09698272b2923cb081878fd145b5e3d/javascripts/jquery.autogrow-textarea.js
 */
if (window.Widget == undefined) window.Widget = {}; 

Widget.Textarea = Class.create({
  initialize: function(textarea, options){
    this.textarea = $(textarea);
    this.options = $H({
      'min_height' : 30,
      'max_length' : 400
    }).update(options);

    this.textarea.observe('keyup', this.refresh.bind(this));

    this._shadow = new Element('div').setStyle({
      lineHeight : this.textarea.getStyle('lineHeight'),
      fontSize : this.textarea.getStyle('fontSize'),
      fontFamily : this.textarea.getStyle('fontFamily'),
      position : 'absolute',
      top: '-10000px',
      left: '-10000px',
      width: this.textarea.getWidth() + 'px'
    });
    this.textarea.insert({ after: this._shadow });

    this._remainingCharacters = new Element('p').addClassName('remainingCharacters');
    this.textarea.insert({after: this._remainingCharacters});  
    this.refresh();  
  },

  refresh: function(){ 
    this._shadow.update($F(this.textarea).replace(/\n/g, '<br/>'));
    this.textarea.setStyle({
      height: Math.max(parseInt(this._shadow.getHeight()) + parseInt(this.textarea.getStyle('lineHeight').replace('px', '')), this.options.get('min_height')) + 'px'
    });

    // Keep the text/character count inside the limits:
    if($F(this.textarea).length > this.options.get('max_length')){
      text = $F(this.textarea).substring(0, this.options.get('max_length'));
        this.textarea.value = text;
        return false;
    }

    var remaining = this.options.get('max_length') - $F(this.textarea).length;
    this._remainingCharacters.update(Math.abs(remaining)  + ' characters remaining'));
  }
});

Hier ist eine Funktion, die ich gerade in jQuery geschrieben habe - Sie können sie nach Prototype portieren, aber sie unterstützen nicht die "Lebendigkeit" von jQuery, so dass von Ajax-Anfragen hinzugefügte Elemente nicht antworten.

Diese Version wird nicht nur erweitert, sondern zieht sich auch zusammen, wenn Sie auf Löschen oder Zurücksetzen klicken.

Diese Version basiert auf jQuery 1.4.2.

Genießen ;)

http://pastebin.com/SUKeBtnx

Verwendung:

$("#sometextarea").textareacontrol();

oder (irgendein jQuery Selektor zum Beispiel)

$("textarea").textareacontrol();

Es wurde auf Internet Explorer 7 / Internet Explorer 8 , Firefox 3.5 und Chrome getestet. Alles funktioniert gut.


Hier ist eine weitere Technik zum automatischen Anpassen eines Textfelds.

  • Verwendet die Pixelhöhe anstelle der Zeilenhöhe: Genauere Handhabung des Zeilenumbruchs, wenn eine proportionale Schriftart verwendet wird.
  • Akzeptiert entweder ID oder Element als Eingabe
  • Akzeptiert einen optionalen maximalen Höhe-Parameter - nützlich, wenn Sie den Textbereich nicht über eine bestimmte Größe hinaus wachsen lassen möchten (behalten Sie alles auf dem Bildschirm bei, vermeiden Sie das Layout zu brechen usw.)
  • Getestet auf Firefox 3 und Internet Explorer 6

Code: (einfaches JavaScript)

function FitToContent(id, maxHeight)
{
   var text = id && id.style ? id : document.getElementById(id);
   if (!text)
      return;

   /* Accounts for rows being deleted, pixel value may need adjusting */
   if (text.clientHeight == text.scrollHeight) {
      text.style.height = "30px";
   }

   var adjustedHeight = text.clientHeight;
   if (!maxHeight || maxHeight > adjustedHeight)
   {
      adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
      if (maxHeight)
         adjustedHeight = Math.min(maxHeight, adjustedHeight);
      if (adjustedHeight > text.clientHeight)
         text.style.height = adjustedHeight + "px";
   }
}

Demo: (verwendet jQuery, Ziele auf der Textfläche, in die ich gerade schreibe - wenn Sie Firebug installiert haben, fügen Sie beide Samples in die Konsole ein und testen Sie auf dieser Seite)

$("#post-text").keyup(function()
{
   FitToContent(this, document.documentElement.clientHeight)
});

Ich brauchte diese Funktion für mich selbst, aber keiner von denen funktionierte so, wie ich sie brauchte.

Also habe ich Orions Code benutzt und geändert.

Ich habe in minimaler Höhe hinzugefügt, damit es beim Zerstören nicht zu klein wird.

function resizeIt( id, maxHeight, minHeight ) {
    var text = id && id.style ? id : document.getElementById(id);
    var str = text.value;
    var cols = text.cols;
    var linecount = 0;
    var arStr = str.split( "\n" );
    $(arStr).each(function(s) {
        linecount = linecount + 1 + Math.floor(arStr[s].length / cols); // take into account long lines
    });
    linecount++;
    linecount = Math.max(minHeight, linecount);
    linecount = Math.min(maxHeight, linecount);
    text.rows = linecount;
};

Meine Lösung, die jQuery nicht verwendet (weil manchmal nicht dasselbe sein muss), ist unten. Obwohl es nur in Internet Explorer 7 getestet wurde, kann die Community auf alle Gründe hinweisen, warum dies falsch ist:

textarea.onkeyup = function () { this.style.height = this.scrollHeight + 'px'; }

Bis jetzt mag ich wirklich, wie es funktioniert, und ich interessiere mich nicht für andere Browser, also werde ich es wahrscheinlich auf alle meine Textareas anwenden:

// Make all textareas auto-resize vertically
var textareas = document.getElementsByTagName('textarea');

for (i = 0; i<textareas.length; i++)
{
    // Retain textarea's starting height as its minimum height
    textareas[i].minHeight = textareas[i].offsetHeight;

    textareas[i].onkeyup = function () {
        this.style.height = Math.max(this.scrollHeight, this.minHeight) + 'px';
    }
    textareas[i].onkeyup(); // Trigger once to set initial height
}

Verwenden Sie ASP.NET einfach so:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Automatic Resize TextBox</title>
        <script type="text/javascript">
            function setHeight(txtarea) {
                txtarea.style.height = txtdesc.scrollHeight + "px";
            }
        </script>
    </head>

    <body>
        <form id="form1" runat="server">
            <asp:TextBox ID="txtarea" runat= "server" TextMode="MultiLine"  onkeyup="setHeight(this);" onkeydown="setHeight(this);" />
        </form>
    </body>
</html>

Wenn ich das nochmal anschaue, habe ich es etwas aufgeräumter gemacht (obwohl jemand, der eine volle Flasche auf Prototype / JavaScript hat, Verbesserungen vorschlagen könnte?).

var TextAreaResize = Class.create();
TextAreaResize.prototype = {
  initialize: function(element, options) {
    element = $(element);
    this.element = element;

    this.options = Object.extend(
      {},
      options || {});

    Event.observe(this.element, 'keyup',
      this.onKeyUp.bindAsEventListener(this));
    this.onKeyUp();
  },

  onKeyUp: function() {
    // We need this variable because "this" changes in the scope of the
    // function below.
    var cols = this.element.cols;

    var linecount = 0;
    $A(this.element.value.split("\n")).each(function(l) {
      // We take long lines into account via the cols divide.
      linecount += 1 + Math.floor(l.length / cols);
    })

    this.element.rows = linecount;
  }
}

Rufen Sie einfach an mit:

new TextAreaResize('textarea_id_name_here');

Wie die Antwort von @memical.

Ich habe jedoch einige Verbesserungen gefunden. Sie können die Funktion jQuery height() verwenden. Beachten Sie jedoch die Pixel padding-top und padding-bottom. Sonst wird Ihr Textbereich zu schnell wachsen.

$(document).ready(function() {
  $textarea = $("#my-textarea");

  // There is some diff between scrollheight and height:
  //    padding-top and padding-bottom
  var diff = $textarea.prop("scrollHeight") - $textarea.height();
  $textarea.live("keyup", function() {
    var height = $textarea.prop("scrollHeight") - diff;
    $textarea.height(height);
  });
});




prototypejs