§09. JavaScript и html документ.
Реакция интернет страницы на действие пользователя.
Одно из назначений языка JavaScript в веб программировании заключается в том, что бы делать интернет страницы динамическими, т.е. «заставлять» их реагировать на действия пользователей. В простейшем случае действием пользователя может быть щелчок мыши по какому либо элементу страницы. В этот момент возникает так называемое «событие щелчок мыши», которое можно обработать с помощью JavaScript. Обработать событие означает запустить на выполнение какой-то код, который в свою очередь называется обработчиком события.
События бывают различными. Они генерируются браузером как при щелчке левой кнопки мыши, при нажатии на кнопку клавиатуры, так и при открытии документа или изменении размеров окна браузера. Подробнее всевозможные события будут изучены в соответствующем параграфе. На данном этапе рассмотрим только одно – щелчок мыши на элементе Html документа. В коде программы это событие имеет имя onсlick.
Всего существует несколько механизмов обработки событий. На данном этапе рассмотрим один из них. У большинства тэгов html может быть атрибут onclik. Он отвечает за обработку события, возникающего при нажатии кнопки мыши на элементе, созданном данным тэгом. Этому атрибуту необходимо присвоить значение, которое является JavaScript кодом. Этот код и будет обработчиком события onclick. Пример:
<!DOCTYPE html>
<html>
<body>
<div onclick = "alert('Вы нажали на элемент страницы')">Нажми меня!</div>
</body>
</html>
При нажатии на элементе появляется диалоговое окно:
Примечание: функция alert вызывает диалоговое окно с сообщением. Она была рассмотрена в 1 параграфе.
Обратите внимание на то, что для присвоения значения атрибуту onclick были использованы двойные кавычки, а уже в самом JavaScript коде для создания строки – одинарные. На практике можно сделать наоборот:
onclick = 'alert("Вы нажали на элемент страницы")'
Результат при этом не изменится.
Здесь стоит вспомнить от том, что есть негласное правило: для того, что бы не запутываться, необходимо для себя определиться, где какие кавычки использовать. Как правило, в коде JavaScript используют одинарные кавычки, а в html коде – двойные. Это правило мы использовали, когда вставляли тэги с помощью метода document.write. В качестве аргумента мы отправляли ему строку с html кодом. Сама строка была в одинарных кавычках, а атрибуты тэгов в двойных.
Для того, что бы отделить JavaScript код от html, код обработчика события определяют как функцию в тэге script. А в качестве значения атрибуту onclick присваивают эту функцию. Причём функция может быть определена и в отдельном файле. Пример:
<body>
<div onclick = 'F()'>Нажми меня!</div>
<script>
function F()
{
alert("Вы нажали на элемент страницы")
}
</script>
</body>
Результат останется прежним.
Использование элемента button для вызова JavaScript кода.
Как было уже сказано, практически любой элемент html документа может иметь атрибут onclick. Соответственно практически для любого элемента можно написать обработчик нажатия. Для наших последующих программ мы будем использовать элемент, который имитирует кнопку, как в «виндоусовских» приложениях. Пример:
<input type = "button" value = "Нажми меня" onclick = "F();">
Доступ к элементам Html документа.
Для того, что бы производить различные манипуляции с элементами html документа, программист должен иметь к ним доступ в коде программы. Один из способов обращения к элементам заключается в том, что у каждого элемента может быть атрибут id. Если у элемента он присутствует, и ему присвоено какое-либо значение, то в коде JavaScript появляется объект с таким же именем. Используя этот объект, можно обращаться к данному элементу.
Например, если у элемента div есть атрибут id со значением «div_1», то в JavaScript коде будет объект div_1. Этот объект, в свою очередь, отражает данный элемент div и имеет свойства и методы для работы с ним. Причём самому программисту объявлять данный объект уже не нужно.
Свойство innerHTML объектов, отражающих элементы HTML документа.
У любого объекта, отражающего элемент HTML документа, есть свойство innerHTML, которое можно использовать для чтения и изменения его содержимого.
Далее пример, в котором присутствует элемент div и кнопка, при нажатии на которую выводится в диалоговое окно содержимое этого элемента div:
<body>
<div id = "div_1"><h1 align = "center">Привет всем!</h1></div>
<input type = "button" value = "Содержимое div" onclick = "F();">
<script>
function F()
{
alert(div_1.innerHTML);
}
</script>
</body>
При нажатии на кнопку:
Теперь изменим функцию F так, что бы при нажатии на кнопку менялось содержимое элемента div:
function F()
{
div_1.innerHTML = '<h2>Нажали на кнопку</h2>';
}
После нажатия:
Формирование содержимого элемента. Конкатенация строк.
В предыдущем параграфе была создана база данных учеников. Сейчас, используя полученные знания, мы можем создать страницу, в которой пользователь при желании может отсортировать по фамилии таблицу с учениками, нажав на кнопку. Для этого необходимо добавить в объект clas метод, который будет формировать строку с таблицей и вставлять её в документ.
Для написания данного метода нам необходимо знать о том, что строки можно соединять друг с другом с помощью знака +. Соединение строк в программировании называется конкатенацией строк. Пример:
var s = 'Привет' + ' ' + 'всем' + '!';
//В результате s содержит «Привет всем!»
Далее получившийся метод и пример его использования:
<body>
<script>
function Birthday(d,m,y)//Конструктор
{
...........
}
function Pupil(SN,N,A,d,m,y)//Конструктор
{
...........
}
function Clas()//Конструктор
{
.............
this.sort_S_Print = function()//Сортирует и выводит
{
this.sort_S();
var s;
s = '<table border = "1">';
s = s + '<tr><td><b>Фамилия</b></td>'+
'<td><b>Имя</b></td>'+
'<td><b>Возраст</b></td>'+
'<td><b>Дата рождения</b></td></tr>';
for (var c = 0;c<this.size; c=c+1)
s = s + '<tr><td>' + clas.pupils[c].surname +
'</td><td>' + clas.pupils[c].name +
'</td><td>' + clas.pupils[c].age +
'</td><td>' + clas.pupils[c].birthday.day + ' ' +
clas.pupils[c].birthday.month + ' ' +
clas.pupils[c].birthday.year + 'г.</td></tr>';
s = s + '</table>';
table_of_pupil.innerHTML = s;
}
}
var clas = new Clas();
document.write('<div id = "table_of_pupil">');
clas.print_table();
document.write('</div>');
document.write('<input type = "button" value = "Сортировать по фамилии" onclick = "clas.sort_S_Print();">');
</script>
</body>
После нажатия на кнопку:
Примечание: в данном примере код, который остался без изменения был заменён многоточиями.
Отступление: здесь необходимо сказать несколько слов о политике использования JavaScript в документах. В данном примере таблица была сформирована в коде программы. Если в браузере у пользователя будет запрещено выполнение сценариев JavaScript, то он эту таблицу не увидит вообще. Поэтому в первоначальном виде она должна существовать в html коде. А сама кнопка может быть добавлена из сценария JavaScript, как было сделано в примере.
Только нужно знать и помнить о том, что метод document.write добавляет содержимое в html документ только в то место, где находится тэг script. Т.е. тег script с кодом, вставляющим кнопку, необходимо поместить туда, где эта кнопка должна быть. Так же необходимо знать о том, что с помощью метода document.write можно вставлять в документ содержимое только на этапе формирования страницы. После полной загрузки страницы вызов этого метода сотрёт всё содержимое и начнёт страницу заново.
Так же стоит сказать о том, что поисковые системы при анализе html документов игнорируют JavaScript код. Поэтому если вам важно, что бы тот или иной контент был проанализирован поисковиком, то он должен присутствовать в html документе.
Динамическое изменение свойств CSS.
Одной из замечательных возможностей JavaScript является то, что можно менять CSS свойства элементов в коде программы. В предыдущем подразделе мы рассмотрели свойство объектов отражающих элементы Html документа innerHTML. Так же у таких объектов есть свойство style, которое является объектом со свойствами CSS данного элемента. Эти свойства имеют такие же имена, как и в html документе за не большими исключениями.
Например, в следующем примере осуществлён доступ к свойству CSS color, при этом после нажатия на элемент цвет текста будет изменён:
<body>
<div id = "div_1" onclick = "div_1_onclick()">Нажми меня!</div>
<script>
function div_1_onclick()
{
div_1.style.color = 'red';
}
</script>
</body>
После нажатия:
Правила формирования имён свойств объекта style.
Как было уже сказано имена свойств в объекте style и css в некоторых случаях отличаются. Для того, что бы сформировать название свойства в объекте style, необходимо придерживаться следующих правил:
во-первых, названия свойств пишутся маленькими буквами. Даже первый символ тоже должен быть маленьким. Исключением является случай описанный в следующем правиле.
во-вторых, если в css в названии свойства есть дефис, то он пропускается, а следующая за ним буква становится большой. Например: в css – border-color, в JavaScript – borderColor.
Пример:
<body>
<div id = "div_1" onclick = "div_1_onclick()">Нажми меня!</div>
<script>
function div_1_onclick()
{
div_1.style.borderStyle = 'solid';
div_1.style.borderColor = 'red';
div_1.style.borderWidth = '2px';
}
</script>
</body>
После нажатия:
Динамическое скрытие и показ элементов с помощью свойства CSS display.
С помощью CSS свойства display элементы html документа можно скрывать и показывать. В следующем примере при нажатии на кнопки показывается и скрывается текст:
<body>
<div id = "text">
Текст. Текст. Текст. Текст. Текст. Текст. Текст.
Текст. Текст. Текст. Текст. Текст. Текст. Текст.
Текст. Текст. Текст. Текст. Текст. Текст. Текст.
Текст. Текст. Текст. Текст. Текст. Текст. Текст.
Текст. Текст. Текст. Текст. Текст. Текст. Текст.
Текст. Текст. Текст. Текст. Текст. Текст. Текст.
Текст. Текст. Текст. Текст. Текст. Текст. Текст.
Текст. Текст. Текст. Текст. Текст. <br><br>
<input type = "button"
value = "Скрыть текст"
onclick = "close_text();"
id = "button_close_text">
</div>
<input type = "button"
value = "Показать текст"
onclick = "open_text();"
style = "display:none"
id = "button_open_text">
<script>
function close_text()
{
text.style.display = 'none';
button_close_text.style.display = 'none';
button_open_text.style.display = 'inline';
}
function open_text()
{
text.style.display = 'inline';
button_close_text.style.display = 'inline';
button_open_text.style.display = 'none';
}
</script>
</body>
После нажатия на кнопку:
Снова нажав на кнопку, всё вернётся в исходное состояние.
Задачи.
1. Добавить в документ с базой данных учеников группу радио кнопок для сортировки таблицы по различным параметрам. После нажатия на кнопки таблица должна автоматически обновляться.
Примечание: радио кнопки имеют индикацию нажатия, т.е. в группе нескольких кнопок индикатор должен показывать, какая кнопка нажата в данный момент. В нашем случае группа радио кнопок может выглядеть следующим образом:
<table style = "border:solid 1px #2B4F82;border-radius:5px;background-color:#F2F2F2;">
<tr>
<td>◉</td>
<td><input type = "button" value = "Сортировать по фамилии"></td>
</tr>
<tr>
<td>◯</td>
<td><input type = "button" value = "Сортировать по возрасту"></td>
</tr>
<tr>
<td>◯</td>
<td><input type = "button" value = "Сортировать по среднему балу"></td>
</tr>
</table>
2. Создать раскрывающееся содержание двумя способами: с помощью изменения свойства css display и с помощью свойства innerHTML.
3. Создать страницу с калькулятором.
Примечание: возможно при решении данной задачи вам понадобиться из свойства innerHTML брать значение в качестве числа. Т.к. свойство innerHTML – это строка, то если вы присвоите его переменой, то она то же станет строкой. В дальнейшем, когда вы будете производить вычисления у вас, возможно, из-за этого появится ошибка. О том, как переводить строки в числа и наоборот речь будет идти в соответствующем параграфе. Н данном этапе для того, что бы переменная, которой вы присвоите значение типа строка, осталась типом число можно умножить её на 1. Пример:
var r = '32.3'*1;//r = 32.3 тип число
Примеры решений.
2.
С помощью свойства CSS display:
<!DOCTYPE html>
<head>
<style>
.main {cursor:pointer;}
.second {cursor:auto;}
</style>
</head>
<html>
<body>
<ul class = "main">
<li><span onclick = "item_1_onclick()">1.Пункт первый.</span>
<ul class = "second">
<li id = "item_11">1.1.Пункт один один.</li>
<li id = "item_12">1.2.Пункт один два.</li>
</ul>
</li>
<li><span onclick = "item_2_onclick()">2.Пункт второй.</span>
<ul class = "second">
<li id = "item_21">2.1.Пункт два один.</li>
<li id = "item_22">2.2.Пункт два два.</li>
</ul>
</li>
</ul>
<script>
//Переводим список в скрытое состояние
item_11.style.display = 'none';
item_12.style.display = 'none';
item_21.style.display = 'none';
item_22.style.display = 'none';
function item_1_onclick()
{
if (item_11.style.display == 'none')
{
item_11.style.display = 'list-item';
item_12.style.display = 'list-item';
}
else
{
item_11.style.display = 'none';
item_12.style.display = 'none';
}
}
function item_2_onclick()
{
if (item_21.style.display == 'none')
{
item_21.style.display = 'list-item';
item_22.style.display = 'list-item';
}
else
{
item_21.style.display = 'none';
item_22.style.display = 'none';
}
}
</script>
</body>
</html>
С помощью свойства innerHTML:
<!DOCTYPE html>
<head>
<style>
.main {cursor:pointer;}
.second {cursor:auto;}
</style>
</head>
<html>
<body>
<ul class = "main">
<li id = "item_1"><span onclick = "item_1_onclick()">1.Пункт первый.</span>
<ul class = "second">
<li>1.1.Пункт один один.</li>
<li>1.2.Пункт один два.</li>
</ul>
</li>
<li id = "item_2"><span onclick = "item_2_onclick()">2.Пункт второй.</span>
<ul class = "second">
<li>2.1.Пункт два один.</li>
<li>2.2.Пункт два два.</li>
</ul>
</li>
</ul>
<script>
//Сохраняем первоначальное состояние
var s_item_1_inline = item_1.innerHTML;
var s_item_2_inline = item_2.innerHTML;
//Создаём скрытый список
var s_item_1_none =
'<span onclick = "item_1_onclick()">1.Пункт первый.</span>';
var s_item_2_none =
'<span onclick = "item_2_onclick()">2.Пункт второй.</span>';
//Переводим список в скрытое состояние
var item_1_display = 'none';
item_1.innerHTML = s_item_1_none;
var item_2_display = 'none';
item_2.innerHTML = s_item_2_none;
function item_1_onclick()
{
if (item_1_display == 'none')
{
item_1.innerHTML = s_item_1_inline;
item_1_display = 'inline';
}
else
{
item_1.innerHTML = s_item_1_none;
item_1_display = 'none';
}
}
function item_2_onclick()
{
if (item_2_display == 'none')
{
item_2.innerHTML = s_item_2_inline;
item_2_display = 'inline';
}
else
{
item_2.innerHTML = s_item_2_none;
item_2_display = 'none';
}
}
</script>
</body>
</html>
Результат тот же.
3.
<!DOCTYPE html>
<html>
<head>
<style>
input {width:100%;}
table {border:solid 1px #707070;border-radius:3px;background-color:#F2F2F2}
</style>
</head>
<body>
<table>
<tr>
<td colspan = "5" style = "border:solid 1px #707070;border-radius:3px;background-color:white;text-align:right;height:3ex;padding:0.2em;">
<div id = "txt"></div>
</td>
</tr>
<tr>
<td><input type = "button" value = "7" onclick = "button_number_onclick(7)"></td>
<td><input type = "button" value = "8" onclick = "button_number_onclick(8)"></td>
<td><input type = "button" value = "9" onclick = "button_number_onclick(9)"></td>
<td><input type = "button" value = "/" onclick = "button_action_oncklick('/')"></td>
<td><input type = "button" value = "C" onclick = "button_clear_oncklick()"></td>
</tr>
<tr>
<td><input type = "button" value = "4" onclick = "button_number_onclick(4)"></td>
<td><input type = "button" value = "5" onclick = "button_number_onclick(5)"></td>
<td><input type = "button" value = "6" onclick = "button_number_onclick(6)"></td>
<td><input type = "button" value = "*" onclick = "button_action_oncklick('*')"></td>
<td><input type = "button" value = "±" onclick = "button_minus_oncklick()"></td>
</tr>
<tr>
<td><input type = "button" value = "1" onclick = "button_number_onclick(1)"></td>
<td><input type = "button" value = "2" onclick = "button_number_onclick(2)"></td>
<td><input type = "button" value = "3" onclick = "button_number_onclick(3)"></td>
<td><input type = "button" value = "+" onclick = "button_action_oncklick('+')"></td>
<td rowspan = "2"><input type = "button" value = "=" onclick = "button_equal_oncklick()" style = "height:100%;"></td>
</tr>
<tr>
<td colspan = "2"><input type = "button" value = "0" onclick = "button_number_onclick(0)"></td>
<td><input type = "button" value = "." onclick = "button_p_oncklick()"></td>
<td><input type = "button" value = "-" onclick = "button_action_oncklick('-')"></td>
</tr>
</table>
<script>
var number_1 = 0,number_2 = 0;//первое и второе число соответственно
var current_number = 1;//Текущее вводимое число
var point = 0;//Была ли нажата кнопка с точкой
var after_point = 1;//Количество знаков после точки
var action = '';//Какое выбрано действие (умножение или деление и т.д.)
//Функция формирует число
function make_number(num,x)
{
if (point==0)//Если кнопка точка ещё не нажата
{
num = num*10+x;
}
else//Если кнопка точка уже нажата
{
num = num+x/Math.pow(10,after_point);
after_point = after_point+1;
}
return num;
}
//Нажатие на кнопку с точкой
function button_p_oncklick() {point = 1;}
//Нажатие на кнопку с цифрой
function button_number_onclick(x)
{
if (current_number==1)//Если вводится первое число
{
number_1 = make_number(number_1,x);
txt.innerHTML = number_1;
}
else//Если вводится второе число
{
number_2 = make_number(number_2,x);
txt.innerHTML = number_2;
}
}
//Нажатие на кнопки с действиями (*/+-)
function button_action_oncklick(d)
{
//Следующее действие нужно для того, что бы после нажатия на кнопку равно
//Получившееся число стало числом number_1
if (txt.innerHTML == '')
number_1 = 0
else
number_1 = txt.innerHTML*1;//*1 Для того, что бы number_1 осталось типом число
//Если произошло повторное нажатие на кнопку действие
if (current_number == 2) number_2 = 0;
//Запоминаем нужное действие и меняем текущее число
action = d;
current_number = 2;
point = 0;
after_point = 1;
}
//Сброс всех значений
function clear()
{
number_1 = 0;
number_2 = 0;
current_number = 1;
point = 0;
after_point = 1;
action = '';
}
//Нажатие на кнопку равно
function button_equal_oncklick()
{
if (action == '/') txt.innerHTML = number_1/number_2;
if (action == '*') txt.innerHTML = number_1*number_2;
if (action == '+') txt.innerHTML = number_1+number_2;
if (action == '-') txt.innerHTML = number_1-number_2;
clear();
}
//Нажатие на кнопку плюс минус
function button_minus_oncklick()
{
if (current_number==1)
{
number_1 = -1*number_1;
txt.innerHTML = number_1;
}
else
{
number_2 = -1*number_2;
txt.innerHTML = number_2;
}
}
//Нашатие на кнопку сброса
function button_clear_oncklick()
{
clear();
txt.innerHTML = '';
}
</script>
</body>
</html>