Растягивание TEXTAREA по вертикали

February 15, 2008, revised March 2, 2014 JavaScript

[UPD 2014-03-02] Прошло шесть лет, и популярные браузеры научились сами растягивать TEXTAREA. Оставляю эту статью для истории, но не рекомендую пользоваться.

Решил опубликовать пару скриптов, написанных для lyrified.com.

Итак, растяжка <TEXTAREA> по вертикали. Вообще-то, растяжка любого блочного элемента по вертикали, но применялась именно для текстовых полей.

Проблема: текстовые поля, как правило, или слишком большие, или слишком маленькие. И то, и другое неудобно. Хорошо бы дать возможность изменить высоту поля

Это выглядит вот так:

 

Тестировалось в IE 6, 7, Firefox 2, 3, Opera 9, Safari 2.

В Safari, к примеру, эта проблема решена на уровне обозревателя: любое текстовое поле можно взять за угол и растянуть, как хочется. Решена она и на нескольких сайтах, например в Drupal.

В интернете есть несколько скриптов, они меня не устроили по разным причинам, в первую очередь - много лишнего кода и лень было разбираться.

Написал свой. Он короткий и понятный, и сейчас мы его разберем.

Разметка

Необходимый минимум - сам <TEXTAREA> и <DIV>, которым будем тянуть. Приведу также стиль, который я накладывал.

div.text_editor textarea
{
    width: 668px;
    height:100px;
}

div.text_editor div {
    background:
      #e2e2e2
      url("/images/resizer.gif")
      no-repeat;
    background-position:center;
    height:10px;
    width:670px;
    font-size:.01em;/* поправка высоты для IE */
    cursor:s-resize;
}

и код:

<div class="text_editor">
  <textarea name="text" id="ta_text"></textarea>
  <div id="ta_text_resizer"></div>
</div>

Идентификаторы подобраны для удобства адресации, об этом чуть попозже.

Скрипт

Общая идея: при нажатии мыши на элементе “element_resizer” активируется функция растяжки элемента “element” при перемещении мыши. При отпускании мыши - она убирается.

var startH=0;
var startY=0;
var textarea=null;
var oldMouseMove=null;
var oldMouseUp=null;

function textareaResizer(e){
    if (e == null) { e = window.event }
    // Предотвращаем выполнение стандартного события
    if (e.preventDefault) {
        e.preventDefault();
    };
    // Определяем DIV, по которому кликнули
    resizer = (e.target != null) ? e.target : e.srcElement;
    // Теперь по id определяем соответствующий textarea
    textarea = document.getElementById(
      resizer.id.substr(0,resizer.id.length-8)
      );
    // Запоминаем начальную позицию мыши и высоту поля
    startY=e.clientY;
    startH=textarea.offsetHeight;
    // Запоминаем обработчики мыши
    oldMouseMove=document.onmousemove;
    oldMouseUp=document.onmouseup;
    // Ставим свои
    document.onmousemove=textareaResizer_moveHandler;
    document.onmouseup=textareaResizer_cleanup;
    return false;
}

В этой функции инициализируется перемещение и привязываются обработчики.

minH=100; // минимальная высота поля

function textareaResizer_moveHandler(e){
  if (e == null) { e = window.event }
  if (e.button&lt;=1){
     //Начальная высота +
     //расстояние, пройденное курсором по вертикали
     curH=(startH+(e.clientY-startY));
     if (curH&lt;minH) curH=minH;
     textarea.style.height=curH+'px';
     return false;
  }
}

Сама растяжка - тут все просто.

function textareaResizer_cleanup(e) {
  //Восстанавливаем обработчики
  document.onmousemove=oldMouseMove;
  document.onmouseup=oldMouseUp;
}

И функция, убирающая обработчики по отпусканию мыши.

Привязка скрипта

Привязываем на событие onMouseDown рястяжки:

<div class="text_editor">
  <textarea name="text" id="ta_text"></textarea>
  <div id="ta_text_resizer"
    onMouseDown="textareaResizer(event);">
  </div>
</div>

Скачать

Скрипт и демонстрация

Buy Me a Coffee at ko-fi.com