Value: Встановити значення textarea в jQuery. Чи можна додавати стильні textarea динамічно

Value: Встановити значення textarea в jQuery. Чи можна додавати стильні textarea динамічно

Зазвичай я займаюся серверним програмуванням на php, але час від часу виходжу назовні і копаюся в верстці, стилях і Яваскрипт. Нещодавно переді мною була поставлена \u200b\u200bзадача змінювати висоту textarea при введенні коментарів до різних об'єктів. В інтернеті матеріалу з цього приводу так, сказати було не мало і не багато. Перший погляд кинувся до реалізованих рішень в таких великих сетех як Вконтакте, Facebook, МойКруг. Однак, під час вирішення було безліч перешкод і далеко не кросбраузерность.

Варіанти вирішення були різні:
* Спиратися на властивості scrollHeight і offsetHeight
* Обчислити кількість використовуваних рядків розпарсити текст
* Або використовувати ідею з вище описаних мереж.

Остаточним варіантом стало ось таке рішення. Для textarea створюється невидимий шар (div) з тойже шириною, шрифтом, розміром шрифту, відступами, далі тільки що змінений текст копіюється в невидимий шар, у шару впізнається висота і ця висота встановлюється у textarea. Звучить просто, але в процесі реалізації знайшлося чимало підводних каменів.
У поточній реалізації використовується prototype версії 1.7, але і більш ранні теж піде (можна замінити на JQuery або зовсім вирізати фреймворк).



Auto-size TextArea Demo





Рішення може здатися комусь дуже компактним, іншим навпаки шалено великою. Одне точно це єдиний кінцевий варинта однаково добре працює на всіх доступних мені браузерах (FF, Ch, Op, IE7-9).

У чому особливість підходу: не можна просто запитати у textarea скільки місця займає текст, тому поміщаємо текст туди, де можна дізнатися скільки він дійсно займає місця (в нашому випадку цікава тільки висота). Ось тут то і виникає безліч підводних каменів. Як помістити текст з textarea в div, щоб в точності зберегти вигляд і займаний обсяг тексту, переноси слів, теги, множинні прогалини - вобщем все, що в звичайному тексті виглядає не так, як в html. Просто користуватися тегом pre не вдалося, тому що приручити його виявилося складніше.

Один по одному всі підводні камені зустрінуті мною (частина проблем я тут не наводжу, тому що код еволюціонував і деякі раніше вирішені проболеми просто не можуть проявити себе в цьому коді). Виходить тут лише проблеми вирішені кодом:

  • Як заховати шар, щоб він зберіг свої розміри і властивості. Причому не можна робити display: none; - губляться розміри. Не можна викидати блок вбік (position: absolute; left: -50000px;), тому що розмір блоку задати не можна, вони не відомий на момент вставки. Рішення повинно бути універсальним і легко вбудовується на будь-яку сторінку.
  • Обійти безліч прогалин і порожніх рядків.
  • Екранувати теги без зміни довжини тексту.
  • Перенесення безперервного тексту.

Рішення наведених проблем добре відображено в коді. Шар ховається зовсім поруч з textarea, це дозволяє не думати про завдання ширини шару. Поспіль кілька прогалин замінюються на Прохворівши +. Порожні рядки -

(Всі соц мережі наведені вище використовують
, але в мене не вийшло). Теги екрануються дуже просто: символи< и > замінюються на _. Ну і найцікавіше для мене відкриття, це розрив безперервного тексту стилями word-wrap: break-word ;.
Ну і найголовніше в цій ідеї - повний збіг стилів шару і textarea.

Недоліки інших підходів

1. Спиратися на властивості scrollHeight і offsetHeight - перший реалізований мною варіант. Все б нічого, але ось зменшувати розмір textarea тут не вдасться.

2. Обчислити кількість використовуваних рядків розпарсити текст. Другий варіан. Це вже краще, але як з'ясувалося застосовувати можна лише встановивши в textarea шрифт типу Monospace, де всі символи однієї ширини. Тільки так можна добитися нормальної точності. Однак, це суперечить задумом дизайнерів ...

Наведу код для цікавих (частина Функ resizeArea):

Var linecount \u003d 1;
area.value.split ( "\\ n"). each (function (s) (
linecount + \u003d Math.floor (s.length / cols) + 1;
})
area.rows \u003d linecount;

Вважаємо рядки і плюсуем довгі рядки. Треба лише знати параметр cols - ось як раз цього ми знати і не можемо без шрифту Monospace. Якщо порівняти кількість букв W і i, то в рядок входить зовсім різний кол-во.

результат

Результат виконаної роботи наведено вище. Працює в FF, Ch, Op, IE7-9. Сподіваюся він вам буде корисний. Після реалізації всіляких варіантів так захотілося мати юніт-тести на Гуйн всіх браузерів ...

