Розтягування тексту

Здавалося б, просте завдання і, напевно, хтось колись щось подібне вже робив. На жаль, ті, що я знайшов, виявилися надто складними, включали хитромудрі математичні обчислення і не коректно працювали, якщо блок із якимось текстом спочатку був прихований. Давайте вивчимо найкращий спосіб, який буде простим і вирішить проблему з спочатку прихованим полем для введення тексту.

Використання клонованого прихованого елемента

Елемент div, як вам відомо, розтягуватиметься, щоб відповідати висоті його змісту (за умови відсутності обтікання або абсолютного позиціонування). Таким чином, щоб отримати висоту текстового поля, просто потрібно зробити таке:

  • Взяти вміст, завантажений у textarea
  • Створити невидимий клон DIV
  • Призначити клону однакову ширину і друкарські властивості, як у тексту
  • Помістити вміст у клон
  • Отримати висоту клону
  • Зробити у textarea таку ж висоту як і у клона

Одним із ключів до цього рішення є CSS. Як уже згадувалося, невидимий клон повинен мати ті ж властивості, що й текстобласті. Це не тільки font-size та font-family, а й white-space та word-wrap.

Ось CSS для textarea:

Ось CSS, які я застосовуватиму до прихованого клону:

Зауважте, я приховав його від користувача за допомогою display: none .

Я також встановив властивості white-space значення "pre-wrap". Це дає впевненість, що рядки переноситимуться правильно, але все інше буде передформатовано. Я також встановити ширину, що дорівнює ширині текстуобласті і продублював кілька типографських властивостей. Також я даю клону та текстовій зоні min-height, так що вона завжди стартує на стандартнійвикористовуваної висоті.

Тепер, накидаємо швидко код на jQuery:

Цей код передбачає, що ми маємо один текстобласті на сторінці. Якщо вам потрібно обробити кілька текстовихобластей, то нам доведеться поправити перший рядок всередині функції.

Я динамічно змінюю висоту на основі JQuery-події в keyup. Ви можете легко змінити це, щоб відповісти на запит Ajax, якщо ви завантажуєте вміст цим способом.

Використання keyup , тим не менш, хороше рішення, тому що найбільш вірогідна причина, з якої потрібно автоматично змінювати висоту текстуобласті - введення користувачем даних.

А що про IE8?

На жаль, наш розкішний скрипт відмовився коректно працювати в IE8. Якщо ви досі користуєтеся ним, то додайте наступні рядки до нашого коду:

Але навіть після додавання цього рядка, у нас, як і раніше, проблема: довгий, безперервний рядок тексту не вплине на висоту текстового поля. Це, насправді, не є великою проблемою: просто додайте для клону textarea CSS-властивість word-wrap: break-word .

Перетворюємо на jQuery-плагін

Наш скрипт з автоматичним розтягуванням textarea може бути легко перетворений на плагін:

Після цього нам залишається викликати його $(".autoresize").textareaAutoresize(); і насолоджуватися. Скрипт чудово працює, поки ми вводимо в текстобласті текст. Якщо ж ми вставимо теги, та ще й зі стилями. здогадуєтеся, що станеться? Правильно! Код усередині текстуобласті підставиться в наш клон, а оскільки він є блоковим елементом, то його висота розрахується з урахуванням стилів підставлених тегів. Давайте внесемо зміну наш скрипт, додавши заміну символів і > на, припустимо, * :

Післямова: оптимізація коду

Як ви маєте помітити, код наш не зовсім ідеальний у планішвидкодії. Виною всьому. так-так, рядок var content = $(this).val().replace(/[ ]/g, '*').replace(/\n/g, ' '); . Перш ніж робити перебір рядка посимвольно у пошуку перенесення на новий рядок ( replace(/\n/g, ' ') ) було б непогано визначити версію браузера і запускати перебір тільки якщо це IE8 і нижче. Наприклад, додаємо в об'єкт settings властивість ie8:

Після цього пишемо if(!settings.ie8) content.replace(/\n/g, ' '); та відсікаємо ресурсомістку операцію в сучасних браузерах.

Проте наш скрипт і так працює досить спритно, тому я не став морочитися. Але, якщо у вас виникнуть проблеми зі швидкодією, ви знаєте, що можна зробити.