Tạo một textarea với tự động thay đổi kích thước


366

một chủ đề khác về điều này , mà tôi đã thử. Nhưng có một vấn đề: textareakhông thu nhỏ nếu bạn xóa nội dung. Tôi không thể tìm thấy bất kỳ cách nào để thu nhỏ nó về kích thước chính xác - clientHeightgiá trị trở lại là kích thước đầy đủ của textarea, chứ không phải nội dung của nó.

Mã từ trang đó là bên dưới:

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

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

window.onload = function() {
    document.getElementById("ta").onkeyup = function() {
      FitToContent( this, 500 )
    };
}

Câu trả lời được chấp nhận cho chủ đề bạn liên kết làm việc cho tôi. Thêm ngắt dòng sẽ mở rộng vùng văn bản và loại bỏ chúng thu nhỏ vùng văn bản. Bạn đang dùng trình duyệt nào?
nguy cơ tuyệt chủngMass

3
Chức năng của tôi không có lỗi. Nó là nhất thiết phải gõ dòng mới ở cuối dòng. Đây là giải pháp tốt hơn. james.padolsey.com/javascript/jquery-plugin-autoresize

Bạn có thể thử plugin của tôi cho việc này: github.com/AndrewDryga/jQuery.Textarea.Autoresize
Andrew Dryga


Tôi đã tạo một gói cho việc này nếu bạn đang sử dụng Reac
Martin Dawson

Câu trả lời:


230

Điều này hoạt động với tôi (Firefox 3.6 / 4.0 và Chrome 10/11):

var observe;
if (window.attachEvent) {
    observe = function (element, event, handler) {
        element.attachEvent('on'+event, handler);
    };
}
else {
    observe = function (element, event, handler) {
        element.addEventListener(event, handler, false);
    };
}
function init () {
    var text = document.getElementById('text');
    function resize () {
        text.style.height = 'auto';
        text.style.height = text.scrollHeight+'px';
    }
    /* 0-timeout to get the already changed text */
    function delayedResize () {
        window.setTimeout(resize, 0);
    }
    observe(text, 'change',  resize);
    observe(text, 'cut',     delayedResize);
    observe(text, 'paste',   delayedResize);
    observe(text, 'drop',    delayedResize);
    observe(text, 'keydown', delayedResize);

    text.focus();
    text.select();
    resize();
}
textarea {
    border: 0 none white;
    overflow: hidden;
    padding: 0;
    outline: none;
    background-color: #D0D0D0;
}
<body onload="init();">
<textarea rows="1" style="height:1em;" id="text"></textarea>
</body>

Nếu bạn muốn thử nó trên jsfiddle Nó bắt đầu với một dòng duy nhất và chỉ phát triển số lượng chính xác cần thiết. Nó là ổn cho một người textarea, nhưng tôi muốn viết một cái gì đó mà tôi sẽ có nhiều nhiều như vậytextarea (nhiều như một người thường có các dòng trong một tài liệu văn bản lớn). Trong trường hợp đó, nó thực sự chậm. (Trong Firefox, nó cực kỳ chậm.) Vì vậy, tôi thực sự muốn một cách tiếp cận sử dụng CSS thuần túy. Điều này có thể xảy ra với contenteditable, nhưng tôi muốn nó chỉ là bản rõ.


13
Nó làm! Tạo một jsfiddle cho ya: jsfiddle.net/CbqFv Hiện tại nó hoạt động trong Chrome, Firefox và IE8 - mặc dù nó có một chút trục trặc trong IE8. Khi bạn tăng hoặc giảm số lượng dòng, nó sẽ hoảng loạn một chút. Như bạn có thể thấy trong plugin tự động kích hoạt cho jQuery, họ đã khắc phục điều đó bằng cách nhân bản textarea, đặt chiều cao của nó thành tự động thay vì ban đầu, sau đó sử dụng nó để đặt chế độ cuộn trên bản gốc. Tôi đã làm điều đó trong fiddle cập nhật này: jsfiddle.net/CbqFv/2 Nó giải quyết vấn đề IE nhưng Firefox ngừng hoạt động.
Chris Moschini

3
@HelenNeely: Sau đó, không sử dụng id. Ví dụ, sử dụng một lớp và làm những gì init làm cho tất cả các phần tử của lớp đó. Đó nên là một nhiệm vụ mới bắt đầu.
panzi

3
@ DenilsonSá Nếu người ta chỉ có thể cho rằng chỉ những trình duyệt hiện đại được sử dụng thì web sẽ là một nơi tốt hơn.
panzi

2
Điều này sẽ không hoạt động tốt nếu một thanh cuộn được hình thành trong IE11. Nếu bạn sử dụng fiddle jsfiddle.net/CbqFv này và nhập các dòng cho đến khi bạn có một thanh cuộn, bạn sẽ thấy nó. Có ý kiến ​​gì không?
kaljak

6
Điều này phá vỡ hoàn toàn nếu textarea ở gần cuối trang dưới cùng - mọi thứ nhảy qua lại do style.height='auto'. Tôi nghi ngờ giải pháp là thêm một anh chị em ẩn chỉ được sử dụng để đo lường.
rr-

372

GIẢI PHÁP HOÀN THÀNH YÊU CẦU ĐƠN GIẢN

Cập nhật 2020-05-14 (Cải thiện hỗ trợ trình duyệt cho điện thoại di động và máy tính bảng)

