Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Текстовые поля с изменяющимся размером.


Добрый день!

Времена, когда приходилось самому писать код для создания эффектов и взаимодействия страницы с сервером, уходят в прошлое. Сейчас создано несколько довольно мощных JavaScript пакетов, которые дают инструментарий для создания Ajax, повышения интерактивности страницы, в том числе для создания динамических форм. Считается, что наиболее красивый дизайн по умолчанию у библиотеки Ext, на сайте вы найдёте множество примеров диковинных контролов и готовых образцов интерфейсов. Например, на странице Resize вы обнаружите объекты для превращения обычных элементов страницы в Resizable, то есть в элементы с изменяемым размером. Особенно мне нравится последний пример, с анимированным изменением размера текстового поля. =)

Наш сегодняшний перевод слегка приоткрывает секрет создания объектов с изменяемым размером.


Оригинал: Javascript Tutorial - Resizeable Textboxes
Переводчик: Додонов Александр Артурович

Текстовые поля с изменяющимся размером

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

Мы собираемся создать текстовое поле с манипуляторами внизу, справа и в нижнем правом углу с помощью которых можно менять размер. Манипуляторы делают то, что вы и могли ожидать - если тащить правый край вы изменяете ширину, если низ - высоту, а если правый нижний угол - то и высоту и ширину одновременно. Большая часть работы уже сделана в предыдущем руководстве о том, как сделать перетаскивание объектов с помощью JavaScript. Возможно, вы захотите его прочесть, прежде чем мы продолжим.

Вот пример. Великий и ужасный.

Так как это у нас перетаскиваемый объект из руководства про перетаскиваемые элементы, код вполне простой. Итак, вначале взгляните на html:


 <div id="textDiv" style="left:10px;top:10px;
    width:100px;height:100px;xposition:relative;">
 <textarea id="textBox" style="width:90px;height:90px;
    left:0px;top:0px;xposition:absolute;"></textarea>
 <div id="handleRight" style="width:5px;height:95px;
    background-color:Red;xposition:absolute;left:95px;
    top:0px;cursor:e-resize;"></div>
 <div id="handleCorner" style="width:5px;height:5px;
    background-color:LightGreen;xposition:absolute;left:95px;
    top:95px;cursor:se-resize;"></div>
 <div id="handleBottom" style="width:95px;height:5px;
    background-color:Blue;xposition:absolute;left:0px;
    top:95px;cursor:s-resize;"></div>
 </div>
  

Действительно не так уж много. В первую очередь оборачивающий div, для того, чтобы позиционировать другие элементы относительно него. Текстовое поле вверху слева и первоначально занимает область 90 пикселей на 90 пикселей. С правой стороны у нас пятипиксельный красный div, на расстоянии 95 пикселей слева. Этот div является правым манипулятором для изменения размера. Причина, по которой мы создаём пятипиксельный отступ между текстовым полем и манипулятором, состоит в том, что 90-пиксельная текстовая область занимает немного больше места, когда у неё появляются скроллбары. Так что мы оставили эти 5 пикселей, чтобы дать текстовой области немного простора. Следующее - это наш зелёный угловой манипулятор, div размером 5x5, в позиции 955x95. Наконец, у нас есть синий нижний манипулятор, высотой в 5 пикселей и на расстоянии 95 пикселей от верха. Поставить в соответствие к этим div'ам нужные курсоры довольно просто - достаточно указать стили для курсора.

Ага, вот код инициализации:


 var textBox = document.getElementById("textBox");
 var handleRight = document.getElementById("handleRight");
 var handleCorner = document.getElementById("handleCorner");
 var handleBottom = document.getElementById("handleBottom");
 var textDiv = document.getElementById("textDiv");

 new dragObject(handleRight, null, new Position(15, 0),
    new Position(500, 0), null, RightMove, null, false);
 new dragObject(handleBottom, null, new Position(0, 15),
    new Position(0, 500), null, BottomMove, null, false);
 new dragObject(handleCorner, null, new Position(15, 15),
    new Position(500, 500), null, CornerMove, null, false);

