# Автоматическое изменение размера текстовой области в JavaScript и jQuery
Очень удобно, когда поле для ввода текста увеличивается в высоту по мере ввода текста. Современные браузеры могут автоматически изменять размер таких полей. В этой заметке мы обсудим, как сделать так, чтобы текстовая область автоматически расширялась, если текста больше, чем она может вместить.
## Содержание
- Опция 1: Автоматическое изменение размера текстовой об��асти с помощью чистого JavaScript
- Опция 2: Автоматическое изменение размера текстовой области с помощью плагина jQuery
- Вариант 3: Авторастягивающаяся текстовая область (мой старый скрипт)
## Опция 1: Автоматическое изменение размера текстовой области с помощью чистого JavaScript
Это, пожалуй, самое простое решение, и мы начнем именно с него.
Скрипт можно найти [здесь](https://github.com/jackmoore/autosize). Вам нужно добавить JavaScript код в ваш HTML.
Для установки достаточно подключить файл скрипта с помощью функции wp_enqueue_script()
. Затем привяжите автоматическое изменение размера к элементу текстовой области с помощью одного из следующих способов:
```javascript
// для списка элементов
autosize(document.querySelectorAll('textarea'));
// для одного элемента
autosize(document.querySelector('textarea'));
// для jQuery элементов
autosize($('textarea'));
Поддержка браузерами
Браузер | Chrome | Firefox | IE | Safari | iOS | Safari (Android) | Opera Mini |
---|---|---|---|---|---|---|---|
Поддержка | да | да | 9 | да | да | 4 | ? |
Опция 2: Автоматическое изменение размера текстовой области с помощью плагина jQuery
Если на вашем сайте установлен jQuery, я рекомендую использовать хороший плагин для автоматического изменения размера текстовой области. Его можно найти здесь.
Вот минимизированная версия кода плагина:
/*
* jQuery autoResize (автоизменение размера текстовой области)
* @copyright James Padolsey http://james.padolsey.com
* @version 1.04.1 (исправление от Kama)
*/
(function($) {
$.fn.autoResize = function(options) {
var settings = $.extend({
onResize: function() {},
animate: true,
animateDuration: 150,
animateCallback: function() {},
extraSpace: 20,
limit: 1000
}, options);
this.filter('textarea').each(function() {
var textarea = $(this).css({'overflow-y': 'hidden', display: 'block'}),
origHeight = textarea.height(),
clone = (function() {
var props = ['height', 'width', 'lineHeight', 'textDecoration', 'letterSpacing'],
propOb = {};
$.each(props, function(i, prop) {
propOb[prop] = textarea.css(prop);
});
return textarea.clone().removeAttr('id').removeAttr('name').css({
position: 'absolute',
top: 0,
left: -9999
}).css(propOb).attr('tabIndex', '-1').insertBefore(textarea);
})(),
lastScrollTop = null,
updateSize = function() {
clone.height(0).val($(this).val()).scrollTop(10000);
var scrollTop = Math.max(clone.scrollTop(), origHeight) + settings.extraSpace,
toChange = $(this).add(clone);
if (lastScrollTop === scrollTop) { return; }
lastScrollTop = scrollTop;
if (scrollTop >= settings.limit) {
$(this).css('overflow-y', '');
return;
}
settings.onResize.call(this);
settings.animate && textarea.css('display') === 'block' ?
toChange.stop().animate({height: scrollTop}, settings.animateDuration, settings.animateCallback) :
toChange.height(scrollTop);
};
textarea.unbind('.dynSiz').bind('keyup.dynSiz', updateSize)
.bind('keydown.dynSiz', updateSize)
.bind('change.dynSiz', updateSize);
});
return this;
};
})(jQuery);
Поддержка браузерами
- IE 6-8
- Firefox 3.5
- Opera 9.5-10
- Safari 3
- Chrome 10
Во время тестирования было обнаружено, что для корректной работы плагина текстовая область должна иметь CSS свойство display: block
, иначе анимация не работала (в браузере Chrome). Также некоторые браузеры позволяли вручную изменять размер текстовой области, но плагин этого не поддерживал.
Настройка плагина
При инициализации плагина можно установить определенные параметры:
- Удалите нижний отступ, который по умолчанию составляет 20 пикселей:
jQuery('textarea').autoResize({
extraSpace: 0
});
- Привязывайте действия во время и после изменения размера - для
onResize
иanimateCallback
:
jQuery('textarea').autoResize({
// Во время изменения размера:
onResize: function() {
jQuery(this).css({ color: '#666', background: '#eee' });
},
// После изменения размера:
animateCallback: function() {
jQuery(this).css({ color: '#222', background: '#fff' });
}
});
Опция 3: Авторастягивающаяся текстовая область (мой старый скрипт)
Первая версия моего скрипта для автоматического растягивания текстовой области в WordPress оказалась не лучшей. При тестировании я не заметил баг, из-за которого экран поднимался при значительном растягивании поля, что усложняло оставление больших комментариев. Кроме того, скрипт лагал в IE 8.
После многочисленных попыток исправить скрипт, я понял, что потребуется что-то полностью переосмыслить. Я искал альтернативное решение и наткнулся на решение на основе jQuery, но захотел реализовать это с помощью чистого JS и оставил jQuery как запасной вариант.
В итоге я нашел функцию для подсчета строк и улучшил ее. Вот более подробное описание работы нового варианта.
Преимущества этого варианта
- Простота интеграции в шаблон.
- Хорошая оценка высоты.
- Нет лагов.
Код нового скрипта
/**
* Скрипт для автоматического растягивания текстовой области по вертикали.
*
* Для работы скрипта высота текстовой области не должна быть строго определена,
* т.е. свойство CSS height не должно быть задано. Вместо height используйте
* min-height: 200px; или лучше задайте высоту через rows=''.
* Можно также ограничить максимальную высоту растягивания через CSS свойство max-height: 800px;
*
* Автор: Тимур Камаем - http://wp-kama.ru
* Версия 4.0
*/
// настройки
var krVar = {
// ID атрибута тега текстовой области
textareaId: 'comment',
// время перерасчета (1000=1 секунда)
repeat: 1000,
// коэффициент. Увеличьте, если происходит прокрутка
cof: 40,
}
var KR = {
timeout: 0,
textarea: document.getElementById(krVar.textareaId),
init: function() {
if (!KR.textarea) return;
KR.textarea.onfocus = KR.doit;
KR.textarea.onblur = KR.stop;
},
doit: function() {
// устанавливаем необходимое количество строк
KR.textarea.rows = KR.countLines(KR.textarea.value);
clearTimeout(KR.timeout);
KR.timeout = setTimeout(function() { KR.doit(); }, krVar.repeat);
},
stop: function() {
clearTimeout(KR.timeout);
},
countLines: function(strtocount) {
var hard_lines = 0;
var str = strtocount.split("n");
hard_lines = str.length;
var tx = KR.textarea;
var letter_width = tx.clientHeight / tx.rows * krVar.cof / 100; // приблизительная ширина одной буквы в пикселях
var chars_in_line = tx.clientWidth / letter_width; // сколько букв в строке
var lines = 0;
var temp = 0;
// hard_lines - 1 = количество элементов в массиве
for (var i = 0; i <= (hard_lines - 1); i++) {
temp = str[i].length / chars_in_line;
if (temp > 0) lines += temp;
}
return lines + hard_lines;
}
}
window.addEventListener("load", KR.init, false);
Установка скрипта
- Скопируйте код выше в любой существующий JavaScript файл вашего шаблона.
- Установите CSS свойство min-height для текстовой области (см. ниже).
- (опционально) Если вы не хотите, чтобы поле растягивалось бесконечно, установите CSS свойство max-height.
Как вставить скрипт прямо в файл темы
Если в вашем шаблоне нет JavaScript файла, вы можете создать один, скопировать код туда и подключить файл к шаблону.
Или вы можете просто включить вышеуказанный код в ваш файл шаблона single.php
, вставив так:
Как установить свойство CSS min-height для текстовой области
Вариант 1: Откройте файл comments.php
, найдите HTML тег textarea
и добавьте style='min-height:200px; max-height:700px;'
. Это будет выглядеть так:
Вы можете опустить max-height:700px;
- это максимальная высота, до которой поле будет растягиваться.
Вариант 2: Найдите класс, отвечающий за текстовое поле, в вашем CSS файле (style.css
) и добавьте свойство min-height:200px;
. Если оно имеет свойство height: XXXpx
, его следует удалить.
Возможные имена классов для поля:
#commentform textarea{}
#respond textarea{}
#comment{}
textarea#comment{}
Технические детали: Как работает скрипт
Код работает следующим образом: когда курсор попадает в поле комментария, начинается периодический подсчет строк (каждые полсекунды), а когда курсор покидает поле, подсчет останавливается. Строки подсчитываются путем суммирования количества явных переносов строк (n
) и вычисления неявных переносов строк.
Главное отличие от предыдущей версии заключается в том, что используется другая технология для подсчета строк, и строки не пересчитываются с каждым нажатием клавиши, а через определенное время (в нашем случае 500 миллисекунд). Данный интервал можно увеличить, если есть задержки. В решениях, где высота рассчитывается с каждой клавишей, всегда есть задержки, особенно на медленных компьютерах.
Если у вас есть вопросы, не стесняйтесь задавать их в комментариях!