Đoạn mã sau sẽ hoạt động:

  • Trên đầu vào chính.
  • Với văn bản dán (nhấp chuột phải & ctrl + v).
  • Với văn bản cắt (nhấp chuột phải & ctrl + x).
  • Với văn bản được tải sẵn.
  • Với tất cả các textarea (hộp văn bản nhiều dòng) trang web .
  • Với Firefox (v31-67 đã thử nghiệm).
  • Với Chrome (v37-74 đã thử nghiệm).
  • Với IE (v9-v11 đã thử nghiệm).
  • Với Edge (v14-v18 đã thử nghiệm).
  • Với Safari Safari .
  • Với trình duyệt Android .
  • Với chế độ nghiêm ngặt JavaScript .
  • w3c xác nhận.
  • Và được sắp xếp hợp lý và hiệu quả.

TÙY CHỌN 1 (Với jQuery)

Tùy chọn này yêu cầu jQuery và đã được thử nghiệm và đang hoạt động với 1.7.2 - 3.3.1

Đơn giản (Thêm mã jquery này vào tệp tập lệnh chính của bạn và quên nó đi.)

$('textarea').each(function () {
  this.setAttribute('style', 'height:' + (this.scrollHeight) + 'px;overflow-y:hidden;');
}).on('input', function () {
  this.style.height = 'auto';
  this.style.height = (this.scrollHeight) + 'px';
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea placeholder="Type, paste, cut text here...">PRELOADED TEXT.
This javascript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder="Type, paste, cut text here..."></textarea>

Test on jsfiddle


TÙY CHỌN 2 (JavaScript thuần)

Đơn giản (Thêm JavaScript này vào tệp tập lệnh chính của bạn và quên nó đi.)

const tx = document.getElementsByTagName('textarea');
for (let i = 0; i < tx.length; i++) {
  tx[i].setAttribute('style', 'height:' + (tx[i].scrollHeight) + 'px;overflow-y:hidden;');
  tx[i].addEventListener("input", OnInput, false);
}

function OnInput() {
  this.style.height = 'auto';
  this.style.height = (this.scrollHeight) + 'px';
}
<textarea placeholder="Type, paste, cut text here...">PRELOADED TEXT. This JavaScript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder="Type, paste, cut text here..."></textarea>

Test on jsfiddle


TÙY CHỌN 3 (Tiện ích mở rộng jQuery)

Hữu ích nếu bạn muốn áp dụng thêm chuỗi cho văn bản mà bạn muốn có kích thước tự động.

jQuery.fn.extend({
  autoHeight: function () {
    function autoHeight_(element) {
      return jQuery(element)
        .css({ 'height': 'auto', 'overflow-y': 'hidden' })
        .height(element.scrollHeight);
    }
    return this.each(function() {
      autoHeight_(this).on('input', function() {
        autoHeight_(this);
      });
    });
  }
});

Gọi với $('textarea').autoHeight()


CẬP NHẬT JAVASCRIPT VĂN BẢN

Khi đưa nội dung vào một vùng văn bản thông qua JavaScript sẽ nối thêm đoạn mã sau để gọi hàm trong tùy chọn 1.

$('textarea').trigger('input');

PRESET TEXTAREA HEIGHT

Để sửa chiều cao ban đầu của textarea, bạn sẽ cần thêm một điều kiện bổ sung:

const txHeight = 16;
const tx = document.getElementsByTagName("textarea");
for (let i = 0; i < tx.length; i++) {
  if (tx[i].value == '') {
    tx[i].setAttribute("style", "height:" + txHeight + "px;overflow-y:hidden;");
  } else {
    tx[i].setAttribute("style", "height:" + (tx[i].scrollHeight) + "px;overflow-y:hidden;");
  }
  tx[i].addEventListener("input", OnInput, false);
}

function OnInput(e) {
  this.style.height = "auto";
  this.style.height = (this.scrollHeight) + "px";
}
<textarea placeholder="Type, paste, cut text here...">PRELOADED TEXT. This JavaScript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder="Type, paste, cut text here..."></textarea>


12
Đây là một giải pháp tuyệt vời, sẽ dễ hiểu hơn một chút nếu tên phương thức và tên tham số được cập nhật thành tên thật thay vì các chữ cái riêng lẻ.
Chris Marisic

5
@Obsidian Cảm ơn! Tôi chỉ cần tìm ra lý do tại sao tôi luôn nhận được một 0 bù Tôi Tôi đặt textarea trong một phương thức Bootstrap! Vì phương thức bị ẩn lúc đầu, textarea trong đó sẽ có 0 cuộnHeight
WTIFS

7
@Obsidian Tuyệt vời !! (Lựa chọn 3). Đây this.style.height = 'auto';là sửa chữa hành vi kỳ diệu. Tôi đã rất thất vọng tại sao scrollHeight lại rất kỳ lạ trong hành vi. Chiều cao để tự động, sau đó khớp với cuộnHeight trong cùng một chu kỳ kết xuất vẫn làm tôi suy nghĩ về cách nó 'khắc phục' vấn đề này mặc dù về mặt kỹ thuật chỉ nên vẽ chiều cao thứ hai.
ít bit

2
Tôi đã thử tùy chọn 3 trong Chrome ngày hôm nay và phải thực hiện một vài điều chỉnh. 1) Nó sẽ không luôn thay đổi kích thước xuống một cách chính xác nếu bạn có quá trình chuyển đổi "chiều cao" hoặc "tất cả" trên vùng văn bản. Tôi khuyên bạn không nên sử dụng các hiệu ứng chuyển tiếp ảnh hưởng đến chiều cao. 2) ScrollHeight đã trả về một phần nhỏ của hai hàng có chiều cao (có lẽ vì đó là mặc định cho textareas trong Chrome) nhưng nếu bạn thay đổi this.style.height = 'auto'; tới đây.style.height = '0px'; và thêm chiều cao tối thiểu để ngăn trạng thái ban đầu thực sự về 0, scrollHeight sẽ trả lại chính xác một hàng chiều cao khi thích hợp.
ZorroDeLaArena

