В этой небольшой статье я хочу поделиться с читателем информацией о применении объектно-ориентированного подхода в javaScriipt при работе с формами на веб-странице.
Для демонстрации я создал страницу с 2 разными формами. Не смотря на то, что обе формы выполняют приблизительно одну и ту же задачу: позволяют пользователю оформить заявку, поля в них – различаются.
Формы на странице скрыты и появляются при клике по соответствующим ссылкам. Для того, чтобы все правильно работало, необходимо реализовать следующий функционал: затенение экрана и появление формы, позиционирование формы по центру экрана, скрытие формы и снятие затенения экрана. Так как у нас 2 формы, придется дублировать код, чтобы реализовать все это для обоих форм. Это совсем не обязательно делать, если использовать объектно-ориентированный подход.
Сначала рассмотрим структуру страницы с формами.
HTML
…
<body>
<div id="overlay"></div>
<div id="wrap">
<h1>Обрабатываем формы с помощью JavaScript ООП</h1>
<div class="btn-wrap">
<div class="btns"><a href="#" id="sh-frm-1">Показать форму №1</a></div>
<div class="btns"><a href="#" id="sh-frm-2">Показать форму №2</a></div>
</div>
</div>
<!--перезвоните мне-->
<div id="form_wrapper_call">
<span class="wr_close">×</span>
<div class="frm_place">
<form action="send_data.php" method="post" id="call_ord">
<div>
<input type="text" name="v_name" id="v_name" value="Введите ФИО" />
</div>
<div>
<input type="text" name="v_phone" id="v_phone" value="Введите телефон" />
</div>
<div id="time_div2">
<p>Удобное время для звонка:</p>
<label for="v_stime">С</label>
<input type="text" name="v_stime" id="v_stime" value="00:00" />
<label for="v_ftime">ДО</label>
<input type="text" name="v_ftime" id="v_ftime" value="00:00" />
</div>
<div id="subm_div2">
<p class="warn">Все поля обязательны для заполнения!</p>
<input type="submit" name="sord_call" id="sord_call" value="" />
</div>
</form>
</div>
</div>
<!--Задать вопрос-->
<div id="form_wrapper_quest">
<span class="wr_close">×</span>
<div class="frm_place">
<form action="send_data.php" method="post" id="sell_flat" enctype="multypart/form-data">
<div>
<input type="text" name="sfv_name" id="sfv_name" value="Введите ФИО" />
</div>
<div>
<input type="text" name="sfv_phone" id="sfv_phone" value="Введите телефон" />
</div>
<div>
<input type="text" name="sfv_email" id="sfv_email" value="Введите e-mail" />
</div>
<div>
<textarea name="sfv_mess" id="sfv_mess">Введите сообщение</textarea>
</div>
<div id="subm_div3">
<p class="warn">Все поля обязательны для заполнения!</p>
<input type="submit" name="ss_flat" id="ss_flat" value="" />
</div>
</form>
</div>
</div>
</body>
Код страницы состоит из нескольких элементов: двух ссылок с идентификаторами (sh-frm-1
и sh-frm-2
) и двух блоков с формами. У блоков с формами также есть идентификаторы (form_wrapper_call
и form_wrapper_quest
).
Для работы потребуется подключить jQuery.
Теперь можно переходить к написанию javaScript кода. Необходимо объединить все функции, описанные выше, в один «класс», сделав их методами этого «класса». Я специально пишу слово «класс» в кавычках, потому что в javaScript классов не существует. При создании объекта этого «класса» передавать в него массив параметров, с которыми будут работать функции. Итак, код получается следующий.
javaScript
function PageForm(p)
{
var o = this;
this.root = $(p.root);
this.closeBtn = $(p.closeBtn, p.root);
this.overlayBlock = $(p.overlayBlock);
this.showBtn = $(p.showBtn);
this.init = function()
{
o.showBtn.click(function(event){
o.showFormBlock();
event.preventDefault();
});
o.closeBtn.click(function(){
o.hideFormBlock();
});
}
}
// функция показывает «затемнение»
PageForm.prototype.showOverlay = function(){
var o = this;
// определяем блок
var over = o.overlayBlock;
// увеличиваем его размер до размеров окна и проявляем его
over.height($('html').height()+'px').width($('html').width()+'px').fadeIn(500);
}
//настраиваем позиции при скролле страницы
PageForm.prototype.ajustScrollTop = function(){
var o = this;
// определяем высоту видимой части страницы
var clHght = document.documentElement.clientHeight;
// определяем высоту изображения
var clformh = o.root.height();
// вычислям позицию верхнего левого угла блока с изображением
var posY = (clHght - clformh)/2+$(window).scrollTop();
// позиционируем блок
o.root.css('top',posY).css('margin-top','0');
}
//прячем форму и затемнение
PageForm.prototype.hideFormBlock = function(){
var o = this;
o.root.hide();
o.overlayBlock.hide();
}
//показываем форму и затемнение
PageForm.prototype.showFormBlock = function(){
var o = this;
o.showOverlay();
o.root.show();
o.ajustScrollTop();
}
Создаем «класс» PageForm
. В начале «класса» создаем несколько свойств: через них будут передаваться параметры для функций-методов PageForm
. Этот код я разместил в отдельном файле и подключил его к странице.
this.root
– блоки - родители форм (div#form_wrapper_call
и div#form_wrapper_quest
)
this.closeBtn
– «кнопка» при клике по которой будет происходить скрытие форм (span.wr_close
)
this.overlayBlock
– блок для затенения окна (div#overlay
)
this.showBtn
– ссылки для показа форм (a#sh-frm-1
и a#sh-frm-2
)
Далее внутри «класса» описываем один метод для инициализации всех параметров. Метод называется init
, в нем описываются все обработчики действий пользователя на странице. В нашем случае их может быть только 2: клик по ссылке для показа формы и клик по кнопке для скрытия формы. Функции, осуществляющие всю основную работу: показывающие затемнение, форму, позиционирующую блок с формой, скрывающую форму и затенение, правильней будет разместить в прототип объекта PageForm
. Эти функции будут присутствовать и в «классе» PageForm
, так как будут унаследованы. Как известно в javaScript наследование реализовано особым образом и основано на прототипах объекта. Для чего же нужно размещать код функций в прототипе PageForm
? Ответ следующий: для оптимизации расходования памяти. В нашем случае на странице всего 2 формы и мы будет создавать только 2 объекта, а если форм намного больше, то для каждого объекта будет создаваться свои экземпляры всех функций. Если же разместить все методы в прототипе, то для каждого объекта методы создаваться не будут, они будут браться из прототипа.
Теперь, когда все более или менее понятно, можно перейти к созданию объектов.
HTML
<head>
…
<script src="/script/jquery-1.9.1.min.js"></script>
<script src="/script/script.js"></script>
<script>
$(function(){
// форма №1
var frm1 = new PageForm({
root: '#form_wrapper_call',
closeBtn: '.wr_close',
overlayBlock: '#overlay',
showBtn: '#sh-frm-1'
});
frm1.init();
// форма №2
var frm2 = new PageForm({
root: '#form_wrapper_quest',
closeBtn: '.wr_close',
overlayBlock: '#overlay',
showBtn: '#sh-frm-2'
});
frm2.init();
});
</script>
</head>
…
Если вы все сделали правильно, то у вас должна получиться правильно работающая страничка с 2 ссылками, при клике по которым открываются 2 разные формы.
В заключении статьи мне хотелось бы подвести небольшой итог. Какую же выгоду мы получаем при использовании объектно-ориентированного подхода в javaScript? Основным плюсом такого подхода, является то, что наш код не дублируется и весь функционал хранится упорядоченно, а объекты, созданные из «класса», совершенно не зависимы друг от друга.
Страница с демонстрацией примера