В настоящее время я работаю над приложением внутренних продаж для компании, в которой работаю, и у меня есть форма, которая позволяет пользователю изменять адрес доставки.
Теперь я думаю, что было бы намного лучше, если бы текстовое поле, которое я использую для основных деталей адреса, просто занимало бы область текста в нем и автоматически изменяло бы размер, если текст был изменен.
Вот его скриншот.

Есть идеи?
@Крис
Хороший замечание, но есть причины, по которым я хочу изменить его размер. Я хочу, чтобы область, которую он занимает, была областью содержащейся в нем информации. Как вы можете видеть на снимке экрана, если у меня есть фиксированное текстовое поле, оно занимает изрядное количество вертикального пространства.
Я могу уменьшить шрифт, но мне нужно, чтобы адрес был большим и читабельным. Теперь я могу уменьшить размер текстовой области, но тогда у меня возникают проблемы с людьми, у которых адресная строка занимает 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;
};
этот плагин кажется хорошим jacklmoore.com/autosize
Есть ли версия JQuery? Как получить доступ к столбцам и строкам TextArea в JQuery?
Почти то же самое, но с явным требованием, которое должно уменьшаться при удалении текста: stackoverflow.com/questions/454202/…



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Facebook делает это, когда вы пишете на стенах людей, но меняет размер только по вертикали.
Горизонтальное изменение размера кажется мне беспорядком из-за переноса слов, длинных строк и т. д., Но вертикальное изменение размера кажется довольно безопасным и приятным.
Ни один из знакомых мне новичков, использующих Facebook, никогда не упоминал об этом и не был сбит с толку. Я бы использовал это как анекдотическое свидетельство, чтобы сказать «давай, реализуй это».
Некоторый код 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 очень наивен и плохо протестирован, и вы, вероятно, не захотите использовать его в текстовых полях с романами в них, но вы поняли общую идею.
Это предполагает, что браузер прерывает работу любого символа, что неверно. Попробуйте на <textarea cols='5'>0 12345 12345 0</textarea>. (Я написал почти идентичную реализацию и заметил это только через месяц использования.) Она также не работает с пустыми строками.
Есть ли для этого версия JQuery?
Для обратной косой черты в $ A (str.split ("\ n")) нужен другой. (Мое редактирование вышеприведенного ответа по какой-то причине не сохранилось.)
Вот еще один метод автоматического изменения размера текстового поля.
Код: (простой ванильный 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)
});
@SMB - это, вероятно, не будет слишком сложно реализовать, просто добавьте еще одно условное
@Jason: Когда текст в поле не заполняет его, clientHeight и scrollHeight равны, поэтому вы не можете использовать этот метод, если хотите, чтобы текстовое поле уменьшалось, а также увеличивалось.
Чтобы просто сжать его, вам просто нужно добавить этот код перед строкой 6: if (text.clientHeight == text.scrollHeight) text.style.height = "20px";
Просто вернувшись к этому, я сделал его немного аккуратнее (хотя кто-то, кто полностью разбирается в Прототип / 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');
Мне эта функция нужна была для себя, но ни одна из них здесь не работала так, как мне было нужно.
Поэтому я использовал код Ориона и изменил его.
Я добавил минимальную высоту, чтобы при разрушении она не стала слишком маленькой.
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, а также иметь текстовую область переменной ширины. Кроме того, в этой версии отображается количество оставшихся символов. Хотя это и не запрашивается, это довольно полезная функция, и ее легко удалить, если она не нужна.
//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);
});
});
Вот расширение виджета Prototype, которое Джереми опубликовал 4 июня:
Он не позволяет пользователю вводить больше символов, если вы используете ограничения в текстовых полях. Он проверяет, остались ли символы. Если пользователь копирует текст в текстовое поле, текст обрезается по максимуму. длина:
/**
* 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.textarea с 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;
}<div class = "textarea-container">
<textarea id = "textArea"></textarea>
<div id = "textCopy"></div>
</div>Это отличное решение! Единственное предостережение: браузеры, не поддерживающие размер окна (IE
Еще лучше работает с resize:none; в стиле textarea!
Я взял на себя смелость реализовать это решение как автономный, простой в использовании плагин jQuery, не требующий разметки или стилизации. xion.io/jQuery.xarea на случай, если кому-то это пригодится :)
установка textCopy на hidden по-прежнему позволяет скрытому div занимать место в разметке, поэтому по мере увеличения содержимого textCopy вы в конечном итоге получите полосу прокрутки по всей длине вашей страницы ...
Было бы неплохо увидеть это на скрипке.
Для людей, использующих веб-компоненты, это решение было включено в компонент основное-autosize-textarea. Есть демонстрация.
Еще одна приятная настройка; var text = $("#textArea").val().replace(/\n/g, '<br/>') + ' '; гарантирует, что вы не получите рывков при переходе от пустой новой строки в конце текстового поля к непустой, поскольку скрытый div гарантирует перенос на nbsp.
@unwitting отличный призыв к добавлению '', чтобы избавиться от этого внезапного увеличения размера, когда вы добавляете первую букву в новую строку - для меня это не работает без этого - это должно быть добавлено к ответу!
Когда я прочитал это, у меня действительно пошли мурашки по коже - настолько простые и элегантные, что довольно редко можно увидеть подобное решение при случайном просмотре SO. Спасибо за вдохновение, и пусть многие другие решат прокрутить страницу вниз!
Вам действительно стоит заменить textCopy.innerHTML на textCopy.innerText! и вместо этого используйте pre для обработки разрыва строки. иначе вы имеете дело с опасным HTML
Пользователи Internet Explorer, Safari, Chrome и Опера должны не забывать явно устанавливать значение высоты строки в CSS. Я делаю таблицу стилей, которая устанавливает начальные свойства для всех текстовых полей следующим образом.
<style>
TEXTAREA { line-height: 14px; font-size: 12px; font-family: arial }
</style>
Вот функция, которую я только что написал для этого в jQuery - вы можете перенести ее на Прототип, но они не поддерживают «живучесть» jQuery, поэтому элементы, добавленные запросами Ajax, не будут отвечать.
Эта версия не только расширяется, но и сжимается при нажатии клавиши удаления или возврата.
Эта версия основана на jQuery 1.4.2.
Наслаждаться ;)
Использование:
$("#sometextarea").textareacontrol();
или (например, любой селектор jQuery)
$("textarea").textareacontrol();
Он был протестирован на Internet Explorer 7 / Internet Explorer 8, 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
});
});
Мертвая ссылка. Код здесь james.padolsey.com/demos/plugins/jQuery/autoresize.jquery.js /…
Вот решение с JQuery:
$(document).ready(function() {
var $abc = $("#abc");
$abc.css("height", $abc.attr("scrollHeight"));
})
abc - это teaxtarea.
У @memical было отличное решение для установки высоты текстового поля при загрузке страницы с помощью jQuery, но для моего приложения я хотел иметь возможность увеличивать высоту текстового поля по мере добавления пользователем большего количества контента. Я построил решение memical следующим образом:
$(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));
}
});
});
Это не очень гладко, но это также не клиентское приложение, поэтому плавность на самом деле не имеет значения. (Если бы это было для клиента, я бы, вероятно, просто использовал плагин jQuery для автоматического изменения размера.)
Как ответ @memical.
Однако я обнаружил некоторые улучшения. Вы можете использовать функцию jQuery height(). Но помните о пикселях верхнего и нижнего отступов. В противном случае ваше текстовое поле будет расти слишком быстро.
$(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);
});
});
Я сделал кое-что довольно легкое. Сначала я поместил 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 одной строки.
Используя 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>
Мое решение, не использующее jQuery (потому что иногда они не обязательно должны быть одинаковыми), приведено ниже. Хотя он был протестирован только в Internet Explorer 7, поэтому сообщество может указать на все причины, по которым это неверно:
textarea.onkeyup = function () { this.style.height = this.scrollHeight + 'px'; }
Пока мне очень нравится, как это работает, и меня не волнуют другие браузеры, поэтому я, вероятно, применим его ко всем своим текстовым областям:
// 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
}
Наверное, самое короткое решение:
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"; в зависимости от того, как вы стилизуете текстовое поле (высота строки, отступы и тому подобное).
Лучшее решение, если вы не против мигания полосы прокрутки.
Достаточно было бы поймать только событие keyup. Вы так не думаете?
Установите для свойства переполнения текстовой области значение «скрытый», чтобы полоса прокрутки не мигала.
keyup может быть достаточно, но я не уверен. Я был так счастлив, что понял это, что перестал пробовать что-либо еще.
Я все еще пытаюсь понять, зачем вы добавили this.style.height = "1px"; или this.style.height = "авто"; перед. Я знаю, что textarea не изменит размер, когда мы удалим контент, если мы не добавим эту строку. Может кто-нибудь объяснить?
Для тех, кто пишет код для IE и сталкивается с этой проблемой. В IE есть небольшая хитрость, которая делает его на 100% CSS.
<TEXTAREA style = "overflow: visible;" cols = "100" ....></TEXTAREA>
Вы даже можете указать значение rows = "n", которое IE проигнорирует, но другие браузеры будут использовать. Я действительно ненавижу кодирование, реализующее взломы IE, но этот очень полезен. Возможно, это работает только в режиме Quirks.
Можете ли вы создать демонстрационный сайт, на котором мы сможем увидеть это в работе?