3
@Obsidian Bạn có thể giải thích cách this.style.height = 'auto';khắc phục hành vi của scrollHeight không? Đó chỉ là ma thuật.
sidney

63

Giải pháp jQuery điều chỉnh css để phù hợp với yêu cầu của bạn

css ...

div#container textarea {
    min-width: 270px;
    width: 270px;
    height: 22px;
    line-height: 24px;
    min-height: 22px;
    overflow-y: hidden; /* fixes scrollbar flash - kudos to @brettjonesdev */
    padding-top: 1.1em; /* fixes text jump on Enter keypress */
}

javascript ...

// auto adjust the height of
$('#container').delegate( 'textarea', 'keydown', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keydown();

HOẶC thay thế cho jQuery 1.7 + ...

// auto adjust the height of
$('#container').on( 'keyup', 'textarea', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keyup();

Tôi đã tạo một câu đố với kiểu dáng tối thiểu tuyệt đối làm điểm khởi đầu cho các thử nghiệm của bạn ... http://jsfiddle.net/53eAy/951/


5
Điều này là tốt, nhưng tôi sẽ thêm overflow-y: hidden;vào css để ngăn thanh cuộn nhấp nháy nhanh khi thay đổi kích thước.
brettjonesdev

Không hoàn toàn chắc chắn, nhưng không có nó, khu vực văn bản phát triển quá nhiều. Tôi nghĩ rằng nó phải làm theo cách mà các yếu tố cuộn được tính toán.
chim

1
Sử dụng nhiều sự kiện để thực hiện công việc cho tính thực tế của kịch bản $('textarea.auto-resize').on('change cut paste drop keyup', function(){...})
raxith

1
Nhảy lung tung như điên trong Chrome 40 Win 8.1 trên các văn bản dài hơn chế độ xem. Hiển thị nó khá không sử dụng được.
trượt băng

1
Giữ kết quả nhập (dòng mới) trong cuộn. Kích thước không điều chỉnh cho đến khi phím được phát hành.
Niels Abildgaard

28
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Textarea autoresize</title>
    <style>
    textarea {
        overflow: hidden;
    }
    </style>
    <script>
    function resizeTextarea(ev) {
        this.style.height = '24px';
        this.style.height = this.scrollHeight + 12 + 'px';
    }

    var te = document.querySelector('textarea');
    te.addEventListener('input', resizeTextarea);
    </script>
</head>
<body>
    <textarea></textarea>
</body>
</html>

Đã thử nghiệm trong Firefox 14 và Chromium 18. Các số 24 và 12 là tùy ý, kiểm tra để xem những gì phù hợp với bạn nhất.

Bạn có thể làm mà không có thẻ kiểu và tập lệnh, nhưng nó trở nên hơi lộn xộn (đây là kiểu HTML + JS cũ và không được khuyến khích).

<textarea style="overflow: hidden" onkeyup="this.style.height='24px'; this.style.height = this.scrollHeight + 12 + 'px';"></textarea>

Chỉnh sửa: mã hiện đại hóa. Đã thay đổi thuộc tính onkeyup thành addEventListener.
Chỉnh sửa: keydown hoạt động tốt hơn keyup
Chỉnh sửa: khai báo chức năng trước khi sử dụng
Edit: input hoạt động tốt hơn keydown (thnx @ WASD42 & @ MA-Maddin)

jsfiddle


3
Điều này có một số nhược điểm: 1) Textarea sẽ không được thay đổi kích thước sau đó người dùng chỉ dán một cái gì đó bằng các nút chuột của mình; 2) Nếu người dùng sẽ dán thứ gì đó bằng bàn phím (Ctrl + V) thì textarea sẽ chỉ được thay đổi kích thước khi anh ta sẽ nhả Ctrl. Nếu người dùng sẽ nhấn Ctrl + V nhiều lần thì textarea sẽ chỉ phát triển sau lần cuối cùng. Bạn nên thêm chức năng tương tự để dán, cắt, thay đổi và thả các sự kiện quá.
WASD42

Vì vậy, chỉ sử dụng inputsự kiện thay thế. Xem stackoverflow.com/a/14029861/1951524
Martin Schneider

Phiên bản cải tiến với nhiều textareahỗ trợ dưới dạng một lớp lót:document.querySelectorAll('textarea').forEach(function(te){ te.addEventListener("input", function() { this.style.height='24px'; this.style.height=this.scrollHeight+12+'px'; }); });
Meisner

1
@Meisner Nó ngắn hơn, nhưng tôi sẽ không nói nó "được cải thiện". Với chức năng ẩn danh, không có cách nào để gọi removeEventListenervà dọn sạch người nghe sự kiện của bạn. Điều này đặc biệt quan trọng khi tạo trình lắng nghe sự kiện ở khắp mọi nơi trong vòng lặp forEach. Thêm vào đó, theo quan điểm của tôi, khả năng đọc quan trọng hơn nhiều so với sự đồng nhất.
GijsjanB

