покс
1. Скриптовой тег и его структура
<script language="JavaScript">
function greet(){
alert("Hello World !!!")
}
</script>
<script language="JavaScript">
</script>
2. События, основные события JS.
ЧТО ТАКОЕ СОБЫТИЯ JAVASCRIPT
Событие - это какое-либо действие, осуществляемое пользователем либо браузером. Например, когда мы щелкаем (кликаем) на ссылке - осуществляется событие, его перехватывает специальный обработчик и перенаправляет нас на нужную страницу; при наведении курсора (указателя мыши) на ссылку в строке состояния (обычно находится в нижней части окна браузера) отображается адрес, так как обработчик "наведения курсора на объект (в данном случае на ссылку)" помещает туда этот адрес и так далее...
ОСНОВНЫЕ СОБЫТИЯ JAVASCRIPT
Итак, загрузим страницу с примерами и начнем ее изучение. Для того, чтобы примеры на странице работали нужно иметь браузер с поддержкой JavaScript. Самые распространенные из них (скорей всего одним из них Вы пользуютесь): Netscape 6.0+, Mozilla 1.0+, Microsoft Internet Explorer 4.0+, Opera 3.0+, Firefox 1.0+ (+ значит, что версия может быть выше чем указанная мною).
а) onmouseout и onmouseover
Для начала наведем курсор на кнопку "Сброс" или "Отправить" и обратим внимание на строку состояния. Вы должны увидеть там надпись с объяснением значения кнопки. Теперь отведите курсор и строка состояния очистится.
Содержимое строки состояния хранится в переменной window.status. Переменная это некоторый объект (можно представить себе ящик), значение которого (содержимое которого) можно изменять. Изменение значения осуществляется операцией присваивания (=), а выглядит она следующим образом:
имя_переменной = "значение"; (какие использовать кавычки: одинарные или двойные значения не имеет)
Поэтому для того, чтобы изменить надпись в строке состояния, нам нужно присвоить переменной window.status нужное нам значение (подсказку к кнопке), а когда курсор будет убран - присвоить пустую строку("").
Вся задача сводится к тому, чтобы определить когда пользователь наводит курсор на кнопку, а когда убирает его. Для этого нужно "сказать" обработчикам этих событий выполнить нужное нам действие. Обработчик события "наведение курсора" - onmouseover, а "отведение курсора" - onmouseout.
Очень многие тэги имеют атрибуты, начинающиеся с on (onclick, onmouseout, onfocus и т. д.). Значение этих атрибутов и есть, задача которую необходимо выполнить соответствующему обработчику. То есть для обработчика onmouseout есть атрибут onmouseout, для onmouseover - onmouseover. И в итоге мы получаем следующее определение кнопок:
<input type="submit value="Готово" onmouseover="window.status='Щелкните для отправки данных'" onmouseout="window.status=''" />
<input type="reset" value="Сброс" onmouseover="window.status='Щелкните для удаления введенного'" onmouseout="window.status=''" />
Как Вы видите, атрибут onmouseover имеет в качестве значения JavaScript-код: window.status='Щелкните для отправки данных', как только курсор достигает кнопки, обработчик события mouseover - onmouseover, смотрит, что хранится в атрибуте onmouseover и выполняет необходимое действие(присвоение значения переменной window.status). Аналогично действует и обработчик события onmouseout: как только курсор уводиться от кнопки (то есть выполняется событие mouseout), то обработчик события - onmouseout выполняет код, содержащийся в атрибуте onmouseout.
То же самое и со второй кнопкой.
б) <a href="javascript:function()">Function</a>
Теперь щелкните на ссылке и откроется окошко с подсказкой. Но заметьте, что окно небольших размеров и у него нет панели инструментов - такого силами html не сделаешь! В данном примере мы имеем окно размером 300x200, без панелей инструментов, содержащее документ help.html.
Для того чтобы создать такое окошко существует следующий JavaScript-код:
helpWindow = window.open("help.html", "", "toolbar=0,width=300,height=200"); где:
1. helpWindow - это имя переменной (как window.status, только в данном случае имя выбирается произвольно). Эта переменная нужна для последующей работы с окном (например, закрыть его нестандартным способом - с помощью JavaScript-сценария).
- Зачем? Не проще ли указывать просто имя открывающейся страницы, например help.html?
- А если у нас две копии одной и той же страницы? Или две страницы с одинаковым именем(например, в разных папках)? Вот для того, чтобы не перепутать страницы и свободно работать именно с тем окном с которым предполагаешь и сделанно, так чтобы "окно" присваивалось переменной, так как имя переменной можно выбрать любое.
2. window.open(что-то) - это функция. Функции выполняют определенную задачу, в данном случае window.open() открывает новое окно.
3. help.html - это страница, которую нужно открыть.
4. "" - В кавычках должно быть имя окна, но оно нам не пригодится, поэтому там нулевая строка. В следующих кавычках указываются "параметры открываемого окна": оно не должно содержать панели инструментов (toolbar=0) и должно быть шириной 300 пикселей, а высотой - 200 (width=300,height=200, соответственно).
Теперь все, что нужно это по событию "щелчка" выполнить этот код, однако есть два "но". Во-первых строка очень длинная, чтобы присвоить ее какому-либо атрибуту - будет некрасиво смотреться, да и вызывать неудобства при чтении кода страницы. Во-вторых, первоначальное предназначение ссылки - это переход на другую страницу, но нам переходить никуда не нужно, нам нужно выполнить вместо этого JavaScript-код.
Первое решается написанием функции. Как я уже говорил функция выполняет некоторую задача, причем для использования функции достаточно указать ее имя. Можно не только использовать предопределенные(функции, которые имеется в языке и без нас), но и писать их самому. Обычно функции определяются(пишутся) в разделе HEAD документа, в котором используются:
<script type="text/javascript">
function help()
{
helpWindow = window.open("help.html", "", "toolbar=0,width=300,height=200");
}
</script>
"function" значит, что дальше будет написана наша функция; help() - это имя функции (оно будет указываться вместо тела функции (между { и })).
Вторая проблема решается тоже довольно просто. Адрес страницы указывается в атрибуте href, а нам надо выполнить JavaScript код вместо перехода по ссылке:
<a href="javascript:help()">Щелкните на ссылке для получения помощи</a>
"javascript:" означает, что дальше должен идти JavaScript-код, и что он должен выполняться вместо стандартного перехода по ссылке. В данном случае наш JavaScript-код - это созданная нами функция help().
в) onclick
Нам не остается ничего более, как закрыть окно со справкой. Для этого воспользуемся кнопкой "Закрыть". Но нас интересует то, как работает эта кнопка, а имеет она следующий вид:
<input type="button" value="Закрыть" onclick="window.close()">
Дабы закрыть окно мы сделали щелчок(Click) на кнопке "Закрыть", а щелчок это нажатие и отпускание кнопки мыши, причем и то и другое должно быть произведено на одном и том же элементе (например, на кнопке). Кликая, на кнопке мы активируем обработчик события onClick, который выполняет для нас JavaScript-код, прописанный в атрибуте onclick нашей кнопки. Помните мы открывали окно? Мы писали window.open(), а здесь тоже самое только window.close(). window - это текущее окно, а close() - закрыть.
Это одно из наиболее частоупотребляемых событий.
г) onfocus и onblur
Ну что ж будем ближе подбираться к вводу требуемой от нас информации.
Как я уже говорил: элемент получает фокус когда на нем происходит нажатие кнопки мыши, или на него осуществляется переход посредством клавиши табуляции (Tab), а теряет, когда фокус получает другой элемент. Наше поле для ввода получит фокус тогда, когда пользователь решиться ввести информацию. При этом было бы удобно, чтобы текст с подсказкой ("Введите Ваше имя") автоматически выделялся и посетитель мог его удалить одним нажатием на del, а не удалять по одному символу, или выделять текст вручную. Удобство пользователя свято. Итак, для этого мы воспользуемся событием focus. Для выделения текста используется метод select(). То есть атрибутом к полю надо прописать: onfocus="this.select();", this обозначает, что выделение должно происходить именно в этом текстовом поле (а можно прописать путь и к другому, но это не целесообразно).
А теперь попробуйте ничего не изменяя (или все удалив) убрать фокус (например, щелкнув в любом месте окна, или нажав Tab). Это событие blur, я прописал в нем выполнение функции: onblur="check();". Сама же функция имеет следующий вид (в разделе head страницы с формой между <script> и </script>):
function check()
{
var val=document.forms[0].name.value;
if(val == '' || val == 'Введите Ваше имя')
{
alert('Вы не ввели Ваше имя!');
}
}
document.forms[0].name.value - это то, что введено в текстовое поле. document - это текущий документ, forms[0] - первая форма на нашей страницы (отсчет с нуля), name = имя поля (задается атрибутом name (<input name="name">)), а value это и есть нужное нам значение (то, что введенно в текстовое поле, к которому м ы и написали путь). Введенное в поле мы присваиваем переменной val (var значит, что дальше идет имя переменной), чтобы в дальнейшем каждый раз не писать весь путь целиком.
Следующее это оператор if(если). Он выглядит следующим образом:
if (условие)
{
Что делать если условие верно.
}
Мы сравниваем содержание переменной val с пустой строкой ('') и с начальной строкой ('Введите Ваше имя'). Обратите внимание, что сравнение не как в математике(с одним =), а сравниваются двума ==. || - или. Функция alert выводит окно с ошибкой (то, что в скобках - это текст ошибки). Тоесть:
Если (поле == '' или поле == 'Введите Ваше имя')
то
вывести('Текст ошибки');
окончание
И на всякий случай приведу целиком строку с кодом поля input:
<input name="name" type="text" value="Введите Ваше имя" onfocus="this.select();" onblur="check();" />
д) onreset и onsubmit
Допустим, что пользователь заполнил форму неправильно, и он хочет очистить все поля формы одновременно: для этого он воспользуется стандартной кнопкой reset. Но что если пользователь щелкнет на ней по случайности (рука дрогнет, или в суете спутает с кнопкой submit), а форма была огромная, и он долго мучился ее заполнять..., ему будет грустно, и еще он будет долго материться. Поэтому хорошо бы у него дополнительно спросить: действительно ли он хочет очистить форму.
Вообще событие reset обрабатывается до очистки формы. А чтобы отменить очистку вообще, нам просто напросто надо вернуть обработчику события значение false, то есть прописать в соответствующем атрибуте: "return false;", а чтобы продолжить очистку: "return true;". А теперь вспомним функцию, которая выдает вопрос пользователю на подтверждение чего-либо, эта функция: "confirm('Вопрос?');". При нажатии "Ok", эта функция заменяется на true, а при нажатии "Cancel" на false. То есть все что от нас требуется, это прописать в теге <form> атрибут: onreset="return confirm('Вы действительно хотите сбросить форму?');". Тогда при нажатии "Ok" там на самом деле будет "return true;", и форма будет очищена, а если "Cancel", то "return false;" и очистка формы будет отменена.
Подобным образом действует событие submit, которое возникает при попытке отправить форму. Поскольку в нашем случае форму отправлять никуда не надо, то у меня просто написано: onsubmit="return false;". И сколько бы Вы не щелкали ничего не изменится (разве что Вы JavaScript отключите).
Обычно же обработчик onsubmit используется для верификации формы (то есть проверки на заполнение всех необходимых полей, правильность их заполнения, скажем, проверка по определенному шаблону и т. п.), для этого создается функция, которая выполняет все действия. Функция должна содержать операторы "return true" и "return false", которые позволяют, заменить функцию на true или false, соответственно, в зависимости от результатов проверки (если успешно, то true, если нет false). Но верификация данных это обширная тема, которая не может быть рассмотрена здесь. Один из примеров базовой верификации я привел, когда объяснял событие blur - подобную функцию можно использовать и здесь. Тогда <form> будет содержать атрибут: onsubmit="return function();".
<form action="page.cgi" onreset="return confirm('Вы действительно хотите сбросить форму?');" onsubmit="return false;">
е) onmousedown и onmouseup
Еще одна пара событий не нашла достойного места на странице, но я ее реализовал в виде кнопки "Button". Причем это не обычная html-кнопка, она реализована в виде двух картинок. Исходная кнопка хранится в файле с именем npressed.jpg, а нажатая - pressed.jpg. Чтобы достичь эффекта нажатия кнопки нам необходимо, чтобы при при щелчке на ней(this) значение атрибута src (путь к картинке) тега <img> менялось на pressed.jpg, а при отпускании обратно на npressed.jpg. Нажатие кнопки обрабатывает onmousedown, а отпускание - onmouseup, то есть здесь все просто:
<img src="npressed.jpg" onmousedown="this.src='pressed.jpg'" onmouseup="this.src='npressed.jpg'" />
ж) onload, onunload и onabort
Обработчик события onload активируется, когда начинает загружаться графическая часть страницы (все тексты, графика и т.п.). onload является атрибутом тега <body>. Если честно я не вижу сколько бы реального применения этому событию, зато я нашел, что можно сделать с onunload. onunload это тоже атрибут тега <body>. Событие unload происходит когда мы пытаемся покинуть данную страницу (переходим по ссылке на другую, закрываем окно браузера, обновляем страницу и т. д.). Откройте еще раз окошко справки. Допустим, что пользователь прочитал справку, и хочет отправить форму, или уйдет с нашего сайта, но при этом он забыл закрыть это маленькое окошко с подсказкой, мы на выходе закроем его сами. А для этого тег <body> (у начального документа) у нас будет выглядеть следующим образом:
<body onunload="helpWindow.close()">
Вы должны бы помнить, что helpWindow это имя нашего окна (ведь именно этой переменной мы присваивали его открытие: helpWindow = window.open("help.html", "", "toolbar=0,width=300,height=200")), а метод close() закрывает это окно. Некоторые нехорошие люди используют это событие, чтобы когда посетители уходили с его страницы, появлялись какие-либо окна, так называемые pop-up.
onabort - атрибут тега <img>. Когда пользователь отменяет загрузку изображения происходит событие abort. Но отмена загрузки изображения может не входить в наши плане. И в качестве предупреждения у нас может быть написано нечто похожее на
<img src="myimage.jpg" onabort="alert('Изображение до конца не загружено! Это может привести к ошибкам.');" />>
3. Событийная процедура. Назначение и структура.
4. Особенности переменных JS.
Переменные в javascript слабо типизированы. Это означает, что при объявлении не нужно указывать тип. Можно присвоить любой переменной любое значение.
Однако при этом интерпретатор javascript (браузер) всегда знает, какого типа значение содержит данная переменная, а значит - какие операции к ней применимы.
Переменную не обязательно объявлять. Достаточно ее просто присвоить:
x = 5
5. Программирование вычислений на JS.
При использовании в операторах математических функций для их вызова следует использовать встроенный объект интерпретатора Math. В общем виде обращение к функции имеет вид: Math.f(d);
f — название функции;
s — аргумент;
Основные функции:
Функция, константа Назначение
abs(x) Модуль
sin(x) Синус
cos(x) Косинус
exp(x) E^x
max(x1,x2) Определения максимума из двух чисел
min(x1,x2) Определение минимума из двух чисел.
pow(x,y) xy
sqrt(x) Корень квадратный
ceil(x) Округление «вверх»
floor(x) Округление «вниз»
round(x) Округление до ближайшего целого
random() Случайное от 0 до 1
6. Управление процессом вычислений на JS.
<form>
<input type=”Button” value=”GO”
onClick=”functionName(param);” >
</form>
Где:
form — тег для создания формы (контейнера) командной
кнопки;
input — тег для создание командной кнопки;
type — параметр, определеет тип элемента диалого как
кнопка;
value — параметр хранит подпись для кнопки;
functionName — имя функции для обработчика события;
param — список фактических параметров обрабочика.
7. Программирование логических условий на JS.
if (isNaN(x)||isNaN(y)||isNaN(z)) {
alert("Error !")
return
}
if (isNaN(x)&&isNaN(y)&&isNaN(z)) {
alert("Error !")
return
}
8. Системные средства вывода-ввода JS.
Код скрипта выполнятся интерпретатором браузера. Для использования системных средств ввода — вывода браузера служат операторы:
Вводит системного окна с текстом: alert(“Текст”);
Для создания сообщения можно использовать операция конкатенции строк +, переход на следующую строку требует включения в текст ESC кода \n. При конкатенции числа автоматически преобразуются к строковому типу.
Вывод окна для диалога с пользователем: confirm(“Текст”).
Если нажата кнопка ОК, то возвращается значение true (истинна), иначе false (ложь) .
Запрос строки текста:
prompt(“подпись к текстовому полю”,”значение по умолчанию”) Возвращает введенную строку.
1.4. Основные операторы
Ветвление:
if (expr) {
//statements
}
else {
//statements
}
Цикл с заданным числом шагов:
for (n1,n2,n3) {
//statements
}
Цикл с пред условием:
wile(expr){
//statements
}
Цикл с пост условием:
do
//statements
while (expr)
expr — логическое выражение.
statements — операторы.
n1 — начальное значение счетчика цикла, n2 — условие выхода из цикла , n3 — выражения для приращения счетчика цикла
9. Особенности обработки символьных данных на JS.
10. Обработка календарных дат на JS.
11. Создание и использование объекта программиста.
JavaScript. Основы работы с объектами браузера
1. Тег для создания формы.
Пример структуры обработчика для командной кнопки.
<form>
<input type=”Button” value=”GO”
onClick=”functionName(param);” >
</form>
Где:
form — тег для создания формы (контейнера) командной
кнопки;
input — тег для создание командной кнопки;
type — параметр, определеет тип элемента диалого как
кнопка;
value — параметр хранит подпись для кнопки;
functionName — имя функции для обработчика события;
param — список фактических параметров обрабочика.
Примеры скриптов.
2.
3.
4.
5. Объект window. Основные методы и свойства.
Объект представляет собой главное окно браузера. Для доступа в строку состояния браузера используется свойство status. Объект обладает набором методов:
Метод Назначение
open(“url”) Открытие документа в новом окне браузера.
open(“url”,”WindowName”,
[features]) Открытие документа в окне заданного вида.
navigate(“url”) Замена документа на новый.
close Закрытие окна браузера.
setTimeout(“ProcName”,t) Запуск процедуры через t миллисекунд, метод возвращает дескриптор процесса id.
clearTimeout(id) Уничтожение деcкриптора периодического процесса и завершение его обработки.
Условные обозначения:
url – адрес ресурса. Локальный ресурс задается в виде:
file:///d|/path/file
WindowName — условное имя окна для тегов HTML.
features – строка параметров окна. Параметр задается в виде p=значение. Значение 1 или 0 (yes | no).
Допустимые параметры:
Параметр Назначение
toolbar Панель инструментов браузера
location Строка ввода url
status Наличие строки состояния
menubar Строка меню
scrollbars Полосы прокрутки
resizable Возможность изменения размеров окна
width Ширина окна в пикселах
height Высота окна в пикселах
id – Дескриптор периодического процесса, возвращается методом setTimeout.
idTimer=setTimeout(“funName()”,t)
clearTimeout(idTimer)
confirm(“text”)
open(“url”)
navigate(“url”)
close()
status
Примеры работы с окном браузера:
Пример№1. Работа со строкой состояния и выход из браузера.
function show(){
window.status="Hello World"
if (window.confirm("Exit ?"))
window.close()
}
Пример №2. Вывод системного времени
function show(){
now = new Date()
h=now.getHours()
m=now.getMinutes()
s=now.getSeconds()
alert("UT -> "+now.toString()+"\nGMT-"+now.toGMTString())
window.status=h+":"+m+":"+s
}
Пример №3. Часы в строке состояния браузера.
var idTime
idTime=window.setTimeout("show()",1000)
function show(){
now = new Date()
h=now.getHours()
m=now.getMinutes()
s=now.getSeconds()
window.status=h+":"+m+":"+s
idTime=window.setTimeout("show()",1000)
}
//Функция для остановки часов
function stop(){
window.clearTimeout(idTime)
}
Пример №4. Создание нового окна браузера
function show(){
"+
" toolbar=0 resizable=1 width=300 height=200")
6.7. Объект document. Основные методы и свойства.
Объект используется для работы с текстом HTML страницы.
Методы объекта:
Метод Назначение Свойство Назначение
open() Открыть буфер редактирования. fgColor Цвет символов.
write(“cтрока”) Запись в буфер редактирования bgColor Цвет фона.
clear() Очистка буфера документа. images[idx] Коллекция изображений на странице.
close() Закрытие буфера и вывод его содержимого.
Изображения на странице представляют собой коллекцию. Каждый элемент коллекции имеет индекс idx. Индексируется коллекция с нуля. Основным свойствами элемента коллекции являются src — в нем хранится адрес графического файла с изображением, alt — хранит подпись для изображения, width и height — размеры графического изображения в пикселах.
В случае деления страницы на фреймы для доступа к странице используется обращение следующего вида:
top.fraName.document.
top — указатель на главное окно браузера
fraName — имя фрейма
Примеры кода для работы с объектом документ
Пример №1. Новое содержание и цвет и цвет страницы
function change(){
document.fgColor="lime"
document.bgColor="blue"
alert("OK !")
document.open()
document.write("<b>Hello World !</b><p>")
document.write("<i>Passed !</i>")
document.close()
document.fgColor="white"
document.bgColor="black" }
Пример №2. Вывод текста во фрейм.
Страница с делением на фреймы.
<html>
<frameset cols="50%,*" >
<frame src="document2.html" name="fraOne" >
<frame src="blank.html" name="fraTwo" >
</frameset>
</html>
//функция вывода
function change(){
top.fraTwo.document.open()
top.fraTwo.document.write("<b>Hello World !</b><p>");
top.fraTwo.document.write("<i>Passed !</i>");
top.fraTwo.document.close()
}
Пример №3. Замена первого графического изображения на новое.
function show(){
var imgURL="00fract.gif"
document.images[0].src=imgURL
document.images[0].alt=imgURL
}
Пример №4. Смена изображений. Кеш.
Кеш используется для ускорения вывода изображений. Технология кеширования — буферизация изображения. Для создания буфера нужно получить экземпляр системного объект Image:
var imgBuf=new Image(w,h);
w — ширина изображения;
h — высота изображения;
Размеры задаются в пикселах.
Программный код:
var imgURL1="00fract.gif"
var imgURL2="01fract.gif"
objImg1=new Image(100,50)
objImg1.src=imgURL1
objImg2=new Image(100,50)
objImg2.src=imgURL2
function change(job){
if (job==2)
document.images[0].src=objImg2.src
else
document.images[0].src=objImg1.src
}
</script>
</head>
<body>
<img src="00fract.gif" alt="Смена изображений"
onMouseover="change(2)"
onMouseout="change(1)">
</body>
</html>
8. Объект navigator. Получение характеристик браузера
Объект используется для получения информации о браузере. Обладает набором свойств:
Свойство Назначение
appName Название браузера
appCodeName Кодовое имя браузера
appVersion Версия браузера
platform Тип ОС
userAgent Идентификация браузера как клиента.
9. Объект location. Работа с URL адресом страницы
Объект используется для работы с URL адресом страницы. Свойства объекта:
Свойство Назначение
protocol Протокол прикладного уровня.
hostname Имя хоста.
pathname Путь к документу.
href Весь адрес.
Свойство href может использоваться для перехода на новую страницу в текущем окне браузера. Для этого следует записать в него URL адрес новой страницы.
Объектная модель документа
1. DOM. Понятие узла.
4. DHTML. Свойства innerText, innerHTML узлов
Хотя консорциум W3C никогда официально не определял свойство innerHTML как
составную часть модели DOM, тем не менее это свойство узлов HTMLElement явля_
ется настолько важным, что поддерживается всеми современными броузерами.
При чтении из этого свойства вы в формате HTML получаете текст, который
представляет дочерние узлы элемента. При записи в это свойство броузер запус_
кает синтаксический анализатор HTML_кода для разбора строки и замещает до_
черние элементы теми, которые были получены от анализатора.
Описывать HTML_документ в виде строки с текстом в формате HTML обычно
удобнее и проще, чем использовать для этих же целей последовательность вызо_
вов createElement() и appendChild(). Снова вернемся к той части примера 15.9, где
создается новый элемент <table> и затем к нему добавляется строка заголовка.
Благодаря свойству innerHTML этот относительно крупный фрагмент программно_
го кода можно переписать следующим образом:
var table = document.createElement("table"); // Создать элемент <table>
table.border = 1; // Установить атрибут
// Добавить в таблицу заголовок Имя|Тип|Значение
table.innerHTML = Веб_броузеры по определению прекрасно справляются с анализом HTML_кода.
Оказывается, что использование свойства innerHTML гораздо эффективнее, осо_
бенно при анализе больших фрагментов HTML_текста. Однако следует отметить,
что операция добавления небольших фрагментов текста в свойство innerHTML
с помощью оператора += обычно не отличается эффективностью, поскольку тре_
бует как сериализации, так и синтаксического анализа.
Свойство innerHML было введено компанией Microsoft в IE 4. Оно входит в квартет
наиболее важных и часто используемых свойств.
Свидетельство о публикации №210033101371
