Подготовил: Александр Головко Дата публикации: 23.09.2010
ЗадачаИзменить дизайн textarea, реализовать стильную вертикальную полосу прокрутки.
ТребованияДля решения поставленной задачи пришлось насильно «подружить» три плагина. Это autoResize (спасибо, James Padolsey!), jScrollPane и UI resizable .
Так родился cuText 0.9.
Пример возможностей . Проверено в:
Подключаем библиотеки:
…и таблицу стилей:
Подразумевается, что в HTML-коде где-то есть textarea:
Инициализируем плагин cuText, например, так:
jQuery(function(){ jQuery("textarea").cuText(); });
Вот и все.
А теперь подробнееФункция cuText(), которая отвечает за инициализацию, может принимать следующие параметры:
Параметры cuText() Примеры инициализацииДля всех полей с классом cuText с возможностью изменения размеров:
jQuery(function(){ jQuery(".cuText").cuText({resizable: true}); });
Поле с id="cuText" с возможностью изменения размеров, минимальными размерами, без стрелок в полосе прокрутки, ширина полосы 12px:
jQuery(function(){ jQuery("#cuText").cuText({ resizable: true, scrollbarWidth: 12, showArrows: true, minWidth: 200, minHeight: 100 }); });
Ограничение: оформление и ресайзИнициализировать плагин с параметром resizable: true можно только для тех textarea, для оформления которых не использовалась цельная фоновая картинка (в демо-примере это все поля, кроме шестого). Ведь при ресайзе цельный фон не потянется и верстка будет выглядеть некрасиво. Это ограничение считаю не очень существенным, так как сам ресайз у обычных textarea реализован только в некоторых браузерах, т.е. не является стандартом.
Немного подробнее про подключаемые *.jsКроме собственно jquery в демонстрационном примере подключается еще 5 js-файлов общим весом почти 60Kb. Возникает резонный вопрос, можно ли этот вес уменьшить? Да, можно. Плагин jquery-ui-1.8.custom.min.js нужен только в случае, если необходимо, чтобы пользователь мог мышью менять размер стильных textarea. Если эта функция не нужна, смело убираем данный плагин.
jScrollPane.js и jquery.mousewheel.min.js отвечают за стильную прокрутку. Понятно, что если таковая уже внедрена в проект (а как правило так и есть, то есть если используются стильные textarea, то и select, как правило, стилизован), тогда эти файлы уже подключены.
Таким образом минимальный набор дополнительно подключаемых файлов — это autoresize.jquery.js и cutext.js общим весом 5.75Kb.
Список типичных вопросов Как настроить внешний вид textarea?Внешний вид стильного textarea определяется в cutext.css. Плагин автоматически оборачивает textarea в . В основном его стили и отвечают за вид поля:
CuTextWrap{ width:400px; background:none; color:#000; padding:3px 3px 10px 3px; /* нижний отступ больше - резервируем место для уголка ресайза */ border:1px solid #B2B2B2; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; position: relative; /* нужно обязательно для позиционирования границ, за которые будет тянуть пользователь */ } .cuTextWrap textarea{ width: 100%; height: 80px; /* начальная высота textarea */ display: block; overflow:hidden; border:none; background:none; color:#000; }
Как настроить стили полосы прокрутки?Поскольку полоса прокрутки формируется с помощью плагина jScrollPane, то и настройка производится так, как описано в статье jScrollPane. Делаем красивый скроллинг . Все необходимые стили вынесены в cutext.css.
А я уже использую в своей верстке jScrollPane. Не будет ли конфликта стилей?Нет, не будет. Стили для textarea защищены, так как в cutext.css они все объявлены с родителем (например, .cuTextWrap .jScrollPaneContainer).
Я уже использую в своей верстке jScrollPane. А в описании плагина указано «jScrollPane.js (22.62 Kb) оригинал был изменен». Как разрулить эту ситуацию?Опять-таки ничего страшного. Оригинал поменялся совершенно незначительно и его можно использовать для обычной прокрутки.
В оригинальном jScrollPane.js есть такие строки:
Switch (e.keyCode) { case 38: //up currentArrowDirection = -1; currentArrowInc = 0; whileArrowButtonDown(); currentArrowTimerArr = setInterval(whileArrowButtonDown, 100); return false; case 40: //down currentArrowDirection = 1; currentArrowInc = 0; whileArrowButtonDown(); currentArrowTimerArr = setInterval(whileArrowButtonDown, 100); return false;
Этот код, кроме всего прочего, как бы блокирует нажатия на стрелки вверх и вниз, т.е. return false не позволяет переместить курсор внутри textarea. Эти стрелки просто перемещают прокрутку. В измененном jScrollPane.js там просто стоит return true.
В плагинах jScrollPane, autoresize и jQuery UI:: resizable есть ряд более тонких настроек поведения. Они не попали в список параметров cuText, а я хочу их использовать! Как быть?Да, параметров у них действительно много. Переносить их все на cuText значит неоправданно усложнить его. Если нужны тонкие настройки, открываем cutext.js, ищем вызовы нужных нам плагинов и добавляем необходимые параметры.
Мне нужно использовать атрибуты в HTML чтобы задать для textarea id, name, disabled, tabindex и прочее. Будет ли это все работать после воздействия плагина?Да, будет. В основе будет находится тот самый textarea, который изначально помещен в HTML, со всеми своими атрибутами.
Можно ли добавлять стильные textarea динамически?Можно. Только для вновь созданного textarea нужно сразу же проинициализировать плагин. Это может выглядеть, например, так (вставка по нажатию на элемент id="btnCreate"):
JQuery("#btnCreate").click(function() { jQuery(this).after("textarea создан на лету с помощью скрипта."); jQuery(this).next().cuText({resizable: true}); });
Баги/недостатки плагинаЯ пытаюсь установить значение в поле textarea, используя jquery со следующим кодом:
$("textarea#ExampleMessage").attr("value", result.exampleMessage);
Проблема в том, что после выполнения этого кода он не изменяет текст в текстовом поле?
Однако при выполнении alert($("textarea#ExampleMessage").attr("value")) возвращается новое заданное значение?
AnswersНа android .val и.html не работает.
$("#id").text("some value")
выполнил эту работу.
Textarea не имеет атрибута значения, его значение происходит между тегами, то есть: my text , это не похоже на поле ввода (). Вот почему attr не работает:)
Текстовая область не имеет значения. jQuery .html () работает в этом случае
$("textarea#ExampleMessage").html(result.exampleMessage);
Просто используйте textarea Id по типу типа:
$("textarea#samplID").val()
Вы пробовали вал?
textarea не сохраняет значения как
вместо этого он сохраняет значения в этом формате:
someString
Так attr("value","someString") получает вам этот результат:
someOLDString.
try $("#textareaid").val() или $("#textareaid").innerHTML Вместо этого используется $("#textareaid").innerHTML .
Чтобы установить значение textarea закодированного HTML (чтобы показать как HTML), вы должны использовать.html(the_var) но, как уже упоминалось, если вы попытаетесь установить его снова, он может (и, вероятно, не работать).
Вы можете исправить это, опустошив textarea.empty .empty() а затем снова установив его с помощью.html(the_var)
jQuery(function($){ $(".load_html").click(function(){ var my_var = $(this).data("my_html"); $("#dynamic_html").html(my_var); }); $("#clear_html").click(function(){ $("#dynamic_html").empty(); }); }); Google HTML Yahoo HTML Clear HTML
У меня была такая же проблема, и это решение не сработало, но работала была с использованием html
$("#your_textarea_id").html("some_value");
Я думаю, что отсутствует один важный аспект:
$("#some-text-area").val("test");
работает только при наличии селектора идентификаторов (#)
для селектора классов существует возможность использовать собственное значение, например:
$(".some-text-area").value = "test";
Использование $("textarea#ExampleMessage").html("whatever you want to put here"); может быть хорошим способом, потому что.val() может иметь проблемы при использовании данных из базы данных.
Например:
Поле базы данных, называемое description имеет следующее значение asjkdfklasdjf sjklñadf . В этом случае использование.val () для присвоения значения textarea может быть утомительным заданием.
Ох, приходите на мальчиков! он работает только с
$("#your_textarea_id").val("some_value");
Вы даже можете использовать приведенный ниже фрагмент.
$("textarea#ExampleMessage").append(result.exampleMessage);
У меня был такой же вопрос, поэтому я решил попробовать его в текущих браузерах (мы полтора года спустя после этого вопроса), и это (.val) работает
$("textarea#ExampleMessage").val(result.exampleMessage);
$("textarea#ExampleMessage").val() в jquery просто магия.
Вы должны заметить, что тег textarea использует внутренний html для отображения, а не атрибут value так же, как входной тег.
blah blah
Вы должны использовать
$("textarea#ExampleMessage").html(result.exampleMessage)
$("textarea#ExampleMessage").text(result.exampleMessage)
зависит от того, хотите ли вы отображать его как теги html или обычный текст.
Я попытался использовать.val() .text() .html() и имел некоторые ошибки, используя jQuery для чтения или установки значения textarea ... i endup с использованием встроенных js
$("#message").blur(function() { if (this.value == "") { this.value = msg_greeting; } });
Просто используйте этот код, и вы всегда будете иметь значение:
var t = $(this); var v = t.val() || t.html() || t.text();
Поэтому он проверит val () и установит его значение. Если val () получает пустую строку, NULL, NaN os, он будет проверять html (), а затем на text () ...
Я думаю, что это должно работать:
$("textarea#ExampleMessage").val(result.exampleMessage);
Там проблема: мне нужно сгенерировать html-код из содержимого данного div. Затем я должен поместить этот необработанный html-код в текстовое поле. Когда я использую функцию $ (textarea) .val () следующим образом:
$ (textarea) .val ("some html like bla bla");
$ ("# idTxtArGenHtml"). val ($ ("idDivMain"). html ());
У меня была проблема с некоторым специальным символом (& "), когда они находятся между квотами. Но когда я использую функцию: $ (textarea) .html (), текст в порядке.
Вот пример формы:
Test your newsletter»
Send to à :
Subject Enter the subject: * Код javascript / jquery, который не работает для заполнения текстового поля:
Function onGenHtml(){ $("#idTxtArGenHtml").html($("#idDivMain").html()); }
Завершите решение:
Function onGenHtml(){ $("#idTxtArGenHtml").html($("#idDivMain").html()); $("#idTxtArGenHtml").parent().replaceWith(""+$("#idTxtArGenHtml").parent().html()+""); }
Трюк обертывает вашу текстовую область тегом span, чтобы помочь с помощью функции replaceWith. Я не уверен, что он очень чист, но он отлично работает, добавляя исходный HTML-код в текстовое поле.
If($("#checkboxId").is(":checked")){ alert("Checked"); }
If($("#checkboxId").attr("checked")==true){ alert("Checked"); }
If (document.getElementById("checkboxID").checked){ alert("Checked"); }
Очень удобно, когда поле для ввода текста растягивается в высоту по мере ввода текста. Для этого в современных бразуерах есть возможность растянуть поле. А в этой заметке мы поговорим о том, как сделать так, чтобы поле textarea растягивалось автоматически когда текста в нем больше чем оно может поместить.
Вариант 1: авто-растягивания textarea (на чистом javascript)Пожалуй это лучшее решение, поэтому это первый вариант.
А это прямая ссылка на сам javascript код, который нужно подключить к html: https://github.com/jackmoore/autosize/blob/master/src/autosize.js
Установка проста: подключаете файл скрипта с помощью wp_enqueue_script() . Затем подключаете растягивание к элементу textarea одним из следующих вариантов:
// список элементов autosize(document.querySelectorAll("textarea")); // один элемент autosize(document.querySelector("textarea")); // jQuery элементы autosize($("textarea"));
Поддержка браузеров:
yes | yes | 9 | yes | yes | 4 | ? |
Если у вас на сайте установлена библиотека jQuery, то рекомендую хороший плагин для автоматического растягивания textarea.
Поделюсь сразу сжатой версией кода плагина:
/* * jQuery autoResize (textarea auto-resizer) * @copyright James Padolsey http://james.padolsey.com * @version 1.04.1 (kama fix) */ (function(b){b.fn.autoResize=function(f){var a=b.extend({onResize:function(){},animate:!0,animateDuration:150,animateCallback:function(){},extraSpace:20,limit:1E3},f);this.filter("textarea").each(function(){var d=b(this).css({"overflow-y":"hidden",display:"block"}),f=d.height(),g=function(){var c={};b.each(["height","width","lineHeight","textDecoration","letterSpacing"],function(b,a){c[a]=d.css(a)});return d.clone().removeAttr("id").removeAttr("name").css({position:"absolute",top:0,left:-9999}).css(c).attr("tabIndex","-1").insertBefore(d)}(),h=null,e=function(){g.height(0).val(b(this).val()).scrollTop(1E4);var c=Math.max(g.scrollTop(),f)+a.extraSpace,e=b(this).add(g);h!==c&&(h=c,c>=a.limit?b(this).css("overflow-y",""):(a.onResize.call(this),a.animate&&"block"===d.css("display")?e.stop().animate({height:c},a.animateDuration,a.animateCallback):e.height(c)))};d.unbind(".dynSiz").bind("keyup.dynSiz",e).bind("keydown.dynSiz",e).bind("change.dynSiz",e)});return this}})(jQuery); // инициализация jQuery(function(){ jQuery("textarea").autoResize(); });
После установки этого кода, все textarea должны автоматически растягиваться.
Поддержка браузеров:
Во время тестирования выяснил, что у textarea обязательно должно быть установлено css свойство display:block , иначе никакая анимация в плагине не работала (браузер chrome). Поэтому добавил в плагин пару строк кода, чтобы он сам устанавливал это свойство. Также, в некоторых браузерах есть возможность изменять размер поля вручную (в углу треугольничек), плагин эту возможность зачем-то убирал, я её вернул. Поэтому в заголовке @version 1.04.1 (kama fix)
Несжатая версия кода плагина: /* * jQuery autoResize (textarea auto-resizer) * @copyright James Padolsey http://james.padolsey.com * @version 1.04.1 (kama fix) */ (function($){ $.fn.autoResize = function(options) { // Just some abstracted details, // to make plugin users happy: var settings = $.extend({ onResize: function(){ }, animate: true, animateDuration: 150, animateCallback: function(){}, extraSpace: 20, limit: 1000 }, options); // Only textarea"s auto-resize: this.filter("textarea").each(function(){ // Get rid of scrollbars and disable WebKit resizing: var textarea = $(this).css({"overflow-y":"hidden", display:"block"}), // Cache original height, for use later: origHeight = textarea.height(), // Need clone of textarea, hidden off screen: clone = (function(){ // Properties which may effect space taken up by chracters: var props = ["height","width","lineHeight","textDecoration","letterSpacing"], propOb = {}; // Create object of styles to apply: $.each(props, function(i, prop){ propOb = textarea.css(prop); }); // Clone the actual textarea removing unique properties // and insert before original textarea: 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() { // Prepare the clone: clone.height(0).val($(this).val()).scrollTop(10000); // Find the height of text: var scrollTop = Math.max(clone.scrollTop(), origHeight) + settings.extraSpace, toChange = $(this).add(clone); // Don"t do anything if scrollTip hasen"t changed: if (lastScrollTop === scrollTop) { return; } lastScrollTop = scrollTop; // Check for limit: if (scrollTop >= settings.limit) { $(this).css("overflow-y",""); return; } // Fire off callback: settings.onResize.call(this); // Either animate or directly apply height: settings.animate && textarea.css("display") === "block" ? toChange.stop().animate({height:scrollTop}, settings.animateDuration, settings.animateCallback) : toChange.height(scrollTop); }; // Bind namespaced handlers to appropriate events: textarea .unbind(".dynSiz") .bind("keyup.dynSiz", updateSize) .bind("keydown.dynSiz", updateSize) .bind("change.dynSiz", updateSize); }); // Chain: return this; }; })(jQuery); Настройка плагинаВо время инициализации плагину можно установить некоторые параметры.
1. Уберем отступ снизу, по умолчанию он равен 20 пикселей: jQuery("textarea").autoResize({ extraSpace: 0 }); 2. Вешаем действия на события в момент ресайза и после него - настройки onResize и animateCallback: jQuery("textarea").autoResize({ // Во время ресайза: onResize: function() { jQuery(this).css({ color:"#666", background:"#eee" }); }, // После ресайза: animateCallback: function() { jQuery(this).css({ color:"#222", background:"#fff" }); } }); Все настройки onResize(функция) Функция вызывается в момент изменения размера textarea. Передает объект textarea, т.е. в функции "this" будет рабочий textarea. animate(логический) Включена ли анимация изменения высоты. true - включена.Очередной новый вариант, от 16 декабря 2013 года. Подправил код, исправил баг - код был написан немного не корректно и мог нагружать компьютер. Теперь этого нет.
/** * Скрипт для автоматического растягивания поля (Textarea) по вертикали. * * Для работы скрипта высота textarea не должна быть определена жёстко, т.е. * НЕ должно быть определено CSS свойство height. Вместо height можно * использовать min-height:200px; или лучше задать высоту через rows="". * Также, можно ограничить максимальную высоту растяжки * через CSS свойством max-height:800px; * * Автор: Тимур Камаев - http://сайт * Версия 4.0 */ // настройки var krVar = { // id атрибут тега textarea 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(i=0; i 0) lines += temp; } return lines + hard_lines; } } if(window.addEventListener) window.addEventListener("load", KR.init, false); else if(window.attachEvent) window.attachEvent("onload", KR.init);
Установка скриптаСкопируйте вышеописанный код в любой уже имеющийся в шаблоне javascript файл;
Установите полю textarea CSS свойство min-height (как это сделать см. ниже );
Если js файла у вас в шаблоне нет, то можно его создать, скопировать туда код, а затем подключить файл к шаблону.
Или можно просто подключить выше написанный код в ваш файл шаблона single.php , вставив такую конструкцию в файл:
/* */
Как установить полю textarea css свойство min-heightВариант 1: Откройте файл comments.php найдите там HTML тег textarea и добавьте к нему style="min-height:200px; max-height:700px;" . На вид примерно так:
max-height:700px; можно не добавлять - это максимальная длинна до которой будет растягиваться поле.
Вариант 2: Найдите в вашем файле стилей (style.css) класс, который отвечает за поле textarea и добавьте к нему CSS свойство min-height:200px; . Если там присутствует свойство height:XXXpx , то его нужно удалить.
Несколько вариантов как может называться класс который отвечает за поле:
#commentform textarea #respond textarea #comment textarea#comment
Тех. подробности: как работает скриптПринцип работы кода заключается в следующем: когда курсор попадает в поле комментирования включается периодический подсчет строк (каждые пол секунды), когда курсор выходит из поля, подсчет строк останавливается. Строки считаются путем суммы количества явных переносов строки (\n) и вычисление неявных переносов (когда строка переводится на новую из-за нехватки ширины поля, над этим моментом пришлось биться долго и муторно).
Принципиальная разница с прошлым вариантом в том, что применяется другая технология подсчета строк и строки считаются не по нажатию клавиши а спустя какое-то время, в нашем случае 500 миллисекунд (пол секунды). Интервал можно увеличить, если наблюдаются тормоза. В вариантах, когда подсчет высоты вешается на нажатие клавиши, везде наблюдаются тормоза, особенно на слабых компах и при быстром печатание.
Если возникнут вопросы задавайте в комментариях!
Метод позволяет получать и изменять значения элементов форм. Для элементов input это значение атрибута value; для списков выбора (select) - значение value выбранного элемента (в случае множественного выбора - массив значений); в случае с textarea , метод.val() будет работать непосредственно с содержимым тега textarea . Метод имеет три варианта использования:
возвращает значение атрибута value у выбранного элемента формы. Если выбрано несколько элементов, то значение будет взято у первого. В случае, элемента формы возвращается массив всех выбранных значений.
атрибуту value будет присвоено значение newVal , у всех выбранных элементов.
атрибуту value будет присвоено значение, возвращенное пользовательской функцией. Функция вызывается отдельно, для каждого из выбранных элементов. При вызове, ей передаются следующие параметры: index — позиция элемента в наборе , newVal — текущее значение атрибута value у элемента.
Примеры использования:
Замечание : важно отметить, что используя метод.val() , вы получите значения атрибута value, только у первого элемента из всех выбранных. Если вам нужны значения всех элементов, то следует использовать конструкции типа .map() или .each() .
В действииЕсли в одном из текстовых полей, в которые нужно записывать любимые продукты, значение окажется отличным от "Шоколад", то пользователь получит замечание:
~lt~!DOCTYPE html~gt~ ~lt~html~gt~ ~lt~head~gt~ ~lt~script src="http://code.jquery.com/jquery-latest.js"~gt~~lt~/script~gt~ ~lt~style~gt~ input{ width:240px; margin:3px; } ~lt~/style~gt~ ~lt~/head~gt~ ~lt~body~gt~ ~lt~b~gt~Укажите любимые продукты:~lt~/b~gt~~lt~br~gt~ ~lt~input type="text" value="Колбаса" /~gt~~lt~br~gt~ ~lt~input type="text" value="Шоколад" /~gt~~lt~br~gt~ ~lt~input type="text" value="Пиво" /~gt~~lt~br~gt~ ~lt~input type="text" value="Спагетти" /~gt~ ~lt~div id="state"~gt~ ~lt~/div~gt~ ~lt~script~gt~ $("input:text").val(function(index, x){ if(x != "Шоколад") return "Шоколад лучше чем " + x; else return x; }); ~lt~/script~gt~ ~lt~/body~gt~ ~lt~/html~gt~
Обычно я занимаюсь серверным программированием на php, но время от времени выхожу наружу и копаюсь в верстке, стилях и яваскрипте. Недавно передо мной была поставлена задача изменять высоту textarea при вводе комментариев к различным объектам. В интернете материала по этому поводу так, сказать было не мало и не много. Первый взгляд устремился к реализованным решениям в таких крупных сетех как Вконтакте, Facebook, МойКруг. Однако, во время решения было множество препятствий и далеко не кросбраузерность.
Варианты решения были различны:
* опираться на свойства scrollHeight и offsetHeight
* вычислить кол-во используемых строк распарсив текст
* или использовать идею из выше описанных сетей.
Окончательным вариантом стало вот такое решение. Для textarea создаётся невидимый слой (div) с тойже шириной, шрифтом, размером шрифта, отступами, далее только что изменённый текст копируется в невидимый слой, у слоя узнаётся высота и эта высота устанавливается у textarea. Звучит просто, но в процессе реализации нашлось немало подводных камней.
В текущей реализации используется prototype версии 1.7, но и более ранние тоже пойдет (можно заменить на JQuery или совсем вырезать фреймворк).
Auto-size TextArea Demo
function resizeArea(text_id, minHeight, maxHeight)
{
var area = $(text_id);
var area_hidden = $(text_id + "_hidden");
var text = "";
area.value.replace(/[]/g, "_").split("\n").each(function(s) {
text = text + "" + s.replace(/\s\s/g, " ") + " "+"\n";
});
area_hidden.innerHTML = text;
var height = area_hidden.offsetHeight + 15;
height = Math.max(minHeight, height);
height = Math.min(maxHeight, height);
area.style.height = height + "px";
}
body, textarea {
font-family: Tahoma, Arial, "Nimbus Sans L", sans-serif;
font-size: 13px;
}
.text {
width:700px !important;
border:1px solid #000;
}
.text .textarea_behavior{
border:0;
width:99%;
word-wrap: break-word;
}
.text textarea{
overflow:hidden;
}
.text .comment_text_hidden{
position: relative;
}
.text #comment_text_hidden{
visibility:hidden;
position: absolute;
}
Решение может показаться кому-то очень компактным, другим наоборот безумно большим. Одно точно это единственный конечный варинта одинаково хорошо работающий на всех доступных мне браузерах (FF, Ch, Op, IE7-9).
В чем особенность подхода: нельзя просто спросить у textarea сколько места занимает текст, поэтому помещаем текст туда, где можно узнать сколько он действительно занимает места (в нашем случае интересна только высота). Вот тут то и возникает множество подводных камней. Как поместить текст из textarea в div, чтобы в точности сохранить вид и занимаемый объём текста, переносы слов, теги, множественные пробелы - вобщем всё, что в обычном тексте выглядит не так, как в html. Просто пользоваться тегом pre не удалось, т.к. приручить его оказалось сложнее.
По порядку все подводные камни встреченные мною (часть проблем я здесь не привожу, т.к. код эволюционировал и некоторые ранее решенные проболемы просто не могут проявить себя в этом коде). Получается здесь лишь проблемы решённые кодом:
Решение приведенных проблем хорошо отражено в коде. Слой прячется совсем рядом с textarea, это позволяет не думать о задании ширины слою. Подряд несколько пробелов заменяются на пробол + . Пустые строки - (все соц сети приведенные выше используют
, но у меня не получилось). Теги экранируются очень просто: символы < и > заменяются на _. Ну и самое интересное для меня открытие, это разрыв непрерывного текста стилями word-wrap: break-word;.
Ну и самое главное в этой идеи - полное совпадение стилей слоя и textarea.
2. Вычислить кол-во используемых строк распарсив текст. Второй вариан. Это уже получше, но как выяснилось применять можно лишь установив в textarea шрифт типа Monospace, где все символы одной ширины. Только так можно добиться нормальной точности. Однако, это противоречит задумкам дизайнеров…
Приведу код для любопытных (часть функи resizeArea):
Var linecount = 1;
area.value.split("\n").each(function(s) {
linecount += Math.floor(s.length / cols) + 1;
})
area.rows = linecount;
Считаем строки и плюсуем длинные строки. Надо лишь знать параметр cols - вот как раз этого мы знать и не можем без шрифта Monospace. Если сравнить кол-во букв W и i, то в строку входит совсем разное кол-во.
Результат Результат проделанной работы приведен выше. Работает в FF, Ch, Op, IE7-9. Надеюсь он вам будет полезен. После реализации всевозможнейших вариантов так захотелось иметь юнит-тесты на гуйню всех браузеров…