В первую очередь, мы берём разные элементы и помещаем их в переменные, по большей части потому, что мы собираемся часто к ним обращаться. Нет нужды заставлять браузер зря терять время каждый раз отыскивая эти элементы. Далее, мы делаем три экземпляра dragObject, по одному для каждого манипулятора. Мы задаём для каждого манипулятора минимальное и максимальное граничное значение. Задав ymin и ymax = 0 для правого манипулятора, мы можем быть уверены, что он может двигаться только влево и вправо, но не вверх - вниз. Аналогично мы установим xmin и xmax = 0 для нижнего манипулятора и тем самым он сможет двигаться только вверх - вниз. Мы зададим ограничения от 15 до 500 для оставшихся границ и это будет максимальный и минимальный размер текстового поля. Задавая xmin = 15 и xmax = 500 для правого и для углового манипуляторов мы тем самым определяем, что наше текстовое поля не может иметь ширину больше 495 пикселей и меньше 10px (разница в пять пикселей из-за того, что мы ранее дали текстовому полю свободное место под скролл ) То же самое мы определяем и для высоты, поэтому мы задаём минимальную высоту в 15 пикселей и максимальную в 500 для нижнего и углового манипулятора.

Второй важный аргумент это функции обратного вызова RightMove, BottomMove и CornerMove. Каждый раз, когда сдвигается один из манипуляторов, соответствующая функция будет вызвана (благодаря коду скрытому в dragObject) Итак, давайте взглянем, что эти функции делают:


 function BottomMove(newPos, element)
 {
   DoHeight(newPos.Y, element);
 }

 function RightMove(newPos, element)
 {
   DoWidth(newPos.X, element);
 }

 function CornerMove(newPos, element)
 {
   DoHeight(newPos.Y, element);
   DoWidth(newPos.X, element);
 }

Вау, здесь почти ничего нет. Но перед тем как мы перейдём к функциям DoHeight и DoWidth, давайте посмотрим, что собой представляют их аргументы. newPos - это объект позиционирования, хранящий позицию (верх, лево) элемента который был сдвинут. Переменная element это в точности то, что написано - элемент, который был сдвинут.

Ок, сейчас перейдём к тому месту, где происходит реальная работа:


 function DoHeight(y, element)
 {
   textDiv.style.height = (y + 5) + 'px';

   if(element != handleCorner)
     handleCorner.style.top = y + 'px';

   handleRight.style.height = y + 'px';

   if(element != handleBottom)
     handleBottom.style.top = y + 'px';
 
   textBox.style.height = (y - 5) + 'px';
 }

 function DoWidth(x, element)
 {
   textDiv.style.width =  (x + 5) + 'px';
 
   if(element != handleCorner)
     handleCorner.style.left = x + 'px';

   if(element != handleRight)
     handleRight.style.left = x + 'px';

   handleBottom.style.width = x + 'px';

   textBox.style.width = (x - 5) + 'px';
 }

Эти две функции делают в точности то, что вы подумали - они считают новую высоту и ширину текстового поля (а также сдвигают манипулятор и меняют его размеры) В обоих случаях, мы сначала регулируем размер большого div-контейнера, принимая во внимание ширину (или высоту) манипуляторов. Затем, если мы меняем размер не угловым манипулятором, его тоже нужно сдвинуть в нужное место. (Если вы меняли размер с его помощью, он уже на месте) Для правого манипулятора, в случае изменения размера по высоте мы обновляем его высоту. Если это изменение размера по ширине, мы убеждаемся, что она не производится правым манипулятором, и если это так мы обновляем координату x позиции манипулятора. Для нижнего манипулятора, мы делаем в сущности то же самое, за исключением того, что мы обновляем ширину в то же самое время, что и изменение размера по ширине, и координату y, когда меняем высоту. Наконец, мы, обновляем размер нашего текстового поля, принимая во внимание свободное место.

Вот и всё! С помощью этого кода, а также кода для перетаскивания элементов, вы можете сделать текстовые поля с изменяющимся размером. Да, этот код уродлив и его функциональность ограничена, так что не удивляйтесь, если когда-нибудь в будущем у нас появятся руководство по текстовым полям с изменяющимся размером 2.0. Но до тех пор свободно задавайте вопросы или комментируйте.


Как обычно, через некоторое время эта статья появится на сайте

А ещё прошу любителей писать пошаговые руководства помочь нам наполнить сайт Guidoscope - стартап написанный с использованием технологий упомянутых в прошлых выпусках рассылки. Заранее сердечно благодарен! =)

Всего наилучшего,
искренне ваш Додонов Александр


В избранное