đối với những người khác và tương lai với tôi, đảm bảo rằng thuộc box-sizing: border-box;tính được đặt hoặc nếu không thì vùng văn bản mở rộng 4px cho mỗi sự kiện onInput. Tôi đã dành như 3 giờ cho đến khi tôi nhận ra đây là vấn đề.
AIon

24

Giải pháp tốt nhất (hoạt động và ngắn gọn) đối với tôi là:

    $(document).on('input', 'textarea', function () {
        $(this).outerHeight(38).outerHeight(this.scrollHeight); // 38 or '1em' -min-height
    }); 

Nó hoạt động như một bùa mê mà không có bất kỳ nhấp nháy nào với dán (cũng có chuột), cắt, nhập và nó co lại với kích thước phù hợp.

Xin hãy xem jsFiddle .


Khủng khiếp!!! thỏa thuận một dòng! Câu hỏi ngớ ngẩn Tôi có thể thêm một hình ảnh động khi nó thay đổi kích thước? Giống như hộp văn bản sắp xếp thay đổi kích thước thay vì sau đó nhảy đến kích thước?
dùng2513846

1
@ user2513846 Có vẻ như không thể thực hiện được bằng thiết kế chỉnh sửa nhiều dòng. Tôi đã làm một ví dụ về kích thước textarea hoạt hình: jsfiddle.net/yk2g333e Như bạn biết con trỏ văn bản đi xuống tại và của dòng hoặc dấu mũ, vì vậy nếu không có tạm dừng tại thời điểm này thì không có gì để hoạt hình. Nhưng tạm dừng sẽ gây khó chịu cho người dùng.
vatavale

1
@ user2513846 Tuy nhiên, với một dòng trống nữa ở cuối textarea, có thể có hình ảnh động mượt mà: jsfiddle.net/p23erdfr
vatavale

16

Bạn đang sử dụng giá trị cao hơn của ứng dụng khách hiện tại và cuộn nội dung. Khi bạn làm cho cuộn nhỏ hơn bằng cách xóa nội dung, vùng được tính không thể nhỏ hơn vì clientHeight, trước đây được đặt bởi style.height, đang giữ mở. Thay vào đó, bạn có thể lấy tối đa () của scrollHeight và giá trị chiều cao tối thiểu bạn đã xác định trước hoặc tính toán từ textarea.rows.

Nói chung, có lẽ bạn không nên thực sự dựa vào scrollHeight trên các điều khiển biểu mẫu. Ngoài scrollHeight thường được hỗ trợ ít hơn so với một số tiện ích mở rộng IE khác, HTML / CSS không nói gì về cách điều khiển biểu mẫu được triển khai trong nội bộ và bạn không đảm bảo cuộn sẽ không có ý nghĩa gì. (Theo truyền thống, một số trình duyệt đã sử dụng các tiện ích HĐH cho tác vụ, khiến cho việc tương tác CSS và DOM trên các phần bên trong của chúng là không thể.) Ít nhất là đánh hơi sự tồn tại của scrollHeight / clientHeight trước khi thử kích hoạt hiệu ứng.

Một cách tiếp cận khác có thể có để tránh vấn đề nếu điều quan trọng là nó hoạt động rộng rãi hơn có thể là sử dụng một div ẩn có kích thước tương đương với textarea và đặt cùng một phông chữ. Khi gõ phím, bạn sao chép văn bản từ textarea sang nút văn bản trong div ẩn (nhớ thay thế '\ n' bằng ngắt dòng và thoát '<' / '&' đúng cách nếu bạn đang sử dụng InternalHTML). Sau đó, chỉ cần đo offset của divHeight sẽ cung cấp cho bạn chiều cao bạn cần.


1
Những trình duyệt nào được cho là có vấn đề với scrollHeighttextareas? Hoạt động tốt với các phiên bản hiện tại của IE, Firefox và Opera ...
Christoph

1
Người duy nhất tôi phải trao là Konqueror, trả về clientHeight dưới dạng scrollHeight. Đây là một hành vi bạn có thể mong đợi trừ khi trình duyệt áp dụng mô hình hộp CSS cho phần bên trong của các widget, điều mà chúng không phải lúc nào cũng thực hiện và tiêu chuẩn không nói rằng chúng phải làm.
bobince

14

Nếu bạn không cần hỗ trợ IE8, bạn có thể sử dụng inputsự kiện này:

var resizingTextareas = [].slice.call(document.querySelectorAll('textarea[autoresize]'));

resizingTextareas.forEach(function(textarea) {
  textarea.addEventListener('input', autoresize, false);
});

function autoresize() {
  this.style.height = 'auto';
  this.style.height = this.scrollHeight+'px';
  this.scrollTop = this.scrollHeight;
  window.scrollTo(window.scrollLeft,(this.scrollTop+this.scrollHeight));
}

Bây giờ bạn chỉ cần thêm một số CSS và bạn đã hoàn tất:

textarea[autoresize] {
  display: block;
  overflow: hidden;
  resize: none;
}

Sử dụng:

<textarea autoresize>Type here and Ill resize.</textarea>

Bạn có thể đọc thêm về cách nó hoạt động trên bài viết trên blog của tôi .


