112

Tôi hiện đang làm việc trên một ứng dụng bán hàng nội bộ cho công ty tôi làm việc và tôi đã có một biểu mẫu cho phép người dùng thay đổi địa chỉ giao hàng.

Bây giờ tôi nghĩ rằng nó sẽ trông đẹp hơn nhiều, nếu textarea tôi đang sử dụng cho các chi tiết địa chỉ chính sẽ chỉ chiếm diện tích của văn bản trong đó và tự động thay đổi kích thước nếu văn bản bị thay đổi.

Đây là một ảnh chụp màn hình của nó hiện tại.

Địa chỉ ISO

Có ý kiến ​​gì không?


@Chris

Một điểm tốt, nhưng có những lý do tôi muốn nó thay đổi kích thước. Tôi muốn khu vực đó chiếm diện tích của thông tin chứa trong đó. Như bạn có thể thấy trong ảnh chụp màn hình, nếu tôi có một vùng văn bản cố định, nó sẽ chiếm một khoảng không gian thẳng đứng.

Tôi có thể giảm phông chữ, nhưng tôi cần địa chỉ lớn và dễ đọc. Bây giờ tôi có thể giảm kích thước của vùng văn bản, nhưng sau đó tôi gặp vấn đề với những người có một dòng địa chỉ mất 3 hoặc 4 (một mất 5) dòng. Cần có người dùng sử dụng thanh cuộn là một điều không nên.

Tôi đoán tôi nên cụ thể hơn một chút. Tôi sau khi thay đổi kích thước dọc và chiều rộng không quan trọng bằng. Vấn đề duy nhất xảy ra với điều đó, là số ISO ("1" lớn) bị đẩy dưới địa chỉ khi chiều rộng cửa sổ quá nhỏ (như bạn có thể thấy trên ảnh chụp màn hình).

Đó không phải là về việc có một gimick; đó là về việc có một trường văn bản mà người dùng có thể chỉnh sửa sẽ không chiếm dung lượng không cần thiết, nhưng sẽ hiển thị tất cả văn bản trong đó.

Mặc dù nếu ai đó nghĩ ra một cách khác để tiếp cận vấn đề thì tôi cũng sẽ giải quyết vấn đề đó.


Tôi đã sửa đổi mã một chút vì nó hoạt động hơi kỳ quặc. Tôi đã thay đổi nó để kích hoạt khi gõ phím, vì nó sẽ không xem xét đến ký tự vừa gõ.

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;
};
|
72

Facebook làm điều đó, khi bạn viết lên tường của mọi người, nhưng chỉ thay đổi kích thước theo chiều dọc.

Thay đổi kích thước theo chiều ngang gây ấn tượng với tôi như một mớ hỗn độn, do bao bọc từ, dòng dài, v.v., nhưng thay đổi kích thước dọc có vẻ khá an toàn và tốt đẹp.

Không ai trong số những người mới sử dụng Facebook mà tôi biết đã từng đề cập bất cứ điều gì về nó hoặc bị nhầm lẫn. Tôi sẽ sử dụng điều này như một bằng chứng giai thoại để nói 'hãy tiếp tục, thực hiện nó'.

Một số mã JavaScript để làm điều đó, sử dụng Prototype (vì đó là những gì tôi quen thuộc):

<!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: Rõ ràng mã JavaScript này rất ngây thơ và không được kiểm tra tốt, và có lẽ bạn không muốn sử dụng nó trên các hộp văn bản có tiểu thuyết trong đó, nhưng bạn có ý tưởng chung.

|
  • 1

    Điều này giả sử trình duyệt bị hỏng ở bất kỳ ký tự nào, không chính xác. Hãy thử nó <textarea cols='5'>0 12345 12345 0</textarea>. (Tôi đã viết một triển khai gần như giống hệt nhau và đã không nắm bắt được điều này cho đến sau một tháng sử dụng nó.) Nó cũng thất bại đối với các dòng trống.

    – Hoàng Hoàng Mai 11:03:45 21/09/2012
  • 1

    Có phiên bản JQuery cho việc này không?

    – Dương Hiếu Dụng 07:56:34 28/09/2015
  • 1

    Dấu gạch chéo ngược trong $ A (str.split ("\ n")) cần một dấu gạch chéo khác. (Chỉnh sửa của tôi về câu trả lời trên đã không tồn tại vì một số lý do.)

    – Hoàng Yến Loan 03:33:08 21/04/2019