підготував: Олександр Головко Дата публікації: 23.09.2010

завдання

Змінити дизайн textarea, реалізувати стильну вертикальну смугу прокрутки.

вимоги

  • легкість інтеграції
  • кроссбраузерность
  • максимальна наближеність до роботи звичайного textarea
    • в основі - звичайний textarea
    • стандартна реакція на атрибути name, id, disabled
    • настроюється вид скролла, прокрутка мишею
    • опціонально можливість змінювати розмір textarea мишею в будь-якому браузері (як в Safari і Chrome)
  • при відключеному javascript залишаються звичайні textarea

Реалізація

Для вирішення поставленого завдання довелося насильно «подружити» три плагіна. це autoResize (Спасибі, James Padolsey!), jScrollPane і UI resizable.

Так народився cuText 0.9.

приклад можливостей . Перевірено в:

  • IE 6-8
  • Firefox 3
  • Opera 9.5-10
  • Safari 3
  • Chrome 6

Що качати?

  • autoresize.jquery.js (3.77 Kb) - плагін autoresize
  • UI resizable (27.41 Kb) - можна не використовувати, якщо немає необхідності в функції зміни розміру textarea мишею
  • jScrollPane.js (22.62 Kb) оригінал був змінений.
  • jquery.mousewheel.min.js (2.6 Kb) для підтримки скролінгу коліщатком миші.
  • cuText.js (1.98 Kb) сам плагін.
  • cuText.css таблиця стилів.

Швидкий старт

Підключаємо бібліотеки:

... і таблицю стилів:

Мається на увазі, що в HTML-коді десь є textarea:

Ініціалізіруем плагін cuText, наприклад, так:

От і все.

А тепер докладніше

Функція cuText (), яка відповідає за ініціалізацію, може приймати наступні параметри:

Параметри cuText ()

приклади ініціалізації

Для всіх полів з класом cuText з можливістю зміни розмірів:

Поле з id \u003d "cuText" з можливістю зміни розмірів, мінімальними розмірами, без стрілок в смузі прокрутки, ширина смуги 12px:

Обмеження: оформлення та ресайз

Ініціалізувати плагін з параметром 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 \u003d -1; currentArrowInc \u003d 0; whileArrowButtonDown (); currentArrowTimerArr \u003d setInterval (whileArrowButtonDown, 100); return false; case 40: // down currentArrowDirection \u003d 1; currentArrowInc \u003d 0; whileArrowButtonDown (); currentArrowTimerArr \u003d 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 \u003d "btnCreate"):

JQuery ( "# btnCreate"). Click (function () (jQuery (this) .after ( " "); JQuery (this) .next (). CuText ((resizable: true));));

Баги / недоліки плагіна

  • Велика кількість використовуваних скриптів при максимальному функціонал плагіна (з резайзом). Спосіб боротися - поклеїти скрипти в один файл. Наприклад, так: скачати cutext-all.min.js (42.8 Kb).

Дуже зручно, коли поле для введення тексту розтягується в висоту зі зворотним відліком. Для цього в сучасних бразуер є можливість розтягнути поле. А в цій замітці ми поговоримо про те, як зробити так, щоб поле 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"));

Підтримка браузерів:

Chrome Firefox IE Safari iOS Safari Android Opera Mini
yes yes 9 yes yes 4 ?

Варіант 2: авто-розтягування textarea (jQuery плагін)