1
Giải pháp tốt, nhưng cần sửa chữa ít. Khi nội dung của textarea được tải f.ex. từ cơ sở dữ liệu, textarea ở lại nhỏ. Bạn phải kích hoạt inputsự kiện trong quá trình khởi tạo trong chu trình foreach.
Ajax

11

kich thươc tự động

https://github.com/jackmoore/autosize

Chỉ hoạt động, độc lập, là phổ biến (3.0k + sao GitHub tính đến tháng 10 năm 2018), có sẵn trên cdnjs ) và nhẹ (~ 3,5k). Bản giới thiệu:

<textarea id="autosize" style="width:200px;">a
J   b
c</textarea>
<script src="https://cdnjs.cloudflare.com/ajax/libs/autosize.js/4.0.2/autosize.min.js"></script>
<script>autosize(document.querySelectorAll('#autosize'));</script>

BTW, nếu bạn đang sử dụng trình chỉnh sửa ACE, hãy sử dụng maxLines: Infinity: Tự động điều chỉnh độ cao cho nội dung trong trình chỉnh sửa Ace Cloud 9


2
Phiên bản 2 đã được phát hành vào tháng 2 năm 2015. Nó đã trở nên đơn giản hơn và không phụ thuộc vào jQuery nữa
giòn giòn

Xin lỗi, nó không hoạt động. Có lẽ tôi đã ở trong trình duyệt khác .. vì vậy, tôi nghĩ sẽ tốt hơn nếu bạn bỏ qua nhận xét của tôi ..
Toni Michel Caubet

@ToniMichelCaubet ah, OK có thể có vấn đề về CDN rồi. Để tôi kiểm tra.
Ciro Santilli 郝海东 冠状 病 事件

Các autosizeplugin không cho phép thay đổi kích thước bằng cách sử dụng biểu tượng thay đổi kích thước trong textarea.
j4v1

7

Tìm thấy một lớp lót từ đây ;

<textarea name="text" oninput="this.style.height = ''; this.style.height = this.scrollHeight +'px'"></textarea>

6

Có ai đã xem xét nội dung? Không phải loay hoay với việc cuộn, một điều duy nhất tôi thích về nó là nếu bạn có kế hoạch lưu dữ liệu mờ ... và rõ ràng, nó tương thích trên tất cả các trình duyệt phổ biến: http://caniuse.com/#feat = nội dung

Chỉ cần tạo kiểu cho nó trông giống như một hộp văn bản và nó tự động hóa ... Làm cho chiều cao tối thiểu của nó thành chiều cao văn bản ưa thích và có ở đó.

Điều thú vị về phương pháp này là bạn có thể lưu và gắn thẻ trên một số trình duyệt.

http://jsfiddle.net/gbutiri/v31o8xfo/

<style>
.autoheight {
    min-height: 16px;
    font-size: 16px;
    margin: 0;
    padding: 10px;
    font-family: Arial;
    line-height: 16px;
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    overflow: hidden;
    resize: none;
    border: 1px solid #ccc;
    outline: none;
    width: 200px;
}
</style>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$(document).on('blur','.autoheight',function(e) {
    var $this = $(this);
    // The text is here. Do whatever you want with it.
    console.log($this.html());
});

</script>
<div class="autoheight contenteditable" contenteditable="true">Mickey Mouse</div>

Chrome sẽ thêm các phần tử <div> trên ENTER.
sbaechler

contenteditablelà tốt, nhưng nếu bạn muốn bản rõ nó cần một loạt các tùy chọn như -webkit-user-modify: read-write-plaintext-onlywhite-space: pre-wrap.
mik01aj

@_sbaechler: <div> s bị bỏ qua khi sử dụng [dom-element].innerText. @WebmasterG IMHO sẽ rất tốt nếu bỏ qua jquery (để minh bạch) và đưa ví dụ trên trang này thông qua Đoạn mã có thể chạy thay vì trên jsfiddle.
adabru

4

Tôi đã sử dụng mã sau đây cho nhiều textareas. Hoạt động tốt trong Chrome 12, Firefox 5 và IE 9, ngay cả với các hành động xóa, cắt và dán được thực hiện trong vùng văn bản.

