使用Prototype Autosizing textarea

我目前正在为我工​​作的公司开发内部销售应用程序,而且我有一个允许用户更改送货地址的表单。

现在我认为它看起来会更好,如果我用于主要地址细节的textarea只占用文本的区域,并且在文本改变时自动resize。

这是当前的截图。

ISO地址

有任何想法吗?


@克里斯

好点,但是我想要调整它的原因。 我想要占用的区域是其中包含的信息的区域。 正如你在屏幕截图中看到的那样,如果我有一个固定的textarea,它会占用垂直空间的一大笔费用。

我可以减less字体,但我需要的地址大而可读。 现在我可以减小文本区域的大小,但是我有一个地址线需要3或4(一个需要5)行的人有问题。 需要让用户使用滚动条是一个主要的禁忌。

我想我应该更具体一点。 我在垂直resize之后,宽度并不重要。 唯一的问题是,当窗口宽度太小时(正如你在屏幕截图中看到的那样),ISO号码(大“1”)被推到地址下。

这不是要有一个gimick; 这是关于有一个用户可以编辑的文本字段,不会占用不必要的空间,但会显示其中的所有文本。

虽然如果有人想出另外一种方法来解决这个问题,我也是这样认为的。


我修改了一些代码,因为它有点奇怪。 我把它改成在关键字上激活,因为它不考虑刚input的字符。

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

当Facebook写在人们的墙上时,Facebook就是这样做的,但只能垂直resize。

由于文字换行,长行等,水平resize会让我感到混乱,但垂直resize似乎相当安全和美观。

我所知道的Facebook使用新手都没有提到任何有关它或混淆。 我会用这个作为传闻的证据来说'去吧,实施它'。

一些使用Prototype的 JavaScript代码(因为这就是我所熟悉的):

 <!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:很显然,这个JavaScript代码是非常天真的,没有经过很好的testing,你可能不希望在文本框中使用它,但是你会得到一个大概的想法。

对这些答案的一个改进是让CSS做更多的工作。

基本的路线似乎是:1)将textarea的内容复制到一个隐藏的div中,2)让浏览器做这个div的高度计算,然后3)把textarea的高度设置到这个高度。 通过让CSS处理textarea的大小,可以省略步骤#3,减less代码量。 将textarea和hidden div放在同一个容器中,并适当使用visibility:hidden,让隐藏div的高度直接驱动textarea的高度。

 <!doctype> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Auto-size TextArea Demo</title> <script type="text/javascript" src="jquery.js"></script> <style> #container { position: relative; } #textArea { box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -webkit-box-sizing: border-box; font-family: Helvetica, Arial, sans-serif; height: 100%; overflow: hidden; position: absolute; width: 100%; } #textCopy { box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -webkit-box-sizing: border-box; font-family: Helvetica, Arial, sans-serif; padding: 6px; /* Same border+padding as text area. */ padding-bottom: 1.15em; /* A bit more than one additional line of text. */ visibility: hidden; width: 100%; } </style> <script> $(function() { $(this.textBox) .change(autoSize) .keydown(autoSize) .keyup(autoSize); autoSize(); }); function autoSize() { // Copy textarea contents; browser will calculate correct height of copy, // which will make overall container taller, which will make textarea taller. var text = $("#textArea").val().replace(/\n/g, '<br/>'); $("#textCopy").html(text); } </script> </head> <body> <div id="container"> <textarea id="textArea"></textarea> <div id="textCopy"/> </div> </body> </html> 

这是另一种自动化一个textarea的技术。

  • 使用像素高度而不是线条高度:如果使用比例字体,则会更精确地处理换行。
  • 接受ID或元素作为input
  • 接受可选的最大高度参数 – 如果您不希望文本区域增长超过一定的大小(保持全部在屏幕上,避免打破布局等)
  • testingFirefox 3和Internet Explorer 6

