使用原型自动调整文本区域
我目前正在为所工作的公司开发内部销售应用程序,并且我有一张表格,允许用户更改收货地址。
现在,我认为它看起来要好得多,如果我用于主要地址详细信息的textarea仅占用其中的文本区域,并且如果更改了文本,则会自动调整大小。
这是当前的屏幕截图。
有任何想法吗?
@克里斯
很好,但是我有理由要调整它的大小。我希望占用的区域是其中包含的信息的区域。从屏幕截图中可以看到,如果我有固定的textarea,它将占用相当大的垂直空间。
我可以减少字体,但是我需要地址大且可读。现在,我可以减小文本区域的大小,但是对于地址行占用3或者4(一行占用5)行的人来说,我遇到了问题。需要用户使用滚动条是主要的禁忌。
我想我应该更具体一些。我需要垂直调整大小,宽度也没关系。唯一发生的问题是,当窗口宽度太小时(如我们在屏幕截图中所见),ISO编号(大的" 1")被推到地址下方。
这不是要有个花哨的东西。这是关于用户可以编辑的文本字段,它不会占用不必要的空间,但会显示其中的所有文本。
尽管如果有人想出另一种方法来解决问题,我也很乐意。
我对代码进行了一些修改,因为它的行为有些奇怪。我将其更改为在键入时激活,因为它不会考虑刚刚键入的字符。
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的新手都没有提及或者困惑过。我会将其用作传闻,说"继续前进,实施它"。
一些使用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代码非常幼稚且未经良好测试,我们可能不想在其中装有小说的文本框中使用它,但我们已掌握了总体思路。
回答
这是用于自动化文本区域的另一种技术。
- 使用像素高度而不是线条高度:如果使用比例字体,则更精确地处理换行。
- 接受ID或者元素作为输入
- 接受可选的最大高度参数-如果我们不想让文本区域超过特定大小(将其保留在屏幕上,避免破坏布局等),则非常有用。
- 在Firefox 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,如果我们已安装Firebug,则现在输入的文本区域为目标,将两个示例都粘贴到控制台中并在此页面上进行测试)
$("#post-text").keyup(function() { FitToContent(this, document.documentElement.clientHeight) });
回答
只是回顾一下,我已经做了一些整理(尽管对Prototype / JavaScript满口的人可能会建议改进吗?)。
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');
回答
我自己需要此功能,但是我需要的这些功能都不起作用。
因此,我使用了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; };
回答
这是调整文本区域大小的原型版本,该文本区域不依赖于文本区域中的列数。这是一种高级技术,因为它允许我们通过CSS控制文本区域以及可变宽度的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' }); 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')
创建窗口小部件。可以通过将默认选项作为对象传递来覆盖默认选项,例如new Widget.Textarea('element_id',{max_length:600,min_height:50})
。如果要为页面上的所有文本区域创建它,请执行以下操作:
Event.observe(window, 'load', function() { $$('textarea').each(function(textarea) { new Widget.Textarea(textarea); }); });
回答
这是Jeremy在6月4日发布的Prototype小部件的扩展:
如果我们在文本区域中使用限制,它将阻止用户输入更多字符。它检查是否还有字符。如果用户将文本复制到文本区域中,则文本将被最大程度地剪切掉。长度:
/** * 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')); } });
回答
对其中一些答案的一种改进是让CSS做更多的工作。
基本路线似乎是:
- 创建一个容器元素来保存
textarea
和一个隐藏的div
- 使用Javascript,使textarea的内容与div保持同步
- 让浏览器完成计算该div高度的工作
- 由于浏览器会处理隐藏的" div"的渲染/调整大小,因此我们避免显式设置" textarea"的高度。
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>
回答
Internet Explorer,Safari,Chrome和Opera用户需要记住在CSS中明确设置line-height值。我做一个样式表,为所有文本框设置初始属性,如下所示。
<style> TEXTAREA { line-height: 14px; font-size: 12px; font-family: arial } </style>
回答
这是我刚刚在jQuery中编写的一个函数,可以将其移植到Prototype,但是它们不支持jQuery的"活动性",因此Ajax请求添加的元素将不会响应。
此版本不仅可以扩展,而且在按Delete或者Backspace时也可以收缩。
此版本依赖jQuery 1.4.2.
享受 ;)
http://pastebin.com/SUKeBtnx
用法:
$("#sometextarea").textareacontrol();
或者(例如,任何jQuery选择器)
$("textarea").textareacontrol();
它已在InternetExplorer7 / InternetExplorer8,Firefox 3.5和Chrome上进行了测试。一切正常。
回答
检查以下链接:
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 }); });
回答
这是JQuery
的解决方案:
$(document).ready(function() { var $abc = $("#abc"); $abc.css("height", $abc.attr("scrollHeight")); })
abc
是teaxtarea
。