<!-- language: lang-html -->
<style type='text/css'>
textarea { border:0 none; overflow:hidden; outline:none; background-color:#eee }
</style>
<textarea style='height:100px;font-family:arial' id="txt1"></textarea>
<textarea style='height:125px;font-family:arial' id="txt2"></textarea>
<textarea style='height:150px;font-family:arial' id="txt3"></textarea>
<textarea style='height:175px;font-family:arial' id="txt4"></textarea>
<script type='text/javascript'>
function attachAutoResizeEvents()
{   for(i=1;i<=4;i++)
    {   var txtX=document.getElementById('txt'+i)
        var minH=txtX.style.height.substr(0,txtX.style.height.indexOf('px'))
        txtX.onchange=new Function("resize(this,"+minH+")")
        txtX.onkeyup=new Function("resize(this,"+minH+")")
        txtX.onchange(txtX,minH)
    }
}
function resize(txtX,minH)
{   txtX.style.height = 'auto' // required when delete, cut or paste is performed
    txtX.style.height = txtX.scrollHeight+'px'
    if(txtX.scrollHeight<=minH)
        txtX.style.height = minH+'px'
}
window.onload=attachAutoResizeEvents
</script>

4

Có một cách tiếp cận hơi khác nhau.

<div style="position: relative">
  <pre style="white-space: pre-wrap; word-wrap: break-word"></pre>
  <textarea style="position: absolute; top: 0; left: 0; width: 100%; height: 100%"></textarea>
</div>

Ý tưởng là sao chép văn bản từ textareavào prevà để CSS đảm bảo rằng chúng có cùng kích thước.

Lợi ích là các khung trình bày các công cụ đơn giản để di chuyển văn bản xung quanh mà không chạm vào bất kỳ sự kiện nào. Cụ thể, trong AngularJS bạn sẽ thêm một ng-model="foo" ng-trim="false"đến textareang-bind="foo + '\n'"đến pre. Xem một câu đố .

Chỉ cần chắc chắn rằng precó cùng kích thước phông chữ như textarea.


1
" Chỉ cần đảm bảo rằng precó cùng kích thước phông chữ nhưtextarea " - Chúng cần giống nhau line-heightvà cùng một lượng paddingvà / hoặc borderquá. Đây là giải pháp tốt nhất cho Angular.
Jamie Barker

4

Các công việc sau đây để cắt, dán, v.v., bất kể những hành động đó là từ chuột, phím tắt, chọn tùy chọn từ thanh menu ... một số câu trả lời có cách tiếp cận tương tự nhưng chúng không tính đến hộp- Kích thước, đó là lý do tại sao họ áp dụng không đúng phong cách overflow: hidden .

Tôi làm như sau, cũng hoạt động tốt với max-heightrowscho chiều cao tối thiểu và tối đa.

function adjust() {
  var style = this.currentStyle || window.getComputedStyle(this);
  var boxSizing = style.boxSizing === 'border-box'
      ? parseInt(style.borderBottomWidth, 10) +
        parseInt(style.borderTopWidth, 10)
      : 0;
  this.style.height = '';
  this.style.height = (this.scrollHeight + boxSizing) + 'px';
};

var textarea = document.getElementById("ta");
if ('onpropertychange' in textarea) { // IE
  textarea.onpropertychange = adjust;
} else if ('oninput' in textarea) {
  textarea.oninput = adjust;
}
setTimeout(adjust.bind(textarea));
textarea {
  resize: none;
  max-height: 150px;
  border: 1px solid #999;
  outline: none;
  font: 18px sans-serif;
  color: #333;
  width: 100%;
  padding: 8px 14px;
  box-sizing: border-box;
}
<textarea rows="3" id="ta">
Try adding several lines to this.
</textarea>

Để hoàn thiện tuyệt đối, bạn nên gọi adjusthàm trong một vài trường hợp nữa:

  1. Cửa sổ thay đổi kích thước các sự kiện, nếu chiều rộng của textarea thay đổi với thay đổi kích thước cửa sổ hoặc các sự kiện khác làm thay đổi độ rộng của vùng văn bản
  2. Khi textarea's displaythay đổi thuộc tính phong cách, ví dụ như khi nó đi từ none(ẩn) đểblock
  3. Khi giá trị của textareathay đổi được lập trình

Lưu ý rằng việc sử dụng window.getComputedStylehoặc nhận currentStylecó thể hơi tốn kém về mặt tính toán, vì vậy bạn có thể muốn lưu trữ kết quả vào bộ đệm.

Hoạt động cho IE6, vì vậy tôi thực sự hy vọng rằng sự hỗ trợ đủ tốt.


4

Là một cách tiếp cận khác, bạn có thể sử dụng một <span>điều chỉnh tự động kích thước của nó. Bạn sẽ cần làm cho nó có thể chỉnh sửa bằng cách thêm thuộc contenteditable="true"tính và bạn đã hoàn tất:

div {
  width: 200px;
}

span {
  border: 1px solid #000;
  padding: 5px;
}
<div>
  <span contenteditable="true">This text can be edited by the user</span>
</div>

Vấn đề duy nhất với phương pháp này là nếu bạn muốn gửi giá trị như một phần của biểu mẫu, bạn sẽ phải tự mình làm điều đó trong JavaScript. Làm như vậy là tương đối dễ dàng. Ví dụ: bạn có thể thêm một trường ẩn và trong trường onsubmithợp biểu mẫu gán giá trị của spantrường bị ẩn, sau đó sẽ được gửi tự động cùng với biểu mẫu.


Đã có câu trả lời bằng cách sử dụng nội dung trên trang này: stackoverflow.com/questions/454202/iêu
adabru

@adabru Có, nhưng hai câu trả lời không giống nhau. Toyota tạo ra những chiếc xe màu đỏ và Ford cũng tạo ra những chiếc xe màu đỏ, nhưng chúng khác nhau, phải không? Nếu bạn thích câu trả lời khác nhiều hơn, sau đó đi với nó. Nhưng có những người đánh giá cao câu trả lời của tôi hơn và đi với nó. Có các lựa chọn khác nhau là tốt.
Racil Hilan

3

Một chút sửa chữa. Hoạt động hoàn hảo trong Opera

  $('textarea').bind('keyup keypress', function() {
      $(this).height('');
      var brCount = this.value.split('\n').length;
      this.rows = brCount+1; //++ To remove twitching
      var areaH = this.scrollHeight,
          lineHeight = $(this).css('line-height').replace('px',''),
          calcRows = Math.floor(areaH/lineHeight);
      this.rows = calcRows;
  });

hoạt động miễn là dòng của bạn không tràn - thì chúng sẽ không phù hợp.
Tomáš Kafka

hoạt động tốt, tuyệt vời (firefox 72)
Mikeys4u

2

Tôi biết một cách ngắn gọn và chính xác để thực hiện điều này với jquery. Không cần thêm div ẩn và hoạt động trong hầu hết trình duyệt

<script type="text/javascript">$(function(){
$("textarea").live("keyup keydown",function(){
var h=$(this);
h.height(60).height(h[0].scrollHeight);//where 60 is minimum height of textarea
});});

</script>

jQuery .live()đã bị phản đối. api.jquery.com/live Bạn thường muốn sử dụng .on()thay thế.
Luke

2

Tôi không biết có ai đề cập đến cách này không nhưng trong một số trường hợp, có thể thay đổi kích thước chiều cao bằng các hàng Thuộc tính

textarea.setAttribute('rows',breaks);

Bản giới thiệu


1
Điều đó chỉ hoạt động nếu bạn có white-space: nowrap;. Khi một dòng kết thúc tốt đẹp đến một dòng khác mà không ngắt dòng, textarea sẽ không được điều chỉnh đúng nữa.
Yeti

2

Đây là một chỉ thị angularjs cho câu trả lời của panzi.

 module.directive('autoHeight', function() {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                element = element[0];
                var resize = function(){
                    element.style.height = 'auto';
                    element.style.height = (element.scrollHeight)+'px';
                };
                element.addEventListener('change', resize, false);
                element.addEventListener('cut',    resize, false);
                element.addEventListener('paste',  resize, false);
                element.addEventListener('drop',   resize, false);
                element.addEventListener('keydown',resize, false);

                setTimeout(resize, 100);
            }
        };
    });