60

Một sàng lọc cho một số câu trả lời này là để CSS thực hiện nhiều công việc hơn.

Lộ trình cơ bản dường như là:

  1. Tạo một phần tử container để giữ textareavà ẩndiv
  2. Sử dụng Javascript, giữ textarea's nội dung đồng bộ hóa với div' s
  3. Hãy để trình duyệt thực hiện công việc tính chiều cao của div đó
  4. Vì trình duyệt xử lý kết xuất / định cỡ ẩn div, chúng tôi tránh cài đặt rõ ràng textareachiều cao.

document.addEventListener('DOMContentLoaded', () => {
    textArea.addEventListener('change', autosize, false)
    textArea.addEventListener('keydown', autosize, false)
    textArea.addEventListener('keyup', autosize, false)
    autosize()
}, false)

function autosize() {
    // Copy textarea contents to div browser will calculate correct height
    // of copy, which will make overall container taller, which will make
    // textarea taller.
    textCopy.innerHTML = textArea.value.replace(/\n/g, '<br/>')
}
html, body, textarea {
    font-family: sans-serif;
    font-size: 14px;
}

.textarea-container {
    position: relative;
}

.textarea-container > div, .textarea-container > textarea {
    word-wrap: break-word; /* make sure the div and the textarea wrap words in the same way */
    box-sizing: border-box;
    padding: 2px;
    width: 100%;
}

.textarea-container > textarea {
    overflow: hidden;
    position: absolute;
    height: 100%;
}

.textarea-container > div {
    padding-bottom: 1.5em; /* A bit more than one additional line of text. */ 
    visibility: hidden;
    width: 100%;
}
<div class="textarea-container">
    <textarea id="textArea"></textarea>
    <div id="textCopy"></div>
</div>

|
  • 1

    Đây là một giải pháp tuyệt vời! Nhắc nhở duy nhất là các trình duyệt không hỗ trợ kích thước hộp (IE <7) sẽ không tính đúng chiều rộng và do đó bạn sẽ mất một số độ chính xác, nhưng nếu cuối cùng bạn sẽ để lại một khoảng trống bạn vẫn sẽ ổn Chắc chắn yêu nó vì sự đơn giản.

    – Võ Thu Bích 22:12:05 25/01/2011
  • 1

    Tôi đã tự do triển khai giải pháp này dưới dạng độc lập, sử dụng plugin jQuery đơn giản, không cần đánh dấu hoặc tạo kiểu. xion.io/jQuery.xarea trong trường hợp ai đó có thể sử dụng nó :)

    – Ngô Ðình Toàn 20:28:18 02/07/2012
  • 1

    cài đặt textCopy thành ẩn vẫn cho phép div ẩn chiếm không gian trong đánh dấu để nội dung textCopy trở nên lớn hơn, cuối cùng bạn sẽ có một thanh cuộn dọc theo toàn bộ chiều dài của trang của bạn ...

    – Hoàng Bảo Vân 16:56:51 22/01/2013
  • 1

    Một điều chỉnh tốt đẹp khác cho điều này; var text = $("#textArea").val().replace(/\n/g, '<br/>') + '&nbsp;';đảm bảo bạn không có hành vi giật khi đi từ một dòng mới trống ở cuối văn bản đến một dòng không trống, vì div ẩn đảm bảo bọc cho các chuỗi.

    – Hồ Hương Điệp 21:36:07 19/02/2015
  • 1

    @unwits cuộc gọi tuyệt vời khi thêm '& nbsp;' để thoát khỏi sự gia tăng kích thước đột ngột đó khi bạn thêm chữ cái đầu tiên vào một dòng mới - với tôi nó đã bị hỏng nếu không có điều này - điều này cần được thêm vào câu trả lời!

    – Tạ Ngọc Dũng 03:07:13 11/07/2015
