Wiki-учебник по веб-технологиям: JavaScript/ОбменДанными ...

Главная | |

Обмен данными


Оглавление документа


Передача данных на сервер из формы осуществляется по событию submit. Это событие происходит при одном из следующих действий пользователя:

При описании отображения контейнера FORM на объекты JavaScript было подробно рассказано об обработке события submit. В данном разделе мы сосредоточимся на сочетании JavaScript-программ в атрибутах полей и обработчиках событий. Особое внимание нужно уделить возможности перехвата/генерации события submit.

1. Кнопка Submit


Кнопка Submit представляет собой разновидность поля ввода. Она ведет себя так же, как и обычная кнопка, но только еще генерирует событие submit (передачу данных на сервер). В этом, с точки зрения JavaScript-программирования, она абсолютно идентична графическим кнопкам:

<FORM>
<INPUT TYPE=submit VALUE=submit>
</FORM>


В данном примере мы просто перезагружаем страницу.

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

click (onClick):

<FORM>
<INPUT TYPE=submit VALUE=Submit onClick="return false;">
</FORM>


При нажатии на кнопку перезагрузки страницы не происходит — передача данных на сервер отменена. Обработчик действует так же, как обработчик события submit в контейнере FORM.

Теперь можно написать собственную программу обработки события submit:

function my_submit()
{
if(window.confirm("Хотите перегрузить страницу?")) return true;
else return false;
}
...
<FORM>
<INPUT TYPE=submit VALUE=Submit onClick="return my_submit();">
</FORM>


Если подтвердить необходимость перезагрузки страницы, она действительно будет перезагружена, а при отказе (cancel) вы вернетесь в текущую страницу без перезагрузки. Действия могут быть и более сложными. В любом случае, если функция обработки возвращает значение true, то передача данных на сервер (в нашем примере — перезагрузка страницы) происходит, иначе (значение false) — данные не передаются.

2. Единственное поле в форме


Если в форме присутствует одно-единственное поле, и мы в него осуществили ввод и после этого нажали Enter, то браузер сгенерирует событие submit:

<FORM onSubmit="window.alert('Сделано');return false;">
<INPUT SIZE=10 MAXLENGTH=10>
</FORM>


Перехватить такое событие и обработать можно только за счет программы обработки события submit в контейнере FORM, что и сделано в примере.

В этом примере, кроме поля ввода, в форме присутствует меню. Если менять значения выбранных альтернатив, то перезагрузки не происходит, но стоит изменить значение в поле ввода и нажать Enter, происходит submit, и система выдает окно предупреждения.

3. Метод submit()


Метод submit() — это метод формы. Если в программе вызывается метод submit, то данные из формы, к которой применяется данный метод, передаются на сервер. Усовершенствуем пример с полем ввода и меню выбора (прежде чем выбирать альтернативы, прочтите комментарий под примером):

<FORM onSubmit="window.alert('Сделано');return false;">
<INPUT SIZE=10 MAXLENGTH=10>
<SELECT onChange="form.submit();">
<OPTION>Вариант 1<OPTION>Вариант 2</SELECT>
</FORM>


При выборе альтернативы пользователь сразу инициирует обмен данными с сервером. Событие submit в данном случае обработчиком событий не перехватывается, в отличие от нажатия Enter. Такое поведение браузера довольно логично. Если программист вызвал метод submit(), то, наверное, он предварительно проверил данные, которые отправляет на сервер.

4. Cookies


Волшебные ключики, или cookies, не являются полями формы, но, тем не менее, отойдя от строгого рассмотрения иерархии объектов JavaScript, мы уделим им немного внимания, как одному из механизмов управления обменом данных.

Основная функция cookie — поддержка сеанса работы между клиентом (браузером) и сервером.

cookie — это небольшой фрагмент текста, который передается от сервера браузеру и потом может быть возвращен обратно. Подробно о cookie рассказано в «Спецификации Cookie», которую можно найти в главе «Дополнения». Программа на JavaScript способна прочитать выставленное значение cookie и даже изменить его. Для этой цели используют свойство объекта DOCUMENT — cookie:

<FORM>
<INPUT TYPE=button VALUE="Показать Cookies"
onClick="window.alert(window.document.cookie);">
</FORM>


В данном случае cookies отображаются в виде одной большой строки со множеством значений. Свойство cookie документа можно переопределить:

function asign()
{
document.cookie="n1=3";
window.alert(document.cookie);
}
...
<FORM>
<INPUT TYPE=button VALUE="Изменить n1" onClick="asign()">
</FORM>


Как видно из примера, программисту не нужно выделять cookie из строки. Браузер рассматривает cookies как ассоциированный массив (хеш) и изменяет значение cookie по имени «ключика».

Наконец, cookie можно удалить. Если быть более точным — деактивировать, указав время его действия:

function change_cookies()
{
a = new Array();
c = new Date();
a = document.cookie.split(';');
document.cookie=a[0]+"; expires="+c.toGMTString()+";";
window.alert(document.cookie);
}
...
<FORM>
<INPUT TYPE=button VALUE="delete cookies" onClick="change_cookies()">
</FORM>