HTML:

<textarea ng-model="foo" auto-height></textarea>

Bạn nên sử dụng $ timeout hơn setTimout - điều này sẽ đảm bảo rằng mô hình được khởi tạo (không cần chỉ định mili giây - nó sẽ được thực hiện sau chu trình tiêu hóa Angular). Ngoài ra phần tử = phần tử [0]; là một thực tiễn rất tệ ... Dù sao, giải pháp là không tốt cho tôi vì tôi cần văn bản là một dòng cho đến khi có nhiều văn bản hơn.
Karol Websky

2

Bạn có thể sử dụng JQuery để mở rộng textareakhi gõ:

$(document).find('textarea').each(function () {
  var offset = this.offsetHeight - this.clientHeight;

  $(this).on('keyup input focus', function () {
    $(this).css('height', 'auto').css('height', this.scrollHeight + offset);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div>
<textarea name="note"></textarea>
<div>


Giải pháp sạch nhất. nhưng vì chúng ta nên ngừng sử dụng jQuery: textarea.addEventListener ('keyup', () => {textarea.style.height = 0; textarea.style.height = ${textarea.scrollHeight}px;});
Toni Michel Caubet

2

Những người muốn đạt được điều tương tự trong các phiên bản mới của Angular.

Lấy văn bảnArea phần tửRef.

@ViewChild('textArea', { read: ElementRef }) textArea: ElementRef;

public autoShrinkGrow() {
    textArea.style.overflow = 'hidden';
    textArea.style.height = '0px';
    textArea.style.height = textArea.scrollHeight + 'px';
}

<textarea (keyup)="autoGrow()" #textArea></textarea>

Tôi cũng đang thêm một trường hợp sử dụng khác có thể hữu ích cho một số người dùng đang đọc chủ đề, khi người dùng muốn tăng chiều cao của vùng văn bản lên chiều cao nhất định và sau đó có thể overflow:scrollsử dụng phương pháp này để đạt được trường hợp sử dụng được đề cập.

  public autoGrowShrinkToCertainHeight() {
    const textArea = this.textArea.nativeElement;
    if (textArea.scrollHeight > 77) {
      textArea.style.overflow = 'auto';
      return;
    }
    else {
      textArea.style.overflow = 'hidden';
      textArea.style.height = '0px';
      textArea.style.height = textArea.scrollHeight + 'px';
    }
  }

1

Một số câu trả lời ở đây không giải thích cho phần đệm.

Giả sử bạn có một tối đa bạn không muốn đi qua, điều này làm việc cho tôi:

    // obviously requires jQuery

    // element is the textarea DOM node

    var $el = $(element);
    // inner height is height + padding
    // outerHeight includes border (and possibly margins too?)
    var padding = $el.innerHeight() - $el.height();
    var originalHeight = $el.height();

    // XXX: Don't leave this hardcoded
    var maxHeight = 300;

    var adjust = function() {
        // reset it to the original height so that scrollHeight makes sense
        $el.height(originalHeight);

        // this is the desired height (adjusted to content size)
        var height = element.scrollHeight - padding;

        // If you don't want a maxHeight, you can ignore this
        height = Math.min(height, maxHeight);

        // Set the height to the new adjusted height
        $el.height(height);
    }

    // The input event only works on modern browsers
    element.addEventListener('input', adjust);

1

Một cách tiếp cận thậm chí đơn giản hơn, gọn gàng hơn là:

// adjust height of textarea.auto-height
$(document).on( 'keyup', 'textarea.auto-height', function (e){
    $(this).css('height', 'auto' ); // you can have this here or declared in CSS instead
    $(this).height( this.scrollHeight );
}).keyup();

// và CSS

textarea.auto-height {
    resize: vertical;
    max-height: 600px; /* set as you need it */
    height: auto;      /* can be set here of in JS */
    overflow-y: auto;
    word-wrap:break-word
}

Tất cả những gì cần thiết là thêm .auto-heightlớp vào bất kỳ textareabạn muốn nhắm mục tiêu.

Đã thử nghiệm trong FF, Chrome và Safari. Hãy cho tôi biết nếu điều này không làm việc cho bạn, vì bất kỳ lý do. Nhưng, đây là cách sạch nhất và đơn giản nhất mà tôi thấy nó hoạt động. Và nó hoạt động rất tốt! : D


Bạn đã cố gắng để loại bỏ văn bản sau khi chỉnh sửa? Có phải văn bản sụp đổ?
18C

1

Mã này hoạt động để dán và chọn xóa cũng.

onKeyPressTextMessage = function(){
			var textArea = event.currentTarget;
    	textArea.style.height = 'auto';
    	textArea.style.height = textArea.scrollHeight + 'px';
};
<textarea onkeyup="onKeyPressTextMessage(event)" name="welcomeContentTmpl" id="welcomeContent" onblur="onblurWelcomeTitle(event)" rows="2" cols="40" maxlength="320"></textarea>

Đây là JSFiddle


1

Tôi khuyên dùng thư viện javascript từ http://javierjulio.github.io/textarea-autosize .

Mỗi bình luận, thêm codeblock ví dụ về việc sử dụng plugin:

<textarea class="js-auto-size" rows="1"></textarea>

<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="jquery.textarea_autosize.min.js"></script>
<script>
$('textarea.js-auto-size').textareaAutoSize();
</script>

CSS yêu cầu tối thiểu:

textarea {
  box-sizing: border-box;
  max-height: 160px; // optional but recommended
  min-height: 38px;
  overflow-x: hidden; // for Firefox (issue #5)
}

1

MakeTextAreaResisable sử dụng qQuery

function MakeTextAreaResisable(id) {
    var o = $(id);
    o.css("overflow-y", "hidden");

    function ResizeTextArea() {
        o.height('auto');
        o.height(o[0].scrollHeight);
    }

    o.on('change', function (e) {
        ResizeTextArea();
    });

    o.on('cut paste drop keydown', function (e) {
        window.setTimeout(ResizeTextArea, 0);
    });

    o.focus();
    o.select();
    ResizeTextArea();
}

1

Không có câu trả lời nào có vẻ hiệu quả. Nhưng cái này hoạt động với tôi: https://coderwall.com/p/imkqoq/resize-textarea-to-fit-content

$('#content').on( 'change keyup keydown paste cut', 'textarea', function (){
    $(this).height(0).height(this.scrollHeight);
}).find( 'textarea' ).change();

Đây phải là câu trả lời được chấp nhận, mặc dù nó đủ để lắng nghe các sự kiện "keyup"
Bob Ross

1

Cách thực hiện của tôi rất đơn giản, đếm số lượng dòng trong đầu vào (và tối thiểu 2 hàng để cho thấy rằng đó là một vùng văn bản):

textarea.rows = Math.max(2, textarea.value.split("\n").length) // # oninput

ví dụ làm việc đầy đủ với kích thích: https://jsbin.com/kajosolini/1/edit?html,js,output

(và điều này hoạt động với tay cầm thay đổi kích thước thủ công của trình duyệt)


2
Điều này chỉ hoạt động nếu bạn ngắt dòng bằng cách nhấn "enter". Nếu văn bản của bạn dài hơn chiều rộng của textarea nhưng bạn không nhấn "enter", nó sẽ không mở rộng.
Nathalia Xavier

1

Câu trả lời được chấp nhận là hoạt động tốt. Nhưng đó là rất nhiều mã cho chức năng đơn giản này. Các mã dưới đây sẽ làm thủ thuật.

   $(document).on("keypress", "textarea", function (e) {
    var height = $(this).css("height");
    var iScrollHeight = $(this).prop("scrollHeight");
    $(this).css('height',iScrollHeight);
    });

0

Đây là những gì tôi đã làm trong khi sử dụng MVC HTML Helper cho TextArea. Tôi có khá nhiều yếu tố textarea nên phải phân biệt chúng bằng Model Id.

 @Html.TextAreaFor(m => m.Text, 2, 1, new { id = "text" + Model.Id, onkeyup = "resizeTextBox(" + Model.Id + ");" })

và trong kịch bản đã thêm điều này:

   function resizeTextBox(ID) {            
        var text = document.getElementById('text' + ID);
        text.style.height = 'auto';
        text.style.height = text.scrollHeight + 'px';            
    }

Tôi đã thử nghiệm nó trên IE10 và Firefox23


0

Bạn có thể sử dụng mã này:

Bản thảo:

jQuery.fn.extend autoHeightTextarea: ->
  autoHeightTextarea_ = (element) ->
    jQuery(element).css(
      'height': 'auto'
      'overflow-y': 'hidden').height element.scrollHeight

  @each ->
    autoHeightTextarea_(@).on 'input', ->
      autoHeightTextarea_ @

$('textarea_class_or_id`').autoHeightTextarea()

Javascript

jQuery.fn.extend({
  autoHeightTextarea: function() {
    var autoHeightTextarea_;
    autoHeightTextarea_ = function(element) {
      return jQuery(element).css({
        'height': 'auto',
        'overflow-y': 'hidden'
      }).height(element.scrollHeight);
    };
    return this.each(function() {
      return autoHeightTextarea_(this).on('input', function() {
        return autoHeightTextarea_(this);
      });
    });
  }
});

$('textarea_class_or_id`').autoHeightTextarea();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.