Дао роста полей

в 20:01, , рубрики: greasemonkey, HabrAjax, javascript, userscript, userscripts, Юзабилити в IT, метки: , ,

Дао роста полейНемного пятничного веселья.
Поля ввода, Textarea, которые молчат, когда с ними ничего не делают, на самом деле хотят расти. Когда объём вводимых текстов превышает их размеры, их тайное желание не всегда слышится дизайнерами и верстальщиками, потому что они уже далеко и думают о новых горизонтах. Оно есть, если прислушаться к кончикам пальцев пользователя, досадливо двигающих скролл мыши.

Иногда об этом удаётся забыть, если размер поля ввода предоставлен в основном удовлетворительный. В 3 браузерах из 5 есть даже место для изменения размеров, которое верстальщик, оглушённый указанием свыше, иногда отключает (textarea{resize: none}). Есть и другие способы затруднить жизнь пользователю. И тогда он уходит берётся за скрипты и стили.

Иногда рост поля ввода требует умеренности. К примеру, если он дошёл до 80% высоты окна или логического блока раскладки страницы. Этот крайний случай тоже требует внимания, но чаще возникает первая проблема — поля малы.

История

На известном новостном сайте Х. (имена изменены, совпадения случайны) изменяемость полей ввода подавляют не менее жёстко, чем политику. Подавление многопланово, словно они, на той стороне баррикады старались затруднить поползновение исправить это простыми средствами.

Пока высота поля ввода составляла 6-7 строк, никто особо не задумывался, почему высота полей не изменяется. Но Safari, а затем Chrome подали плохой пример — у них появился уголок, за который пользователь мог потянуть и начать вводить в комментарий слишком много текста. Надо было что-то делать, чтобы ухудшить жизнь, чтобы они, эти толпы кликали куда надо и не писали куда не надо. Последней каплей стал Firefox около года назад. Когда и он стал ресайзить поле ввода, срочно надо было что-то предпринимать. И тут они вспомнили про resize: none.

Начали с того, что в вопросах-ответах установили 3 строки ввода и вскоре запретили ресайз (resize: none). Но пользователи-то не лыком шиты, на каждый resize:none у них найдётся свой resize: vertical. Ощущения полной победы над пользователями полем ввода у дизайнера не оставалось.

И тогда появилась находка (у верстальщика — дизайнер об этом даже не мечтал), опробованная в письмах:

textarea {height: 120px!important};

— Браво! — сказал Большой Босс верстальщику, — Молодец, брат, выручил! Теперь они попляшут у нас в пределах 120 пикселей! Теперь просто стилями не обойдёшься, чтобы таскать поле ввода за уголок и ресайзить на сколько хошь. Теперь они и письма будут стараться писать на 6 строк, а ответы, как обычно — на 3 строки. Мы им покажем, как не писать статьи, на которые отведено целых 400 пикселей! (Почему не 800 и вообще почему до сих пор нет автоувеличения поля ввода? Это тебе наш сеошник объяснит.)

И тогда юзеры взялись за скрипты. Сами они не хотели резать и вообще мирные люди. Но пришлось. Небольшая магия скриптов со стилями — и поля снова стали ресайзиться вручную. Но этого показалось мало. Теперь в желаниях юзеров, опьянённых жаждой борьбы и вкусом победы, снова замаячил авторост.

Авторост — это такое свойство поля ввода, не предусмотренное даже браузером (иначе, зачем были бы нужны программисты?). Если в обычный блок добавляешь текст, его границы растут в высоту (вниз) без всяких скриптов. У поля ввода этого нет. Только костыли скриптов помогут полю ввода подрастать и уж очень изысканно надо уметь позаботиться о том, чтобы этот рост был идеальным, кроссбраузерным и таким же точным, до пикселя, какой он изначально есть у блочного элемента (который, например, с тегом DIV). Правда, проблемы значительно уменьшаются, если не нужно обеспечивать автоуменьшение высоты, только автоувеличение.

Реализация

Скрипт HabrAjax дополнился функцией автоувеличения полей ввода по мере роста текстового содержания. Автоуменьшение сознательно не сделано, потому что имеется возможность регулировать высоту поля ввода вручную, двигая за нижний правый уголок (кроме Оперы, где нет такой функции, но в ней устроено автоуменьшение).

Теоретически, этого хотелось давно — не смотреть на ограниченные рамки полей, но так, чтобы не писать 20 строк скрипта, если неудобство решается 1 строкой стилей. Поэтому 1.5-2 года обходились ресайзом стилями и руками. Поэтому и дополнение сейчас — не на 20 строк, а примерно на 7 содержательных, остальное — фарш для прочих эффектов — максимальная высота и отсутствие скролла, когда он не нужен, реалии DOMа. (Код адаптирован для чтения, не точная копия юзерскрипта.)

var dQ = function(q){return document.querySelector(q);};
var win = typeof unsafeWindow !='undefined'? unsafeWindow: window;
var tAGrow = function(tA){ //авторост-обработчик
  if(!tA) return;
  var tSHPrev =0,
    maxH = Math.floor(win.innerHeight *0.8),
    tAF = function(){
      if(tSHPrev < maxH)
        tA.style.overflow ='hidden';
      var tSH = tA.scrollHeight - (isFx?0:6); //isFx = is Firefox; 6 - мутное место для Хрома
      if(tSHPrev < tSH){
        tA.style.height = tSH +'px';
        if(tSHPrev < maxH)
          tA.style.overflow ='hidden';
      }else
        setTimeout(function(){tA.style.overflow ='inherit'}, 250);
      tSHPrev = tSH;
    };
  tA.addEventListener('keypress',tAF,!1); //контроль за ростом блока данных
  tA.addEventListener('keyup',tAF,!1);
  tA.style.resize ='vertical'; //чтобы уменьшать вручную (Fx, Chrome, Safari)
  tA.style.maxHeight = maxH +'px';
};
tAGrow(dQ('.editor #comment_text')||dQ('.editor #answer_text')||dQ('.editor #text_textarea') );
tAGrow(dQ('.editor #text') );

Известно, что если не дублировать в невидимом месте поле ввода для получения правильной высоты текста в Firefox/Chrome/Safari, можно заметить только увеличение высоты поля ввода, а не уменьшение. Уменьшать поле ввода нет частой необходимости, и это можно сделать тасканием за уголок. Поэтому решение — максимально ленивое, но, наверное, будет достаточно удобным. В любом случае, может быть доработано или отключено.

С практической стороны, не хотелось вдаваться в сложности, чтобы соблюсти принцип максимальной простоты. И вот, в момент медитации разбора проблем с ручным ресайзом полей, снизошло просветление, и было познано дао автороста.

Увидеть авторост в действии и пользоваться им на сайте можно, установив версию юзерскрипта Habrajax 0.87 или выше.

Отключается возможность автороста при сохранении других функций скрипта — в настройках; по умолчанию — включено. Проверялось в Fx, Chrome, но остальные 2 браузера должны работать, а в Опере высота должна автоуменьшаться, без необходимости тянуть обратно за уголок (там и возможности такой нет). Могут быть небольшие малоприятные прыжки высоты поля в начале ввода символов из-за многочисленных разных сайтовых вёрсток, это будет решаться чуть позже стилями. Могут всплыть и другие побочные эффекты роста — всё будет тестироваться в реальной работе.

Автор: spmbt

* - обязательные к заполнению поля