代码:(普通香草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"; } } 

演示:(使用jQuery,我正在input的textarea上的目标 – 如果你已经安装了Firebug ,将两个样本粘贴到控制台并在此页面上testing)

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

可能是最短的解决scheme:

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

这样你就不需要任何隐藏的div或类似的东西。

注意:你可能需要玩this.style.height = (this.scrollHeight) + "px"; 取决于你如何devisetextarea(线高,填充和那种东西)。

这里是一个原型版本的文本区域resize,它不依赖于textarea中的列数。 这是一个优秀的技术,因为它允许您通过CSS控制文本区域以及具有可变宽度的textarea。 此外,此版本还显示剩余的字符数。 虽然没有被要求,但它是一个非常有用的function,如果不需要,很容易被删除。

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

通过调用new Widget.Textarea('element_id')创build小部件。 默认的选项可以通过将它们作为一个对象来重写,例如new Widget.Textarea('element_id', { max_length: 600, min_height: 50}) 。 如果你想为页面上的所有textareas创build它,请执行如下操作:

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

以下是使用JQuery的解决scheme:

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

abc是一个teaxtarea

检查下面的链接: 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 }); }); 

只是重新审视这一点,我已经做了一点整理(尽pipe有人对Prototype / JavaScript进行了全面的研究,可以提出改进build议)。

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

只要打电话给:

 new TextAreaResize('textarea_id_name_here'); 

我做了一件很容易的事。 首先我把TextArea放到一个DIV中。 其次,我已经调用了这个脚本的ready函数。

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

简单。 一旦它被渲染,它是div的最大高度,除以一行的一个TextArea的高度。

就像@memical的答案一样。

但是我发现了一些改进。 你可以使用jQuery的height()函数。 但要注意填充顶部和填充底部的像素。 否则你的textarea会变得太快。

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

以下是Jeremy 6月4日发布的Prototype widget的扩展:

如果你在textareas中使用限制,它会阻止用户input更多的字符。 它检查是否有剩余的字符。 如果用户将文本复制到textarea中,文本将在最大值处截断。 长度:

 /** * Prototype Widget: Textarea * Automatically resizes a textarea and displays the number of remaining chars * * From: http://stackoverflow.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')); } }); 

@memical有一个很好的解决scheme,用jQuery设置页面加载的textarea的高度,但是对于我的应用程序,我希望能够随着用户添加更多内容而增加textarea的高度。 我build立了以下的化学解决scheme:

 $(document).ready(function() { var $textarea = $("p.body textarea"); $textarea.css("height", ($textarea.attr("scrollHeight") + 20)); $textarea.keyup(function(){ var current_height = $textarea.css("height").replace("px", "")*1; if (current_height + 5 <= $textarea.attr("scrollHeight")) { $textarea.css("height", ($textarea.attr("scrollHeight") + 20)); } }); }); 

这不是很顺利,但它也不是一个面向客户的应用程序,所以平滑度并不重要。 (如果这是面向客户端,我可能会只使用自动resize的jQuery插件。)

对于那些正在编码的IE和遇到这个问题。 IE有一个小窍门,使得它100%的CSS。

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

你甚至可以为IE浏览器忽略的rows =“n”提供一个值,但是其他浏览器会使用这个值。 我真的很讨厌实现IE黑客的编码,但是这个是非常有帮助的。 它可能只适用于怪癖模式。

我自己需要这个function,但是没有一个从这里工作,因为我需要他们。

所以我用了Orion的代码并改变了它。

我加了一个最小的高度,这样在破坏时不会太小。

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

Internet Explorer,Safari,Chrome和Opera用户需要记住在CSS中明确设置行高值。 我做了一个样式表,为所有的文本框设置如下的初始特性。

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

这里是我在jQuery中写的一个函数 – 可以将它移植到Prototype中 ,但是它们不支持jQuery的“活性”,所以Ajax请求所添加的元素将不会响应。

该版本不仅扩展,而且在按下删除或退格键时也会收缩。

这个版本依赖于jQuery 1.4.2。

请享用 ;)

http://pastebin.com/SUKeBtnx

用法:

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

或者(例如任何jQueryselect器)

 $("textarea").textareacontrol(); 

它在Internet Explorer 7 / Internet Explorer 8 ,Firefox 3.5和Chrome上进行了testing。 一切正常。

使用ASP.NET,只需简单地这样做:

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

我的解决scheme不使用jQuery(因为有时他们不一定是相同的东西)在下面。 虽然它只是在Internet Explorer 7中testing过,所以社区可以指出所有这些错误的原因:

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

到目前为止,我真的很喜欢它是如何工作的,我不关心其他浏览器,所以我可能会将它应用到我所有的textareas:

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