38

Đây là một kỹ thuật khác để tự động hóa một vùng văn bản.

  • Sử dụng chiều cao pixel thay vì chiều cao dòng: xử lý chính xác hơn của đường bao nếu sử dụng phông chữ tỷ lệ.
  • Chấp nhận ID hoặc phần tử làm đầu vào
  • Chấp nhận tham số chiều cao tối đa tùy chọn - hữu ích nếu bạn không muốn khu vực văn bản phát triển vượt quá một kích thước nhất định (giữ tất cả trên màn hình, tránh phá vỡ bố cục, v.v.)
  • Đã thử nghiệm trên Firefox 3 và Internet Explorer 6

Mã: (JavaScript vanilla đồng bằng)

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";
   }
}

Bản trình diễn: (sử dụng jQuery, các mục tiêu trên textarea tôi đang nhập vào ngay bây giờ - nếu bạn đã cài đặt Fireorms , hãy dán cả hai mẫu vào bảng điều khiển và kiểm tra trên trang này)

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

    Đẹp, nhưng nó không "không phát triển" khi văn bản / dòng bị xóa khỏi textarea ..

    – Trịnh Xuân Thịnh 04:04:30 23/01/2009
  • 1

    @SMB - điều đó có lẽ sẽ không quá khó để thực hiện, chỉ cần thêm một điều kiện khác

    – Hoàng Hạnh Nga 07:57:58 09/01/2010
  • 1

    @Jason: Khi văn bản trong hộp không điền nó clientHeightscrollHeightbằng nhau, vì vậy bạn không thể sử dụng phương pháp này nếu bạn muốn vùng văn bản của mình co lại cũng như phát triển.

    – Hoàng Thế Dân 22:35:03 17/12/2010
  • 1

    Để đơn giản làm cho nó thu nhỏ lại, bạn chỉ cần thêm mã này trước dòng 6:if (text.clientHeight == text.scrollHeight) text.style.height = "20px";

    – Trịnh Diệu Hoa 07:18:36 20/10/2011
12

Có lẽ là giải pháp ngắn nhất:

jQuery(document).ready(function(){
    jQuery("#textArea").on("keydown keyup", function(){
        this.style.height = "1px";
        this.style.height = (this.scrollHeight) + "px"; 
    });
});

Bằng cách này, bạn không cần bất kỳ div ẩn hoặc bất cứ điều gì tương tự.

Lưu ý: bạn có thể phải chơi với this.style.height = (this.scrollHeight) + "px";tùy thuộc vào cách bạn tạo kiểu cho vùng văn bản (chiều cao dòng, phần đệm và loại nội dung đó).

|
8

Đây là phiên bản Prototype thay đổi kích thước một vùng văn bản không phụ thuộc vào số lượng cột trong vùng văn bản. Đây là một kỹ thuật ưu việt vì nó cho phép bạn kiểm soát vùng văn bản thông qua CSS cũng như có vùng văn bản có chiều rộng thay đổi. Ngoài ra, phiên bản này hiển thị số lượng ký tự còn lại. Mặc dù không được yêu cầu, đây là một tính năng khá hữu ích và dễ dàng bị loại bỏ nếu không mong muốn.

//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'
    });

    var remaining = this.options.get('max_length') - $F(this.textarea).length;
    this._remainingCharacters.update(Math.abs(remaining)  + ' characters ' + (remaining > 0 ? 'remaining' : 'over the limit'));
  }
});

Tạo widget bằng cách gọi new Widget.Textarea('element_id'). Các tùy chọn mặc định có thể được ghi đè bằng cách chuyển chúng dưới dạng một đối tượng, ví dụ new Widget.Textarea('element_id', { max_length: 600, min_height: 50}). Nếu bạn muốn tạo nó cho tất cả các textareas trên trang, hãy làm một cái gì đó như:

Event.observe(window, 'load', function() {
  $$('textarea').each(function(textarea) {
    new Widget.Textarea(textarea);
  });   
});
|
7

Đây là một giải pháp với JQuery:

$(document).ready(function() {
    var $abc = $("#abc");
    $abc.css("height", $abc.attr("scrollHeight"));
})

abclà một teaxtarea.

|
5

Kiểm tra liên kết dưới đây: 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
    });
});
|
3

Tôi đã làm một cái gì đó khá dễ dàng. Đầu tiên tôi đặt TextArea vào DIV. Thứ hai, tôi đã gọi readychức năng cho kịch bản này.

<div id="divTable">
  <textarea ID="txt" Rows="1" TextMode="MultiLine" />
</div>

$(document).ready(function () {
  var heightTextArea = $('#txt').height();
  var divTable = document.getElementById('divTable');
  $('#txt').attr('rows', parseInt(parseInt(divTable .style.height) / parseInt(altoFila)));
});

Đơn giản. Đó là chiều cao tối đa của div sau khi được hiển thị, chia cho chiều cao của một TextArea của một hàng.

|
3

Chỉ cần xem lại điều này, tôi đã làm cho nó gọn gàng hơn một chút (mặc dù ai đó có đầy đủ chai trên Prototype / JavaScript có thể đề xuất cải tiến?).

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;
  }
}

Chỉ cần nó gọi với:

new TextAreaResize('textarea_id_name_here');
|
2

Giải pháp của tôi không sử dụng jQuery (vì đôi khi chúng không phải giống nhau) ở bên dưới. Mặc dù nó chỉ được thử nghiệm trong Internet Explorer 7 , nhưng cộng đồng có thể chỉ ra tất cả các lý do điều này là sai:

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

Cho đến nay tôi thực sự thích cách nó hoạt động và tôi không quan tâm đến các trình duyệt khác, vì vậy tôi có thể sẽ áp dụng nó cho tất cả các văn bản của mình:

// 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
}
|
2

Giống như câu trả lời của @memical.

Tuy nhiên tôi tìm thấy một số cải tiến. Bạn có thể sử dụng height()hàm jQuery . Nhưng hãy lưu ý đến các pixel padding-top và padding-bottom. Nếu không thì textarea của bạn sẽ phát triển quá nhanh.

$(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);
  });
});
|
2

Tôi cần chức năng này cho bản thân mình, nhưng không ai trong số họ làm việc như tôi cần.

Vì vậy, tôi đã sử dụng mã của Orion và thay đổi nó.

Tôi đã thêm vào một chiều cao tối thiểu, để phá hủy nó không quá nhỏ.

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;
};
|
1

Sử dụng ASP.NET, chỉ cần làm điều này:

<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>
|
1

Đây là một hàm tôi vừa viết trong jQuery để làm điều đó - bạn có thể chuyển nó sang Prototype , nhưng chúng không hỗ trợ "tính sống" của jQuery để các phần tử được thêm bởi các yêu cầu Ajax sẽ không đáp ứng.

Phiên bản này không chỉ mở rộng mà còn co lại khi nhấn xóa hoặc xóa lùi.

Phiên bản này dựa trên jQuery 1.4.2.

Thưởng thức ;)

http://pastebin.com/SUKeBtnx

Sử dụng:

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

hoặc (bất kỳ bộ chọn jQuery nào chẳng hạn)

$("textarea").textareacontrol();

Nó đã được thử nghiệm trên Internet Explorer 7 / Internet Explorer 8 , Firefox 3.5 và Chrome. Tất cả đều hoạt động tốt.

|
1

Người dùng Internet Explorer, Safari, Chrome và Opera cần nhớ để thiết lập một cách rõ ràng giá trị chiều cao dòng trong CSS. Tôi làm một biểu định kiểu đặt các điều chỉnh ban đầu cho tất cả các hộp văn bản như sau.

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

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.