В данном случае мы «удаляем» cookie за счет параметра expires (времени, до которого cookie живет). Так как мы берем текущее время, то cookie исчезает из списка «ключиков». Многократно нажимая на кнопку, можно удалить все cookies для данной страницы.

Как мы уже знаем, функции в JavaScript используются для многократного выполнения одной и той же задачи. До сих пор функции всегда вызывались вручную с помощью скобок: myFunction(). Что, если потребуется вызвать функцию, когда пользователь выполняет определенную задачу? В JavaScript можно соединить функцию практически с любым событием, которое может порождать пользователь. Давайте посмотрим это в действии и напишем функцию, которая подсчитывает, сколько раз пользователь щелкнул на странице.

<script type="text/javascript">
var clickCount = 0;
function documentClick(){
document.getElementById('clicked').value = ++clickCount;
}
document.onclick = documentClick;
</script>


Вы щелкнули на этой странице <input id="clicked" size="3"
onfocus="this.blur();" value="0"> раз.

Вы щелкнули на этой странице раз.

В предыдущей лекции оператор ++ был применен только после переменной, как в случае “clickCount”. Однако в данном примере оператор ++ используется перед переменной. В первом примере “clickCount”, единица добавляется к переменной clickCount после чтения ее значения. В случае “clickCount” единица добавляется к переменной clickCount перед чтением ее значения. Так как в этом примере переменной clickCount в начале присваивается значение 0, то единицу к ней необходимо добавлять до задания значения поля ввода, поэтому использована запись “clickCount”.

Предыдущий пример может показаться достаточно знакомым. Так же, как и раньше, определяется переменная и функция. Изменение состоит в том, что вместо вызова функции documentClick() код содержит указание, что функция должна выполняться всякий раз, когда пользователь щелкает на документе.

"document.onclick " связывает функцию с событием документа onclick ("при щелчке").

Существует множество событий подобных “onclick «. Мы познакомимся с некоторыми из них, но наиболее распространенными являются: onclick, onload, onblur, onfocus, onchange, onmouseover, onmouseout и onmousemove. Функцию можно связать с событиями любого объекта, такого, как изображение или поле ввода, а не только документа. Например, события onmouseover и onmouseout используются обычно с изображениями для создания эффекта изменения.

Можно также заметить, что ссылка на поле ввода делается другим образом. Ранее говорилось, что для указания поля необходимо использовать "document.forms.имяФормы.elements.имяПоляВвода «. Хотя этот способ прекрасно работает, это не всегда необходимо. В данном примере поле ввода действует просто как счетчик. Оно не находится внутри формы, и нам это и не нужно.

Поэтому мы задаем для поля некоторый ID (идентификатор): id="clicked". ID можно использовать для ссылки на любой объект на странице. ID должен быть уникальным на странице, поэтому если имеется 5 полей ввода с ID, то все ID должны быть различны, даже если они только имеют вид “input1”-->"input5 «. Поскольку это поле ввода используется как счетчик, то нежелательно, чтобы пользователи щелкали на нем и изменяли его значение. Здесь на помощь приходит другое связывание, “onfocus ", которое срабатывает, когда курсор перемещается на объект. Поэтому при щелчке на поле ввода или при перемещении на поле ввода с помощью клавиши Tab вызывается “onfocus «.

Событие onfocus имеет очень короткий код, но он также очень важен. В нем появляется ключевое слово “this”, которое важно понимать в JavaScript. Ключевое слово “this” указывает на тот объект, на котором выполняется код. В данном примере “this” указывает на поле ввода. Выражение «this.blur() “ «размывает» поле ввода, другими словами, заставляет его терять фокус ввода. Так как это происходит, как только пользователь активизирует поле ввода, то это делает «невозможным» изменение данных.

Если указатель “this” используется в функции, то он указывает на саму функцию.

Если “this” используется в коде JavaScript вне функции, то он указывает на объект окна. Наиболее часто “this” используется для изменения свойства текущего объекта, как в примере выше, или для передачи текущего объекта функции.

Давайте посмотрим на другой пример:

<script type="text/javascript">
function showValue(obj){
alert('You Clicked On ' + obj.value);
}
</script>
<input type="radio" name="fruit" onclick="showValue(this);" value="Яблоко" >
Яблоко
<input type="radio" name="fruit" onclick="showValue(this);" value="Апельсин"
> Апельсин
<input type="radio" name="fruit" onclick="showValue(this);" value="Груша" >
Груша
<input type="radio" name="fruit" onclick="showValue(this);" value="Банан">
Банан


Яблоко Апельсин Груша Банан

Можно видеть, что событие onclick для каждой из этих радио-кнопок одинаково. Однако, если щелкнуть на каждой из них, то будут получены разные сообщения. Это связано с использованием “this”. Так как “this” указывает на каждую отдельную радио-кнопку, то каждая радио-кнопка передается в функцию “showValue " по отдельности.

Вернемся к функциям и рассмотрим передачу функции аргументов. В предыдущем примере “obj” является аргументом. Предполагается, что “obj” содержит указатель на поле ввода, на котором был произведен щелчок. В функцию можно передавать любое количество аргументов. Если потребуется 10 аргументов, то функция будет выглядеть следующим образом:

function myFunction(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10){
// здесь располагается код
}


Во многих случаях может понадобиться функция, которой требуется определенное количество аргументов, но не всегда требуются все.

В JavaScript не нужно передавать все 10 аргументов в функцию, которая объявлена с 10 аргументами.

Если передать только первые 3, то функция будет иметь только 3 определенных аргумента. Это необходимо учитывать при написании функций. Например, можно написать функцию, которой всегда требуются 3 первых аргумента, но следующие 7 являются необязательными:

function myFunction(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10){
// код с arg1
// код с arg2
// код с arg3
if(arg4){
// код с arg4
}
if(arg5 && arg6 && arg7){
// код с arg5, arg6 и arg7
if(arg8){
// код с arg8
}
}
if(arg9 || arg10){
// код с arg9 или arg10
}
}


Можно видеть, что в коде выполняется простая проверка «if(arg) «. Если аргумент не передается в функцию, то при попытке использовать этот аргумент будет получено значение “undefined «. При использовании “undefined” в качестве логического (булевого) значения (true / false), как в операторах if, оно воспринимается как false.

Поэтому, если arg4 не был передан в приведенном выше примере, то он является “undefined” и тело оператора if не выполняется.

Как быть, когда трудно определить, сколько потребуется аргументов? Можно иметь функцию, которая получает от 1 до n аргументов и выполняет с каждым из них одну и ту же задачу. На этот случай JavaScript имеет в каждой функции объект “arguments”. Объект arguments содержит все аргументы функции:

function myFunction(){
for(var i=0; i<arguments.length; i++){
alert(arguments[i].value);
}
}


Этот код сообщит значение всех переданных ему объектов. Если передать 100 объектов, то будет получено 100 сообщений. Более полезной функцией было бы, возможно, скрытие/вывод всех переданных функции объектов.

Один из наиболее интересных аспектов JavaScript – идея о том, что функции являются объектами и могут передаваться как поле ввода, изображение или что- то еще, что может быть. Посмотрите, например, следующий код:

<script type="text/javascript">
function multiply(){
var out=1;
for(var i=0; i<arguments.length; i++){
out *= arguments[i];
}
return out;
}
function add(){
var out=0;
for(var i=0; i<arguments.length; i++){
out += arguments[i];
}
return out;
}
function doAction(action){
alert(action(1, 2, 3, 4, 5));
}
</script>
<button onclick="doAction(multiply)">Test Multiply</button>
<button onclick="doAction(add)" >Test Add</button>


Test Multiply Test Add

В этом небольшом фрагменте кода происходит очень многое. Вначале просто определяют две функции: multiply и add. Функция multiply просто перемножает все переданные ей числа. Аналогично, функция add складывает все переданные ей числа. Тонкости начинаются при использовании действий onclick двух созданных кнопок. Можно видеть, что при щелчке на любой из двух кнопок в функцию doAction передается объект. Ранее мы всегда передавали переменные или объекты HTML (такие, как поля ввода в предыдущем примере). В этом примере передаются функции. Функции можно передавать таким же способом, как и любой другой объект, и когда они передаются, их можно вызывать таким же способом, как и любую другую функцию. Изменяется только ее имя.

Таким образом функция doAction получает другую функцию в качестве аргумента!

Если передается функция multiply, то функция doAction передает ей значения от 1 до 5, и мы получаем в результате 120. Если в doAction передается функция add, то ей также передаются значения от 1 до 5, и в результате мы получаем значение 15.

Это в действительности одно из наиболее мощных свойств JavaScript, и оно будет более подробно рассмотрено в следующих лекциях.

Пока достаточно понять общий принцип.

Другим важным свойством функций является возможность вложения их друг в друга. JavaScript не поддерживает истинный объектно-ориентированный подход к проектированию, но это свойство обеспечивает очень похожие возможности.

Кроме вложения функций, важно отметить, что имеется несколько различных способов объявления функций:

function myFunction(){
function nestedFunction1(arg1, arg2, arg3){
alert(arg1+arg2+arg3);
}
var nestedFunction2 = function(arg1, arg2, arg3){
alert(arg1+arg2+arg3);
}
var nestedFunction3 = new Function('arg1, arg2, arg3',
'alert(arg1+arg2+arg3);');
}


В этом примере функции nestedFunction1, nestedFunction2 и nestedFunction3 являются одинаковыми по своим возможностям.

Единственное различие состоит в том, как они определяются. nestedFunction1 объявлена, как это делалось раньше.

Синтаксис для nestedFunction2 немного отличается. Мы задаем для функции переменную this.nestedFunction2. Синтаксис этого объявления будет следующий " имяПеременной= function(аргументы){". Аналогично для функции nestedFunction3 задается переменная для новой функции. Однако это объявление существенно отличается, так как мы определяем функцию с помощью строк. Третий вариант используется редко, но является очень полезным, когда используется. Он позволяет создать строку, содержащую код выполняемой функции, а затем определить функцию с помощью этой строки.