Якщо у вас на сайті встановлена \u200b\u200bбібліотека 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 \u003d function (f) (var a \u003d b.extend ((onResize: function () (), animate:! 0, animateDuration: 150, animateCallback: function () (), extraSpace: 20, limit: 1E3), f); this .filter ( "textarea"). each (function () (var d \u003d b (this) .css (( "overflow-y": "hidden", display: "block")), f \u003d d.height () , g \u003d function () (var c \u003d (); b.each ([ "height", "width", "lineHeight", "textDecoration", "letterSpacing"], function (b, a) (c [a] \u003d 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 \u003d , e \u003d function () (g.height (0) .val (b (this). val ()). scrollTop (1E4); var c \u003d Math.max (g.scrollTop (), f) + a.extraSpace, e \u003d b (this) .add (g); h! \u003d\u003d c && (h \u003d c, c\u003e \u003d a.limit? b (this) .css ( "overflow-y", "") :( a.onResize.call (this), a.animate && "block" \u003d\u003d\u003d 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 повинні автоматично розтягуватися.

Підтримка браузерів:

  • IE 6-8
  • Firefox 3.5
  • Opera 9.5-10
  • Safari 3
  • Chrome 10

Під час тестування з'ясував, що у 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 \u003d function (options) (// Just some abstracted details, // to make plugin users happy: var settings \u003d $ .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 \u003d $ (this) .css (( "overflow-y": "hidden", display: "block")), // Cache original height, for use later: origHeight \u003d textarea.height (), // Need clone of textarea, hidden off screen: clone \u003d (function () (// Properties which may effect space taken up by chracters: var props \u003d [ "height", "width", "lineHeight", "textDecoration", "letterSpacing"] , propOb \u003d (); // Create object of styles to apply: $ .each (props, function (i, prop) (pro pOb \u003d 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 \u003d , updateSize \u003d function () (// Prepare the clone: \u200b\u200bclone.height (0) .val ($ (this) .val ()). ScrollTop (10000); // Find the height of text: var scrollTop \u003d Math.max (clone.scrollTop (), origHeight) + settings.extraSpace, toChange \u003d $ (this) .add (clone); // Don "t do anything if scrollTip hasen" t changed: if (lastScrollTop \u003d\u003d\u003d scrollTop) (return;) lastScrollTop \u003d scrollTop; // Check for limit: if (scrollTop\u003e \u003d 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") \u003d\u003d\u003d "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 - включена.
За замовчуванням: true animateDuration (Число) Час, який займає анімація в мілісекундах.
За замовчуванням: 150 animateCallback (Функція) Викликається при закінченні анімації. extraSpace (Число) Відступ у textarea знизу в пікселях.
За замовчуванням: 20 limit (Число) Максимальна висота textarea в пікселях. Вище з'явиться скролл.
За замовчуванням 1000

Варіант 3: авто-розтягування textarea (мій старий скрипт)

З плюсів цього варіанту зміни розмірів поля коментування, можна виділити:

  • проста інтеграція в шаблон;
  • хороший підрахунок висоти;
  • не гальмує.

Черговий новий варіант, від 16 грудня 2013 року. Підправив код, виправив баг - код був написаний трохи некоректно і міг навантажувати комп'ютер. Тепер цього немає.

/ ** * Скрипт для автоматичного розтягування поля (Textarea) по вертикалі. * * Для роботи скрипта висота textarea не повинна бути визначена жорстко, тобто * НЕ повинно бути визначено CSS властивість height. Замість height можна * використовувати min-height: 200px; або краще задати висоту через rows \u003d "". * Також, можна обмежити максимальну висоту розтяжки * через CSS властивістю max-height: 800px; * * Автор: Тимур Камаєв - http: // сайт * Версія 4.0 * / // настройки var krVar \u003d (// id атрибут тега textarea textareaId: "comment", // час перерахунку (1000 \u003d 1 сек). Repeat: 1000 // коефіцієнт. Збільшите, якщо з'являється прокрутка. cof: 40,) var KR \u003d (timeout: 0, textarea: document.getElementById (krVar.textareaId), init: function () (if (! KR.textarea) return; KR .textarea.onfocus \u003d KR.doit; KR.textarea.onblur \u003d KR.stop;), doit: function () (// встановлюємо потрібну кількість рядків KR.textarea.rows \u003d KR.countLines (KR.textarea.value); clearTimeout (KR.timeout); KR.timeout \u003d setTimeout (function () (KR.doit ();), krVar.repeat);), stop: function () (clearTimeout (KR.timeout);), // функція підрахунку рядків countLines: function (strtocount) (var hard_lines \u003d 0; var str \u003d strtocount.split ( "\\ n"); hard_lines \u003d str.length; var tx \u003d KR.textarea; var letter_width \u003d tx.clientHeight / tx.rows * krVar.cof / 100; // приблизна ширина однієї літери в пікселях var chars_in_li ne \u003d tx.clientWidth / letter_width; // скільки букв в рядку var lines \u003d 0; var temp \u003d 0; // hard_lines-1 \u003d кількість елементів в масиві for (i \u003d 0; i<= (hard_lines-1); i++){ temp = str[i].length / chars_in_line; if(temp > 0) lines + \u003d 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 (як це зробити див. нижче);

  1. (Необов'язково) Якщо не хочете, щоб поле тяглося до нескінченності встановіть йому CSS властивість max-height;

Як вставити скрипт прямо в файл теми:

Якщо js файлу у вас в шаблоні немає, то можна його створити, скопіювати туди код, а потім підключити файл до шаблону.

Або можна просто підключити вище написаний код в ваш файл шаблону single.php, Вставивши таку конструкцію в файл:

Як встановити полю textarea css властивість min-height

Варіант 1: Відкрийте файл comments.php знайдіть там HTML тег textarea і додайте до нього style \u003d "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 у обраного елемента форми. Якщо вибрано кілька елементів, то значення буде взято у першого. У разі, елемента форми