dfns
9/27/2015 - 8:50 AM

#js #webformyself

#js #webformyself

/* функции */
/* функции вывода */
alert();
document.write("hello");

typeof
isNaN(myVar);
isFinite(myVar);
//
// массивы
length;
for in
reverse();
join();
sort();
concat();
slice();
splice();
push();
pop();
unshift();
shift();
оператор delete 
инструкция in
Array.isArray();
//
// функции
function max() {
  var arr = arguments;
}
//
//
// Объекты
var obj = {}
delete obj.prop;  // удаление свойства. Только у данного объекта, в свойства прототипа он не лезет.
var obj2 = Object.create(obj1);  // создать прототип для obj2
obj.hasOwnProperty('prop');   // проверить есть  ли свойство в объекте. true or false.Вернет false, если свойство наследуется
console.log('prop1' in obj);  // --|-- Вернет true, если свойсто есть, независимо наследуется или нет.
//
//
// window
setTimeout('func()', 1000);
setInterval('fucn()', 1000);
w = window.open('http://ya.ru', 'mywindow', 'width=100,height=100,menubar=1,toolbar=1,resizable=0,scrollbars=0');
w.close();
w.focus();  // Присвоить фокус на новое окно.
window.opener;    // свойство вернет 0, если это окно "родительское". И верент ссылку на окно если его открыли.
w.blur();
w.print();
w.scrollTo(150,150);
w.scrollBy(150,150);
w.moveTo(150,150);
w.moveBy(150,150);
w.resizeTo(150,150);
w.resizeBy(150,150);
//
//
// Работа с фреймами.
<iframe name="first" src="frame1.html"></iframe>
window.frames     
frames.length;    
frames[0]
alert(frames.first.test_frame);    // переменная test_frame объеявлена на странице фрейма(в скрипте)
// из фрейма можно получить доступ к переменным родительского окна с помощью parent(родитель) либо top(самое первое окно)
alert(parent.var_name);
alert(top.var_name);
//
//
// window.navigator
navigator.userAgent;
navigator.platform;
//
// window.screen
screen.width;
screen.height;
//
// window.location
location.hash;
location.host;
location.hostname;
location.href;
location.pathname;
location.protocol;
location.search;
location.assign('http://wwww.ya.ru');
window.location = 'http://wwww.ya.ru';
location.replace('http://wwww.ya.ru');
location.reload();
location.toString;
//
// window.history
history.length;
history.back();
history.forward();
history.go(-2);
history.pushState();
//
//
// DOM
// выборка элементов
document.getElementById();
document.getElementsByClassName();
document.getElementsByTagName();
document.getElementsByName();
document.querySelector();
document.querySelectorAll();
//
// поиск структурно-связанных узлов
block.parentNode;
block.childNodes; 
block.children.length;
block.nextSibling;
block.previousElementSibling;
block.firstChild;
block.lastElementChild;
block.childElementCount;
//
// создание элементов
document.createElement('div');
document.createTextNode('text');
var frag = document.createDocumentFragment();
// вставка элементов
block.appendChild(elem);
block.insertBefore(elem, child_name);
block.insertAdjacentHTML('beforebegin', new_elem);
// удаление элементов
block.removeChild(block.firstElementChild);
// замена элементов
block.replaceChild(new_elem, old_elem);
// работа с аттрибутами
block.getAttribute('class');
block.setAttribute('src', 'img.jpg');
block.removeAttribute('href');
block.hasAttribute('name');
// работа с Node
block.nodeValue;
block.nodeType;
block.nodeName;
// работа с формами
document.forms.my_name.my_input.type;
document.forms.elements[0].value;
my_form.my_radio[0];
// innerHTML
var my_html = block.innerHTML;
block.innerHTML = '<h2>Test</h2>';
// взаимодействие с css
elem.style.fontSize = '24px';
//
//
// События
// window
window.onload
window.onbeforeunload
window.onfocus
window.onblur
window.onresize
window.onscroll
// mouse
onclick = function(e) {
  e.altKey, e.shiftKey, e.ctrlKey
  e.clientX, e.clientY
  e.button
}
onmousemove
onmousedown
onmouseup
onmouseover
onmouseout
onmousewheel
// keyboard
obj.onpresskey = function(e) {
  e.keyCode
}
onkeydown
onkeyup
// forms
obj.onchange
obj.oninput
obj.onfocus
obj.onblur
obj.onsubmit
obj.onreset
// метод addEventListener регистрирует обработчики событий
addEventListener('click', myFunc, false);





/* Внедрение JS в HTML. Синтаксис */
1. <script type="text/javascript"> code... </script>
Если JS встроен в <head> то сначала отрабатывает скрипт, потом загружается html. Если скрипт встроен в <body>,
то отработает html расположеный выше скрипта.
2. внешний файл
3. встраивание кода js через обработчики событий
/*При клике по тексту заголовка отработает код, описанный внутри onclick="" */
<h1 onclick="alert('Вы кликнули мышью')">Заголовок</h1>  
4. Передача кода скрипта в url. Надо использовать псевдопротокол js. Этот специльный тип протокола означает, что
тело url адреса представляет собой js код.
<a href="JavaScript:alert('Hello')">ссылка</a>

-завершить работу функции return;



/* Переменные и типы данных */
Переменная - определенный именованный участок в памяти. 
/* зарезервированные слова. Не называть переменные. */
try var void with debugger default catch break do
Для удобства сначала переменные объявляют, потом присваивают значения.

/* NULL TYPE */
хранит в себе одно значение null(не строка, именно значение). Это отсутствие значения, пустота. Если переменной присваиваем 
null, переменная пустая, но она определена. Зачем нужно такое значение? Если в функцию не пришел определенный набор
значений, то значит расчет не возможжен. И как результат работы функции можно вернуть null. Потом проверяем есть
ли значение в результате функции.

typeof(name); функция возвращает тип данных.

/* UNDEFINED TYPE */
Неопределенный тип данных. Содержит в себе только одно значение undefined. Говорит о том что значение переменной
вообще отсутствует. Можем получить undefined когда обратимся к только что определенной переменной, которой
еще не присвоили значение. Обычно значение null мы присваиваем сами в каких-то своих целях, а undefined 
получаем в результате неправильных действий, ошибочных выводов на экран и т.д. Также undefined возвращается
функциями, которые не имеют возвращаемого значения.

/* NUMBER TYPE */
В js нет целых и действительных, все вещественные.
Числовой тип данных. Можем записывать числа как в 10-ричной форме, так и в 16-ричной и 8-ю. Мы можем задавать
значения, используюя 16-ю, 8-ю сист.исч., но js при отображении на экран переведет в 10-е значение.
Функция Number(var) приводит к числовому типу данных.

% - оператор отсаток от деления
var a=7, b=3, c;
c = a % b; /* 1 */

-деление на 0 вернет infinity(бесконечность), не ошибку.
- 0/0, infinity/infinity, корень квадратный из отрицательного числа вернет NaN(not a number не число). Т.е. те операции
которые провести невозможно.
Функция isNaN проверяет что содержится в переменной "не число" или нет. Если NaN вернет true;
Функция isFinite(myVar) возвращает истину, если переменная является числом отличным от NaN, и отличным от infinity и -infinity.

/* STRING TYPE */
Строка - упорядоченная последовательность значений. Строка - неизменный тип данных.
-Если мы хотим вывести в строке двойную кавычку - используем обратный слэш \. Экранирование кавычек.
Если ставим \, то следующий за ним символ уже не воспринимается интерпритатором js как управляющая конструкция.
Ковычка становиться частью обычного текста.
var str = "стро\"ка";
-перенос строки \n. var str = "стро\nка"
-табуляция \t.
-конкатенация str1 + " " + str2
Строки являются последовательностями 16-и битных челочисленных значений и сравнение строк сводится к числовому сравнению
этих же значений.
var str1 = "new";
var str2 = "new 2"; // str1 меньше str2
if(str1 > str2) {
  document.write("str1 больше str2");
}
else {
  document.write("str1 меньше str2");
}
Такое сравнение строк дает порой неожиданные результаты, поэтому  для сравнения строк используется другой метод.

/* метод write. выведет строку на экран. Если скрипт прописан в head, то данные выводятся сразу после открывающего
тега <body>, т.е. в начале */
document.write("hello");

/* BOOLEAN TYPE */
функцияя Boolean(var) приводит переменную к логическому типу данных.

var test = '10' + '20'; /* вывод 1020 - строка */
var test = '10' * '20'; /* 200 число. Выполниться неявное преобразование типов */ 
var test = 10 * '20';  /* 200 число */
var test = 'str' * "str2"; /* NaN */
var x = 10;  var test = x + ''; /* приведение к строке */
var x = '10';  var test = +x;   /* придение к числу */
-x тоже приводит к числу, но меняет при этом знак на противоположный.
0.2 можно записать как .2




/* Условные операторы, сравнения, switch */
== равенство (не берет во внимание типы данныхоперандов) '10' == 10 /* true */
=== оператор идентичности
!= без учета типа данных
!== сравнивается с учетом типа даннх
{} блок кода в фигурных скобках еще называют составным оператором
else if() {}  /* раздельно */

/*  switch сравнивает и ищет совпадения по оператору идентичности, т.е. сравнивает типы данных.
оператор switch используется только для чисел и строк */
switch(test) {
  case null:
    alert("null");
  break;
  case "string":
    alert("string");
  break;
  
  default:
    alert("default");
} 

// как сделать так, чтобы определенный участок кода будет выполняться на каких-то одинаковых равных условиях.
// т.е. alert("null") будем выводить, если test = null и test = ''.
// Если нужно проверить несколько идентичных условий, но при этом код выполняется один.
case(null):
case(''):
  alert("null");
  break;

// ДЗ
alert(0.1 + 0.2);   // 0.30000000004
// появляется погрешность 
// все числа в js храняться в формате float 64, т.е. все числа представлены как вещественные и для их вывода
// используется 64-х битный формат данных, т.е. это 8 байт с плавающей точкой    



// 5. Циклы
// условие выхода из цикла - это то, что условие цикла в какой-то момент должно вернуть false.
// вложенные циклы удобно использовать для создания таблиц. Во вложенном цикле переменная счетчика цикла 
// должна иметь другое название.
//цикл while
while(i < 10) {
  document.write(i + '<br/>') ;
  i++;
}
// цикл  do while
do {
  if(i == 5) {
    i++;
    continue;
  }
  document.write(i + '<br/>');
}
// инструкция continue - переход на следующую итерацию цикла
// инструкция break завершает выполнение цикла
// цикл for
for(инициализация; проверка(условие выхода из цикла); обновление) {
  // код цикла 
}
for(var i = 0; i < 5; i++) {
  document.write(i + '<br/>');
}


// 6. Методы ввода-вывдоа.
// данные методы являются методами глобального клиенского объекта js - объекта window.
1. alert("test");  // выводит модальное окно и ожидает пока пользователь его закроет
2. var result = confirm("Подтвердите свой выбор");      // предлагает кнопки ok и cancel, и возвращает логическое значение
3. prompt("Введите ваше имя");       // выводит сообщение на экран и ждет ввода произвольной строки от пользователя 
// и возвращает данную строку.
// можно передавать второй параметр и он будет выведен как подсказка в поле ввода.
prompt("Ваше имя", "латинскими буквами");
// Данные методы применяются довольно редко, т.к. модальное окно никак не форматируется. Используется для отладки
// и сервисных сообщений.
//
//
// пример. В переменную login сохраним значение отработки метода prompt. Т.е. предложим пользователю ввести логин.
do {
  var login = prompt("Ваш логин");
  // спросим правильно ли пользователь ввел логин
  var correct = confirm("Ваш логин:" + login + " \nПоддтвердите введенные данные.")
}
// условие выхода из цикла - когда пользователь подтвердит свой логин и в переменной correct будет лежать true
while (correct == false); /* или */ while(!correct)
alert("Ваш логин " + login);
//
// метод также выводит модальное окно, но его содержание мы можем выбирать по своему усмотрению.
// первым параметром принимает путь той страницы, которая  откроется в новом модальном окне
// второй параметр это текст, который будет отбражаться на странице
// третий это параметры самого модального окна - ширина и высота
showModalDialog("http://localhost/form.html",
                "",
                "dialogheight : 200px , dialogwidth : 300px");
// содержание страницы
// доступ к введенному тексту мы сможем получить в скрипте
<form>
  Введите текст <br/>
  <input type="text"/><br/>
  Введите текст <br/>
  <input type="text"/><br/>
  Введите текст <br/>
  <input type="text"/><br/>
  <input type="submit"/>
  <input type="reset" onClick="window.close()"/>    // метод close() объекта window - закрытие текущего окна.
</form>
//
// 
// метод eval позволяет разбирать строковые выражения
eval("2+3");    // вернет 5
eval("alert(2+3)");   // выведет окно 50. т.е. обработался и alert и выражение внутри него.
// ключевой особенностью данного метода является то, что данный метод использует окружение того програмного кода,
// который и вызывает данный метод. Т.е. метод eval будет выполнять поиск значений переменных и определять
// новые переменные функций. Этот метод сильно ухудшает читаемость кода, просто знать, если встретить в чужем коде.
//
//
// инструкция void. Указывается перед своим единственным операндом любого типа.
void 2;
alert(void 2);  // вернет undefined потому что void вычисляет значение своего операнда, затем отбрасывает это значение
                // и возвращает undefined.
// Применяется в адресах url.
// При переходе по ссылке откроется новое пустое окно, а текущее окно полностью потеряет свой контент (надпись
// [object Window]. Потому что конструкция window.open вернула нам некий объект и js сообщает, что вернулся
// определенный объект, но нам нужно было просто открыть новое окно, поэтому это возвращаемое значение
// нам нужно было бы отбросить, для этого используется void
<a href="JavaScript: void window.open()">Ссылка</a> 



// 7. Массивы
// Массив - упорядоченный набор значений. 
// массив может содержать пустые ячейки, в них храниться значение undefined. Такие массивы называются разряженными.
var arr = [5,7,,9 ];
var arr2 = [,,];  // этот массив не имеет элементов, но его длина равна 2. Последняя запятая необязательна и
                  // не учитывается, т.е. [5,7,9,];
var arr3 = new Array();   // используя такую запись мы вызываем метод конструктора объекта Array.
//
document.write(arr);    // на экране увидим массив в виде строки. Потому что массивы ведут себя как объекты и 
                        // практически у каждого объекта есть метод toString. Данный метод автоматически отрабатывает, 
                        // когда мы пытаемся вывести на экран какое-то значение. toString преобразовывает массив
                        // в строку через запятые.
//
arr.length; // свойство длина массива
//
// можно ограничить длину массива. Если длина меньше, то лишняя часть будет отброшена. Если задается длина
// большая, то будут созданы пустые ячейки.
var arr = [2,3,4,5,6,7,7,7];
arr.length = 4;
alert(arr);   // 2,3,4,5
//
var arr = [1,3,5];
arr[100] = 0;
document.write(arr.length);   // 101
//
arr["20"] = 0;    // js ожидает числовой тип данных, если сможет успешно перевести, то создаст ячейку под номером 20.
//
//
// цикл for in применяется для обхода либо объектов либо массивов
for(/*переменная для индексов*/  in  /*массив для прохода*/) {
  // код цикла
}
//
// объявляем пустую переменную index и в нее на каждой итерации цикла будет поподать индекс массива array. 
for(var index in array) {
  alert(array[index]);
}
//
//
// многомерный массив
// js не поддерживает многомерные массивы. ????
var arr = [1,2,3,["hello", "world"]];
alert(arr[3][1]); // world
//
//
// методы массивов
var arr = ["мандарин", "апельсин", "груша", "банан"];
join();   // преобразует элементы массива в строку
// если мы передадим методу join параметр, то он будет использоваться как разделитель вместо дефолтной запятой
arr.join(" |---| ");
//
reverse();    // возвращает массив в обратном порядке. Данный метод не создает новый массив, он выполняет изменения
              // существующего массива.
//
sort();   // сортирует элементы в исходном массиве. Сортирует массив так, как будто элементы массива это строки.
          // В алфавитном порядке.
          // сортировка цифр 1,100,11,111,2,200,22,222,3,4,5
// чтобы отсортировать массив как обычные числа методу sort нужно передать функцию, которая будет описывать 
// правила сортировки. В методе sort именовать функцию не нужно - мы используем анонимную функцию.
// передадим функции 2 параметра. a и b это какбы ячейки массива. Правила сортировки описываем для двух
// произвольных значений. Данная функция должна возвращать 3 определенных значения. Если будет возвращено -1(любое < 0),
// значит элемент a должен следовать до элемента b. Если вернется 1 (любое число больше 0), значит первый элемент a должен
// идти после элемента b. Если вернем return 0; то порядок следования элементов a и b как бы не важен, другими словами a==b.
array.sort(function (a,b) {
  if(a < b) 
    {return -1;}
  if(a > b)
    {return 1;}
  return 0;
});
//
//
// метод concat() позволяет создавать и возвращать новый массив, который содержит элементы исходного массива и те элементы,
// которые переданы параметром методу concat(). Данный метод используется редко, т.к. массивы можно создать напрямую
// обращаясь к его элементами.
var arr = ["a", "b", "c"];
// мы хотим создать новый массив. 
var a = arr.concat("d", "e", "f");
document.write(a);    // a,b,c,d,e,f
//
//
// метод slice возвращает подмассив, либо фрагмент исходного массива. Принимает 2 параметра - начало и конец того
// подмассива, который мы хотим получить. slice не изменяет исходный массив.
var arr = ["a", "b", "c","d", "e", "f"];
// чтобы получить элементы "c" и "d". Указываем начальный индекс 2. А конечный указваем на 1 больше, т.е.
// он не будет включен в подмассив.
arr.slice(2,4);   // "c","d"
// если указать 1 параметр, то получим подмассив от этого индекса до конца массива.
arr.slice(2);   // "c","d", "e", "f"
// отрицательный параметр вернет элементы с конца массива. Причем -1 это индекс последней ячейки (не 0).
arr.slice(-2);    // "e", "f"
//
//
// метод splice позволяет выполнять вставку и удаление неких элементов из массива. Данный метод изменяет исходный массив.
// первый аргумент метода splice показывает позицию в массиве, начиная с которой будет выполняться вставка или
// удаление данных. Второй параметр показывает количество элементов, которые необходимо вырезать.
var arr = ["a", "b", "c","d", "e", "f"];
arr.splice(2,2);    // a,b,e,f
// если второй параметр не задать, то удаляться все элементы из данного массива до конца строки.  
arr.splice(2);    // a,b
// метод splice возвращает вырезаные элементы, т.е.
alert(arr.splice(2,3));   // c,d,e
// после второго параметра можно элементы, которые будут добавлены в исходный массив начиная с позиции, указанной 
// в исходном элементе.
arr.splice(2,3,"hello","world");
// чтобы не удалять никаких данных, вторым параметром передадим 0
arr.splice(2,0,12,15);
//
//
// методы для работы с последней ячейкой массива. Эти методы изменяют исходный массив.
push();   // добавляет элементы в конец массива и возвращает длину измененного массива.
var arr = [1,2];
arr.push(3);    // 1,2,3
//
pop();    // удаляет и возвращает последнюю ячейку массива. 
//
//
// методы для работы с началом массива. Изменяют исходный массив.
var arr = [1,2];
// unshift() добавит новый элемент в начало массива. Возвращает длину нового массива.
arr.unshift(0);   // 0,1,2
// shift() удаляет первый элемент массива. Возвращает удаленный элемент.
var arr = [1,2];
arr.shift();    // вернет 1. arr = [2].
//
//
// оператор delete удаляет ячейку массива. Значение будет удалено, но ячейка останестся со значением undefined.
delete arr[1];
// эта запись равносильна
arr[1] = undefined;
// т.е. в отдичие от метода shift, инструкция delete не изменяет длину исходного массива.
//
//
// инструкция in применяется чтобы проверить существует ли какое-то свойство в объекте, либо элемент в массиве
// существует ли в массиве arr эдемент с индексом 1
if(1 in arr) {
  alert(arr[1]);
}
else {
  alert("not");
}
//
//
// Как проверить что в переменной содержиться массив. Параметром передается переменная, которую мы проверяем.
Array.isArray(arr);
//
// создать двумерный массив, в котором содержиться таблица умножения. Чтобы вывести умножение пар чисел необходимо
// arr[5][5] в певрой ячейке 1 множитель во второй яч 2 множ. Данное выраж должно вернуть 25. 




// 8. Работа со строками.
// у строки есть одно свойство length.
str.length;
// способ создания строки. Образаемся к объекту String.
var str = new String("hello world 112 world ");
//
// методы для работы со строками.
str.charAt(5);   // str[5]; Не меняет исходную строку.  Принимает индекс. Возвращает элемент строки под этим индексом.
str.concat("new string");   // Данный метод выполняет аналагичную операцию оператора +, т.е. конкатенация строк. К исходной
                            // строке добавляет новую строку
str.indexOf("world");   // производит поиск подстроки в исходной строке. Возвращает индекс с которого подстрока
                        // входит в исходную строку. Ищет индекс первого вхождения такой подстроки.
str.lastIndexOf("world");   // поиск последнего вхождения подстроки в строку
str.split(",");         // разбивает строк и возвращает массив. Разбивает по разделителю, который передаем параметром.
                    // Если не передавать разделитель в массив попадет вся строка. В виде разделителя может быть
                    // шаблон регулярного выражения.
str.replace("world", "new string")   // выполняет замену первого вхождения подстроки в исходную строку. 
               // 1 параметр = та подстрока, которую мы хотим заменить. 2 параметр - строка на которую происходит замена.
str.substr(7,5);  // возвращщает подстроку, которая начинается с индекса, переданного первым параметром. Длниа 
                  // передается 2 параметром. Не рекомендуется передавать отриательный параметр, т.к. IE может заменить его 0.
str.substring(2,5); // возвращает подстроку от 1 параметра, до позиции указанной во 2 параметре, но последний символ
                      // не включается в возвращаемую строку. Если передать отрицательное число, оно будет заменено 0.
                      // Если второй параметр меньше первого, то они меняются местами.
str.toUpperCase();
str.toLowerCase();
str.toLocaleUpperCase();  // возвращает новую строку, в которой все буквы исходной строки заменены на большие, но с учетом
str.toLocaleLowerCase();  // национальных установок операионной системы. Кодировок языка очень много и если кодировка
                        // языка как-то противречит  правилам юникода, то лучше использовать тот метод. Применяется редко.
str.slice(6,10);   // возвращает подстроку с индекса, переданного первым параметром, и до индекса переданного 2 параметром.
                  // последний символ не включается. Можно использовать отрицательный аргумент.
str1.localeCompare(b);   // стравнение строк с учетом национальных особеннойстей. -1 если str1 < str2. 0 равны. 1 str1>str2.
//
//
// методы для работы с регулярными выражениями
str.search(/[0-9]/);    // выполняет поиск в исходной строке по шаблону регулярного выражения переданного параметром. 
                    //Возвращает позицию первого найденного совпадения. Если совпадений не найдено, возвращается -1.
str.match(/[0-9]+/);  // выполняет поиск регулярного выражения в исходной строке. Возвращает массив найденныых подстрок 
                      // или 0 если совпалений нет.
//
//
// устаревшие методы
str.bold(); // оборачивает строку в тег <b>.
str.blink();  // мигающая строка
str.fixed();  // <tt>
str.fontcolor("red"); 
str.fontsize(20);
str.italics();  // <i>
str.link("http://google.com");  // <a href="google.com">
//
// вывести подальное окно и предложить пользователю ввести строку. Чтобы эта строка содержала в себе некие слова, 
// разделенные |.  Затем надо разбить строку на массив и вывести каждое слово на новой строке. Если пользователь нажмет
// отмена, надо заново отобразить это модальное окно. Нельзя передать пусую строку. ВВеденная строка обязательно
// должна содержать разделители. Если в конце строки разделитель, чтобы не полуилась лишняя пустая ячейка.
//
// вывести строку в которой символы следуют наоборот




// 9. Функции
// Т.к. js объектно-ориентированный язык, то функции в js являются объектами. 
// объявление функции через оператор function. Присваиваем функции имя. Можем  вызвать функцию на исполнение до ее объявления.
function func(a, b) {}
//
// присваиваем функцию переменной. НЕЛЬЗЯ вызвать функцию на исполнение до ее присваивания переменной. Имя функции не задаем. 
// Присваиваем имя функции только в том случае, если необходимо использовать имя функции в самой же функции.
// (рекурсивная функция).
var func = function(a, b) {...};
func(1, 2);
// такую функцию сразу можно вызвать на исполнение, передав параметры в скобках. Не использовать ухудшает читабельность кода.
// Это как бы однократная функция, т.е. дальнийшие ее вызовы в коде не будут работать.
var func = (function(a, b) {...}(10,5));
//
//
// рекурсивная функция
function getStr() {
  var str = prompt("Введите строку");
  // если пользователь закрыл модальное окно и в переменную str вернулся null - повторно вызываем функцию.
  if(!str) {
    getStr();
  }
  else {
    alert(str);
    // используется для завершения работы функции
    return;
  }
}
//
// функции, у которых нет инструкции return, возвращают значение undefined.
//
// Интерпритатор js не проверяет типы данных параметров, переданных в функции.
// в начале функций не забывать проводить проверки параметров на типы данных и т.д. Чтобы защитить
// себя от ошибочных результатов отработки функции.
function func(str) {
  document.write("<h1>" + str + "</h1>");
}
func("string");
// если функции не переданы параметры, которые она ожидает, то этим параметрам присваивается значение undefined.
// Параметры, которые мы передаем в функцию записываются в массив arguments. Мы можем не указывать в функции какие
// аргументы она ожидает. Доступ ко всем переданным параметрам можно получить через массив arguments. Мы можем
// манипулировать ячейками этого массива, дописывать в них, удалять и т.д.
function func() {
  document.write("<h1>" + arguments[0] + "</h1>");
}
func("string");
//
// Более того, мы можем создать функцию, которая будет выполнять прием любого неограниченного числа параметров.
function max() {
  var arr = arguments;    // необязательно
  for(var i = 0; i < arк.lenth; i++) {
    ...
  }
}
max(1,2,3,4,5);
//
// если в функции описаны 2 параметра, а ей переданы 3. Лишние параметры интерпритатор не учитывает, они отбрасываются.
//
// Если вы пишите отдельный модуль какого-то проекта, то чтобы не дублировать переменные обычно создают функцию,
// выполняют какой-то код и потом просто эту функцию вызывают на исполнение. И переменные которые были созданы внутри
// функции являются локальными и самом скрипте, как глобальные переменные они не будут доступны и конфликта не будет.
function block() {
  // code
}
block();
// если надо исключить даже имена функций можно создать анонимную функцию
(function() {
  // code
  // потом сразу вызывается функция на исполнение - передаются параметры в скобках
}(a,b...))
//
// 
// функции могут быть вложенными. Вложенная функция имеет полный доступ к локальным переменным функции верхнего уровня.
function myFunc(x, y) {
  alert(x + y);
  function myFunc2() {
    document.write(x - y);
    return (x- y);
  }
  return myFunc2;
}
myFunc(1, 2);
// функцию можно передавать параметром
//
// функции можно выносить в отдельный файл



// Время и дата
// В js существует объект Date(), содержащий все необходимые методы для работы с датаой и временем. Данный объект
// на момент своего вызова хранит в себе как бы текущую метку времени.
// Чтобы создать объект необходимо, с помощью ключевого слова new вызвать функцию конструктор данного объекта
var now = new Date();
document.write(now);  // отработает метод toString(), который преобрахует содержимое объекта в строку.
now.toLocaleString();  // метод toLocaleString выводит дату и время в соответствии с региональными настройками компьютера польз
now.toLocaleDateString();    // вывод даты, время отброшено
now.toLocaleTimeString();      // вывод времени
//
// объект Date() хранит время момента своего создания, т.е. время в нем не изменяется динамически.
//
// Можно не только выводить но и задавать время и дату. Например нужно сделать таймер отсчитывающий время от начала акции.
// Чтобы вывести до конца акции осталось 10 дней к примеру. Для этих целей необходимо работать с будущим временем, а не
// с текущим. Для этих целей применяются методы задающие время. 
now.setFullYear(1990);
now.setMonth(9);
now.setDate(25);
// можем изменять число месяца date, но не можем задать день недели, т.к. он расчитывается.
now.setHours(13);   // если интерпритатор видит, что мы задали большее количество часов, чем в сутках, он увеличит дату
                    // и добавит к ней.
now.setMinutes(59);
now.setMilliseconds(100);
now.setTime(100);     // прошло 100 миллисекунд с 1970г.
//
//
// Также объекту Date можно передавать параметры.
// Задача. Отобразить сколько дней осталось до нового года. 
// Необходимо создать объект Date с датой нового года.
var newYear = new Date(2016,0,1);
// текущее время
var now = new Date(); 
// можно использовать метод getTime(), либо обычное вычитание.
var number_days = newYear - now;  // разность в количествах миллисекунд.
// Т.к. дата установлена в миллисекундах, переведем в начале в секунды - поделим на 1000. Переведем в минуты - поделим на 60.
// В часы - еще на 60. В дни - на 24.
// Отбросим остаток с помощью parseInt
alert(parseInt(number_days / (1000 * 60 * 60 * 24)));
//
//
// Метод parse() - статический метод объекта Date(), вызывается непосредственно у объекта Date(). Принимает один 
// строковый параметр, саму дату в виде строки, анализирует ее и возвращает количество миллисекунд с 1970.
Date.parse();

// вывести количество дней и часо до 1 сентября 2016.
// создать часы в браузере(рекурсия, setTimeout. document.write не подойдет.)



// 11. Математические операции объект Math. Объект Number.
// Объект Math содержит константы и методы для выполнения математических операций. Объект Math не имеет конструктора.
// Т.е. мы не можем создать новый объект с помощью ключевого слова new Math(). Получить доступ к методам можно с
// помощью оператора точка Math.
var test = -10;
Math.abs(test);   // число по модулю 10
Math.round(x);      // округлить число до ближайшего целого в соответсвии с математическими правилами.
Math.ceil(x);     // округлить число вверх в независимости от того какая десятичная часть. 45.1 -> 46. 
Math.floor(x);    // округляет число до ближайшего меньшег
Math.max(10,23,45,-1);    // вычисляет максимально число из переданных
Math.min(1,2,3);          // вычисляет минимальное число из переданных
Math.pow(x,y);            // вычисляет степень числа. 1 параметр - число. 2 пар - степень.
Math.sqrt(x);             // квадратый корень
Math.random();            // возвращает случайно сгенерированное число от 0 до 1



Math.acos(-1);    // арккосинус. Принимает от -1 до 1
Math.asin(1);     // арксинус. от -1 до 1
Math.atan();      // арктангенс
Math.atan2(y, x); // арктангенс параметров y и x. Это координаты.
Math.cos(x);      // косинус. x - значение угла в радианах. Чтобы перевести градусы в радианы - умножить на 0.17.
Math.PI;          // число Пи константа
Math.E;           // константа екпонента
Math.exp(x);      // вычисляет экспоненту принимает степень
Math.LN10;        // константа натуральный логорифм числа 10.
Math.LN2;         // константа натуральный логорифм числа 2.
Math.log(x);      // вычисляет натуральный логорифм любого числа больше 0.
Math.LOG10E;      // логориф по основанию 10 константы е
Math.sin(x);      // позволяет определить синус угла. x - угол в радианах.
Math.tan(x);      // x - угол в радианах. тангенс
//
// 
// Объект Number.
var numb = 4; // эта запись равносильна
var numb = new Number(4);   // если это объект то у него есть методы и свойства
//
Number.MAX_VALUE;   // константа максимальное значение, которое можно присвоить переменной  
Number.MIN_VALUE;   // константа
Number.NEGATIVE_INFINITY;   // - бесконечность
Number.POSITIVE_INFINITY;   // + бесконечность
//
Number(x);    // преобразует переданный параметр в числовой тип данных (дробное)
numb.toString();    // преобразует число в строку
numb.toFixed(2);        // преобразует число в строку. Принимает число цифр после точки
nump.toPrecision(numb); // форматирует значащие цифры числа.
//
// реализовать возможность генерации случайного числа от 0 до 100. целые числа.
// выведите на экран тангенсы Пи, Пи/2, /3 


// Объекты.
// И рег.выр. и массивы и функции являются объектами.
// Объект это контейнер из ключей и свойств. 
// 2 способа создания объекта.
var obj = new Object{};   // не использовать, литерал короче и удобней
var obj = {}; // литерал объекта
// 
// Свойство объекта это переменная объявленная внутри объекта.
// именем свойства - ключом может быть любая строка, в том числе пустая. Обычно пишется без ковычек.
// значение свойства может быть любым - другим объектом, функцией, числом, булевым значением, кроме undefined.
// Разделяется имя и значение двоеточием. Свойства разделяются запятой.
var obj = {
  str_name : 'str_value',
  func : function() {}
};
console.log(obj.str_name);    // str_value
//
// Объекты очень уобны для хранения и организации данных. И т.е. в объекты можно вкладывать другие объекты, то можно
// делать полезные древовидные структуры.
// Чтобы достать свойсто можно использовать 2 нотации - точечную и квадратные скобки. 
// Когда надо доставать разные свойства используем переменную и достает эти свойства с помощью квадратных скобок.
// А в любом другом случае используется точечная нотация.
var prop = 'str_name';
var prop = 'func';
obj[prop];
// При попытке обратиться к несуществующему свойству получим undefined.
// Чтобы задать свойство по умолчанию можно использовать оператор "или". Т.е. если у нас нет этого свойства, оно пустое
// то можно его сразу задать. Т.е. если слева false, то берется справа.
console.log(obj.fff_name || 'fff_value');
//
// Присвоение. Добавить новое свойство или изменить старое.
obj.ddd = 'Gag 9';
//
// Объекты всегда передаются по ссылкам, они никогда не копируются.
var a = {prop : 1}, b = {prop : 2}, c = {prop : 3};
console.log(a, b, c);   // Object {prop:1} Object {prop:2} Object {prop:3}
// Но если объекты приравнять друг к другу, то все они имеют ссылку на один и тот же объект.
a = b = c = {prop : 'allTheSame'};
console.log(a, b, c);   // Object {prop : 'allTheSame'}  * 3 
//
// У нас есть объект. Объявляем переменную y и присваиваем ей объект.
var y = obj;
console.log(y.str_name);    // str_value
//
// Удаление свойств. delete удаляет только свойство именно этого объекта, в свойства прототипа он не лезет.
delete obj.func;
//
// Доступ к объекту. Когда функция находиться в объекте, является его свойством, то такая функция называется методам.
// Часто бывает нужен внутри метода доступ к самому объекту или к какому-то из его свойств. Используем ключевое
// слово this.
var obj = {
  str_name : 'str_value',
  func : function() {
    console.log(this.str_name);
  }
};
//
// В js все переменные являются глобальными. Когда работаете в команде создается одна глобальная функция и в ней описывается
// все приложение. Констант как таковых в js нет, обычно пишутся переменные заглавными буквами. Создается объект
// MYAPP и внутри него перечисляются все свойства и методы, которые будут использоваться в приложение.
var MYAPP = {};
//
//
// Каждый объект в js имеет второй объект, который асоциируется с ним называется прототипом. И первый объект наследует
// от прототипа все его свойства. Все объекты созданные с помощью литерала объекта имеют один прототип 
var object = {};    // прототип Object.prototype
var newDate = new Date();   // прототип Date.prototipe
// Object.prototype не имеет прототипа и не наследует ничьи свойства. В свою очерендь Date.prototype наследует 
// Object.prototype. Т.е. Object.prototype это какбы основной прототип для всех объектов, которые наследуют его свойства.
// Если мы вызовем у созданного объекта метод toString то он отработает, хотя мы его не определяли и ошибок при этом нет.
// Потому что метод toString является составным методом Object.prototype и наш объект является наследником данного
// объекта и получает доступ к этому методу.
//
// Реализуем функционал чтобы obj2 получал доступ к свойствам obj1. Есть метод create(), который создает новый объект и
// использует свой первый параметр в качестве прототипа этого объекта. create это даже не метод, а статическая функция.
var obj1 = {x : 1};
var obj2 = Object.create(obj1); // используя такую запись мы создали прототип для obj2. Теперь obj2 унаследовал все свойства
                                // obj1. Как только вы создаете одноименное свойство с наследованным вы его переписываете
                                // в obj2. Если изменить значение свойства в родителе, то изменения произойдут и в дочерних.
//
//
var obj = {
  x1 : 100, x2 : 200, x3 : 300
}
for(var i = 1; i < 4; i++) {
  console.log(obj['x' + i]);
}
//
//
// Проверить наличие свойств у объекта.
obj.hasOwnProperty("property");   // true or false. Но если свойство наследуется то этот метод вернет false.
alert("property" in obj); // оператор in вернет true, если указанное свойство существует в объекте. Не важно наслед или нет
alert(obj.propetyIsEnumerable());  // Если свойство наследуется то этот метод вернет false.
//
//
// Методы чтения и записи свойств. Это специальные методы, которые определяются не при помощи ключевого слова function,
// а при помощи ключ. слов get и set. get определяет код функции, когда будем обращаться к какому-то свойству.
// Метод set определяет код функции, когда мы пытаемся свойство изменить.
var obj = {
  x : 100,
  y : 20,
  get test() {
    return this.x + this.y;
  }
}
console.log(obj.test);
// если попытаемся изменить метод test, то изменений не будет, т.к. мы определили для данной переменной метод get, который
// отрабатывает во время обращения к данной функции.
obj.test = 1000;
//
//
// Определить свой метод.
var obj = {
  myMethod : function () {
    // code
  }
}
// ывет|тип кузова  Создать объект k. Свойство color, type, data


// Объект window.
// Фрейм это другая страница на html странице.
<iframe name='ya' src='frame.html'></iframe>
//
//
// Таймеры
setTimeout('func()', 2000);  // Выполняет действие с задержкой. Возвращает некий идентификатор, для того, чтобы его передать
                             // в clearTimeout(применяется редко т.к. обычно действие выполняется однократно. Чаще
                             // применяется для setInterval)
function time() {
  setTimeout("alert('hello this is set timeout'), 2000");
}
<h1 OnClick="time()">Заголовок</h1>
//
setInterval('func()', 1000);   // позволяет многократно вызывать опреденный код или функцию.
var interval;
function intervar() {
  interval = setInterval(my, 2000)
}
var n = 1;  // просто счетчик
function my() {
  ++n;
  console.log(n);
  if(n == 4) {
    clearINterval(interval);
  }
}
//
//
// window может управлять окнами - открывать, закрывать.
var w = window.open("http://ya.ru", "mywindow", "width:400,height:350,menubar=1, toolbar=1, resizable=0, scrollbars=1");
                // открывает окно(вкладку). Пустое если без параметров. 
                // Метод open возвращает ссылку на открытое окно(переменная w). Это даже не ссылка, это объект window 
                // для нашего нового окна. Это нужно чтобы закрыть данное окно.
                // 1 параметр - путь html страницы, которая будет открыта в новом окне
                // 2 параметр - имя окна. Параметр name служит также целью(т.е. в каком окне будет открыто новое окно).
window.open("http://google.com", "mywindow"); // Гугл будет открыт в этом же окне mywindow.
                // 3 - параметры позволяющие задать ширину/высоту окна/наличие в новом окне панели инструментов/адресной стр.
                // 3 параметр это обычная строка в которой через запятую перечислены соответствующие настройки и иъ значения.
                // width, height - ширина, высота окна
                // menubar - панель меню(1 есть, 0 нет)
                // toolbar - тулбар
                // resizable - возможность изменять окно в размерах. В мозиле не робит, всегда включена.
                // scrollbars - полоса прокрутки
//
//
w.close();     // метод close() закрывает указанное(w) окно.
var w;
function op() {
  w = window.open("http://ya.ru", "mywindow");
}
function cl() {
  w.close();
}
<h2 OnClick="op()">Открыть окно</h2>
<h2 OnClick="cl()">Закрыть окно</h2>
//
//
// Взаимодействие с новым открытым окном.
window.opener;    // свойство вернет 0, если это окно "родительское". И верент ссылку на окно если его открыли.
// index.html
function new_window() {
  w = window.open("new_html.html");
}
var glob_var = "test string";
function get_str() {    // вывод "test string" 100
  console.log(get_str());
  w.remake_str();
  console.log(get_str());
}
// new_html.html
function remake_str() {
  opener.glob_str = 100;
}
//
//
w.focus();  // Присвоить фокус на новое окно.
w.blur();   // снимает фокус с окна
w.print();  // запускает комбинацию клавиш CTRL + P
window.scrollTo(0, 100);    // выполнить перемещение используя полосы прокрутки до указанных.
window.scrollBy(0, 100);    // выполнить перемещение используя полосы прокрутки на указанные пиксели.
w.moveTo(300,300);    // перемещает данное окно в указанную позицию. Задает абсолютную позицию.
w.moveBy(50,50);      // сдвигать на указанное количество пикселей.
w.resizeTo(200,250);  // изменяет размер окна до указанного
w.resizeBy(20,20);      // изменяет размер окна на заданные пиксели
//
//
// Работа с фреймами.
window.frames     // это объект который содержиться внутри window
frames.length;    // вернет количество фреймов на странице
//
<iframe name="first" src="frame1.html"></iframe>
// К фрейму можно обратиться по индексу
frames[0]
// либо по имени фрейма
alert(frames.first.test_frame);    // переменная test_frame объеявлена на странице фрейма(в скрипте)
// из фрейма можно получить доступ к переменным родительского окна с помощью parent(родитель) либо top(самое первое окно)
alert(parent.var_name);
alert(top.var_name);




// Объект window и BOM (объектная модель браузера).
// Глобальный объект window состоит из 3 частей: 
// DOM объектная модель документа
// BOM объектная модель браузера
// и сам javascript все объекты, переменные, которые мы создаем записываются в объект window.
var foo = 'String';
console.log(foo);  /* равносильна */ console.log(window.foo);
// Все что мы выводим вне функций записывается в window.
// console - объект внутри объекта window. log - его метод.
//
// Основные виды объектов, относящиеся к BOM.
// 1. window.navigator это объект, в котором храниться вся информация о браузере и ОС.
console.log(navigator);
navigator.userAgent  // вся информация о браузере
navigator.platform   // информация о ОС. Пригодиться для написания программ, где нужно проверять браузер и систему.
// неактуальные свойства. С их помощью сложно определить браузер.
navigator.appName    // содержит имя браузера. Mozila, Chrome вернут Netscape. Opera-opera. Ie-Ie.
navigator.appVersion // содержит номер версии сборки браузера
navigator.javaEnabled  // Вернет true, если браузер способен выполнять язык java.
//
// не очень актуальные методы
navigator.cookieEnabled();   // проверить включены ли у пользователя cookie

//
// 2. Объект screen. В нем хранятся все данные о экране пользователя. Полезен для проверки если код выполняется на 
//  маленьком разрешении на мобильниках.
console.log(screen.width , screen.height );   // 1200 800
//
// 3. Объект location содержит информацию о текущем url.
// Свойства
location.hash;    // вернет анкор, переданный в url. #top
location.host;    // вернет домен и порт(если есть в адресной строке) localhost:80
location.hostname;  // вернет только сам домен
location.href;      // хранит в себе полную адресную строку. Отрабатывает метод toString()
location.pathname;  // вернет путь от домена до GET параметров /page_1/article_1/index.html
location.protocol; // вернет http:
location.search;    // хранятся GET параметры ?param=1&qwe=2. Самый полезное свойство.
//
// Методы
location.assign("http://google.com");  // загружает и отображает адрес, который передается параметром данному методу. 
                                       // Выполняет перенаправление
window.location = "http://javascript.ru";   // перейти на другую страницу. С точки зрения правильности кода жедательно
                                            // использовать метод assign().
location.reload();    // дает возможность перезагружать страницу с сервера. Будет циклически перезагружать стр.
location.replace();   // аналогичен методу assign. В истории браузера новая ячейка не будет создана, будет переписана
                      // существующая. Нельзя кликнуть назад.
location.toString();  // возвращает полностью текущий url страницы. Отрабатывает автоматически при записи console.log(location)
                      // Возвращает строковое представление url для объекта location.
//
//
// 4. Коллекция frames содержит дочерние объекты(фреймы) которые используются на данной странице.
// 
// 5. Объект history хранит в себе историю просмотра страниц. Позволяет переходить назад вперед по истории перехода страниц, 
// также позволяет без перезагрузки обновлять страницу браузера. На новых одностраничных ajax приложениях все это происходит 
// благодаря об. history. Объект history используется когда нужно организовать перемещение по внутренним страницам сайта
// по истории.
// Нет свойства или метода, который бы вернул пути посещенных страниц. Такое ограничение наложено с целью повышения
// безопасности. Можем выполнять перемещение по элементам истории.
// Свойство
history.length;   // количество элементов в списке истории.
// Методы
history.back();  // переход к предидущему элементу в истории посещений. Аналогичен нажатию кнопки назад в браузере.
history.forward();  // вперед
history.go(-2);   // принимает параметром числовое значение и пропускает в истории заданное число страниц и выполняет 
                // переход на необходимый элемент списка. Чтобы перейти назад передаем отрицательный элемент.
                // Чтобы перейти на 2 элемента назад.
history.pushState('my_data', 'my title', 'index.html?q=2');  // Редкий метод. Добавляет новую запись в объект history, 
                      // т.е. в журнал посещений для данного окна, при этом
                      // сохраняя структурированную копию данных, которые передаются ему 1 параметром, 2 параметр - title
                      // название окна, 3 параметр - url той страницы, которая сохраняется в истории. url должен быть указан
                      // относительно вашего текущего скрипта.
history.replaceState();   // аналог предидущего. Вместо создания новой записи изменяет текущую запись. Браузеры могут 
                          // игнорировать этот метод. Редкий метод.
// принят url, создать массив у которого ключи - названия GET параметров, значения - значения гет параметров
//
//
// 
// Проблемы совместимости.
// 1. Эволюционные проблемы
// 2. Отсутсвие реализации
// 3. Ошибки
// Решение. 
// 1. Определить тип браузера. И уже под него разработать отдельный код.
// 2. Подключение библиотек (js скриптов), которые будут обеспечивать совместимость со всеми  браузерами.
// 3. Использование фреймворков
// 4. Проверка функциональных возможностей
// 5. Условные комментарии html
// 6. Условный комментарий js. 
// cc - condition compilation(условный комментарий)
// @_jscript - переменная в IE всегда равна true.
/*@cc_on
  @if(@_jscript) 
    alert('this is IE');
  @else*/
    alert('another brower');
  /*@end
@*/

//
//
//
// DOM. Объектная модель документа.
// Скрипт подключать внизу страницы, иначе блоки к которым мы обращаемся еще не созданы.
// Выбор элементов
1. document.getElementById();
<h2 OnCLick="fucn()">Выполнить функцию</h2>
function func() {
  var block = document.getElementById('my_text');
  console.log(block);       // Object HTMLParagraphElement
}
2. block = document.getElementsByName('my_name');   // выборка элементов по аттрибуту name(например у элементов формы). 
// name не уникальный элемент, может выбрать несколько (коллекию совпадений). Вернет Object NodeList. Ведет себя как 
// доступный только для чтения массив элементов.
alert(block[0].innerHTML);
//
// Если на странице есть элементы с аттрибутами name, то у глобальго объекта window создаются свойства и именами этих
// свойств. Тоже в объекте document. Т.е. чтобы о братиться к элементу с известным значением name='myName'. 
// Но document.getElementByName('myName') предпочтительней.
var block = document.myName;
//
3. block = document.getElementsByTagName('p');  // выборка элементов по типу(имени тэга). Вернет Object HTMLCollection.
// Формально это объект, но работаем с ним как с массивом. Если передать *, то будут выбраны все hTML тэги на странице.
alert(block[0].innerHTML);    // вывести HTML код первого выбранного параметра.
// 
// Данный метод  также доступен у объекта Element. Допустим выбрали див по id (это уже объект Element). 
// Но внутри него лежит <p> с текстом. Мы знаем что там параграф и нам нудно его отбросить, 
// чтобы получить только текст.
var block = document.getElementById('myDiv');
alert(block.getElementsByTagName('p')[0].innerHTML);
//
4. block = document.getElementsByClassName('my_class');   // выбор элементов по классам. Возвращается объект/массив.
// Также вызывается не только у document, но и конкретно выбранного блока
//
5. querySelector('.my_class')  // выборка элементов по селекторам css. Данный метод выполняет поиск по 
//указанному селектору. Вернет первое совпадение.
var block = document.getElementById('my_id');
alert(block.querySelector('#my_id').innerHTML);
5.1. querySelectorAll('.my_class');   // вернет все элементы, с данным классом.
querySelectorAll('#my_id')[0].innerHTML;
//
6. // Свойства отыскать структурно связанные элементы(родители, дочерние, братья)
block.parentNode;   // вернет родительский узел данного узла или null если нет родителя
block.childNodes;   // Вернет объект NodeList, который представляет все дочерние узлы
block.firstChild;   // первый дочерний элемент
block.lastChild;    // последний дочерний элемент
block.previousSibling;    // предидущий братский узел
block.nextSibling;        // сдежующий братский узел
// nextSibling, previousSibling использовать не удобно, т.к. он постоянно возвразает пустой текстовый узел. 
block.previousElementSibling;    // возвращается предидущий узел типа элемент, т.е. текстовый узел пропускается.
block.nextElementSibling;
// также с lastChild, firstChild. Пропускают текстовые узлы.
block.lastElementChild;
block.firstElementChild;


block.nodeValue;  // свойство хранит в себе значение текстового узла
block.innerHTML;  // HTML содержимое выбранного блока
block.nodeType;   // свойство вернет тип данного узла. Узлы типа document(родитель html) имют значение 9. 
                  // Все узлы типа Element имеют  значение 1. Текстовый узлы - 3. 
block.nodeName;   // вернет имя тэга элемента (P параграф)
block.childElementCount;    // количество дочерних элементов типа элемент
block.children.length;      // количество дочерних элементов
//
//
//
// Работа с аттрибутами. Чтобы получить значение какого-то стандартного аттрибута достаточно обратиться по его имени.
img.src;    // вернет значение аттрибута src для данного изображения.
//
// получим значение аттрибута method у текстовой формы
var form = document.getElementsByTagName('form');
console.log(form[0].method);    // POST или GET
//
// Иногда имена аттрибутов совпадают с зарезервированными словами в js. Аттрибут class. Поэтому явно обратитьтся 
// к аттрибуту class нельзя block.class. Поэтому обращаемся к classNAme. 
block.className
//
1. img[0].getAttribute('class');   // метод позваоляет получить аттрибут по его стандартному названию
2. img[0].setAttribute('src', 'img.jpg');    // установить значение аттрибута
// установить значение аттрибута можно просто обратившись к его свойству
img.src = "img.jpg";
//
// Редко используется
// Спецификация html5 поддерживает создание пользовательских аттрибутов. Должен начинаться с "data-" потом имя аттр.
<div data-my_attr='#'>...</div>
// получить к нему доступ можно с помощью свойства dataset. Это объект пользовательских аттрибутов.
dataset.my_attr
//
// Редко исп.
img.attributes  // объект, который содержит в себе все аттр. данного элемента. У объекта есть 2 свойства - name и value.
// К конкретным аттр. можно добраться по индексам
img.attributes[0].name;   // width например
img.attributes[0].value;  // 150
// К конкретным аттр. можно добраться по имени аттр.
img.attributes['src'].value;
//
//
// innerHTML
var tag = document.getElementsByTagName('h2');
tag[0].innerHTML = 'POSTS';   // изменить содержимое блока.
//
outerHTML;   // хранит в себе код данного элемента вместе с тегами, которые образуют данные тег.
// Когда мы присваиваем данному свойству значение, то содержимое замещает элемент целиком.
//
tag[2].insertAdjacentHTML('beforebegin','<p>New</p>');    // первый параметр - куда будет вставлена разметка, по отнощению 
// к выбранному элементу.
// beforebegin - вставляет перед выбранным элементом
// afterbegin - вставляет на место первого дочернего элемента
// beforeend - вставляет на место последнего дочернего 
// afterend - после выбранного элемента
//
// вытаскивает только текст из определенных элементов. Отбрасывает теги.
div.textContent;
//
div.hasAttribute('class');    // проверяет наличие аттрибута
div.removeAttribute('class'); // удаляет аттрибут
//
//
//
// Создание узлов.
var newNode = document.createTextNode('Содержимое текст узла');  // создает текстовый узел
var newElem = document.createElement('div');   // создаем элемент, содержащий этот текстовый узел
// Вставка узлов
newElem.appendChild(newNode);   // вызывается относительно узла родителя, становиться последним дочерним узлом.
div.insertBefore(newElem, div_name);    // 1 пар - вставляемый узел, 2 пар - узел, перед которым должен быть 
                                        // вставлен новый узел. div_name - див полученный по id.
// удаление элементов
div.removeChild(div.firstElementChild); // вызывается не относительно узла, который должен быть удален, а 
                                        // относительно рожителя удаляемого узла и принимает в качестве 
                                        // параметра дочерний узел, который должен быть удален.
// Или можно получить элемент, который нужно удалить, через него обратиться к родителю и передать параметром самого себя.
var header = document.getElementsByTagName('h1');
header[0].parentNode.removeChild(div[0]);
//
// Замена узлов
header[0].parentNode.replaceChild(newText, header[0]);  // удаляет дочерний узел и замещает его другим. Вызывается 
                                                        // относительно родительского узла. 1 пар - новый узел, 
                                                        // 2 пар - заменяемый узел.
//
//
// Редко исп. Полезен для выполнения операций над множеством узлов. Подкласс объекта Node, он служит временным 
// контейнером для других узлов. Т.е. создаем объект(контейнер) DocumentFragment и помещаем в него различные узлы.
// Со всеми ними можно работать как с одним большим узлом.
var frag = document.createDocumentFragment();
frag.appendChild(elem1);
frag.appendChild(elem2);
div.appendChild(frag);
//
//
// Работа с формами.
<form method="post" name="my_name" action="#">
  <input type="text" name="text_field_1"/>
</form>
// У объекта document есть свойство forms. Данное свойство ссылается на объект HTML Collection, в котором 
// содержатся все формы данного документа. Хотя форму можно выбрать по тегу или id.
document.forms.my_name  // обратились к свойству формз и выбрали форму по аттр. name.
document.forms[0]       // или так
// чтобы обратиться к конкретному полю input можно по именам
document.forms.my_name.text_field_1;    // вернет Object HTMLInputElement
// обратиться к аттрибуту поля
document.forms.my_name.text_field_1.type;   // text
// полуичть содержимое поля - свойство value
document.forms.my_name.text_field_1.value;
// Обращаться к элементам формы можно не используя их имена, а используя свойство elements, которое содержит все
// елементы формы.
document.forms.my_name.elements[0].value;
// Радиокнопки и чекбоксы имеют одно имя и разное значение. Нам вернется объект, подобный массиву с элементами с 
// одинаковыми именами.
<input type="radio" name="my_radio"/>
<input type="radio" name="my_radio"/>
document.my_name.elements.my_radio[0];
// метод submit - выполняет отправку формы
document.forms.my_name.submit();
//
//
// Редко исп. свойства объекта Document
document.images[0].src;    // данное свойство images ссылается на Object HTML Collection, в котором содержаться 
// все изображения документа
document.documentElement;  // ссылается на корневой узел html
document.body;    // HTMLBodyElement
document.title;   
document.anchors; // все якоря
document.applets; // все java аплеты
document.links;   // все ссылки
// методы
document.createAttribute();
document.createElement();
document.createTextNode();
1. копирайты отобразить жирным шрифтом, после нажатия на выполн функ. Исп replaceChild. заместить данный узел узлом
стронг и внутрь его поместить данную строку
2. создать функцию, которая пронумерует пункты меню. Добавить возлекаждого пункта его номер. 
3. выполнить сортировку в обратном порядке дочерних элементов узла body
var b = document.body;
var f = document.createDocumentFragment();
while(b.lastChild) {
  f.appendChild(f.lastChild);
}
b.innerHTML = f;
4. выполнять перемещениепо DOM



// События.
// Тип события это строка, обозначающая тип выполненного действия. Событие это click. Приставка on 
// дописывается в соответствии с спецификацией.   
//
// Чтобы заставить браузер выполнять код по клику можно добавить элементу аттрибут onclick="my_func()"
//
// События загрузки и готовности документа. 
// чтобы обратиться к событию и назначить обработчик события обратимся к одноименному свойству объекта 
window.onload = function() {...}   // код сработает после полной загрузки страницы
// 
// События форм
onsubmit  // данное событие срабатывает, когда происходит отправка формы
onreset   // нажатие на кнопку reset
onchange  // срабатывает когда выполняется изменение елементов форм (ввод данных) а затем убирается курсор.
oninput   // аналогично событию onchange. За исключением того, что данное событие срабатывает сразу же, как только
          // пользователь вводит символ в текстовое поле
obj.onchange = function() {
  alert(obj.value);
} 
//
onfocus  // наведение курсора
onblur   // уведение курсора - потеря фокуса
onfocusin - IE
onfocusout - IE
//
//
// События мыши
onclick   // когда срабатывает данное событие, создается объект у которого есть свойства. Чтобы их получить
          // надо передать параметр e(event) в анонимную функцию. В этот параметр попадает объект самого события.
          // altKey, shiftKey, ctrlKey вернут тру, если в момент клика была нажата соответствующая кнопка.
          // свойства clientX, clientY вернут координаты клика
          // свойство button показывает какой кнопкой кликали
obj.onclick = function(e) {
  alert(e.altKey);    
}
onmousemove   // срабатывает на движение мыши
onmousedown   // нажатие клавиши мыши
onmouseup     // пользователь отпускает нажатую клавишу
oncontextmenu // кликая правой кнопкой мыши на экране пользователь открывает контекстное меню. Срабатывает событие.
obj.oncontextmenu = function(e) {
  return false;  // если функция-обработчик события возвращает false, то отменяется стандартное поведение 
                 // для данного события. Когда происходит клик правой кнопкой, браузер знает, что выхвано
                 // контекстное меню. И если мы отменяем текущее значение по умолчанию данного события, то
                 // вызов контекстного меню не проихойдет.
}
ondbclick  // двойной клик. Редко исспольз.
onmouseover   // срабатывает когда пользователь перемещает курсор на выбранный нами элемент
onmouseout    // когда уводим курсор с элемента
onmousewheel  // когда выполняется прокрутка колесом мыши. может не работать в Firefox
//
//
// События объекта window
window.onload = function() {...}       // код сработает после полной загрузки страницы
window.onbeforeunload = function() {      // срабатывает, перед тем как пользователь покидает документ
  return confirm('Вы уходите?');
}
window.onfocus  // срабатывает, когда окно получает фокус
window.onblur   // или его теряет. Актуально, когда вы создаете окна из определенного документа
window.onresize // срабатывает при изменении размера окна
window.onscroll // при прокрутке окна
//
//
// События клавиатуры
onkeypress // Нажатие клавиши. Является высокоуровневым событием. И ему соответствует объект, котоый содержит 
         // информацию о введенном символе нажатой клавиши.
e.keyCode // это ствойство содержит код нажатой клавиши         
obj.onkeypress = function(e) {
  console.log(e.keyCode);
}  
onkeyup     // отжата
onkeydown   // срабатывает когда нажата клавиша
//
//
// Если описать обработчик события onchange в html теге input. this переданный параметром функции означает
// объект того элемента, у которого указан данный обработчик события. Его не нужно будет выбирать мы его сразу передаем.
<input type='text' onclick='myFunc(this)'/>
myFucn(param) {
  console.log(param.value);
}
//
//
//
// Фазы распространения события.
<div onclick="myFunc(this)">
  <p onclick="myFunc(this)">p text
    <span onclick="myFunc(this)">span text</span>
  </p>
</div>
myFunc(e) {
  alert(e.tagName);   // выведет имя тега. аналог nodeName
}
// При клике по спану отработает его обработчик события, затем p и родительского дива. Выведется 3 окна. span-p-div.
// На данном примере мы видим фазу распространения события. А именно 3-ю фазу распространения события, которая
// называется всплытие. 
document--родитель--родитель--целевой_элемент
// Обработка события делится на 3 фазы 
// 1. перехват. Еще до того как вызывается событие в ЦЭ, т.е. пользователь кликнул мышью, но событие не 
// обработалось, начинается фаза перехвата события. Т.е. событие двигается от родительского элемента и проходит
// ниже по узлам дерева DOM до ЦЭ таким образом, что событие можно перехватить в любом из родительских
// элементов. В первую очередь вызываются перехватывающие обработчики самого верхнего элемента(window), затем
// document, body и т.д. к ЦЭ, до тех пор пока не будут вызваны перехватывающие обработчики родителя ЦЭ.
// Перехватывающие обработчики, которые зарегистрированы в самом ЦЭ при этом не вызывются 
// Модель распространения события бывает 2 видов: 
  // 1.модель распространения событий-дерево DOM.
  // 2.модель распространения событий браузера IE. В IE8 и ниже первая фаза распространения события отсутствует.
  // Поэтому так сложилось, что фаза перехвата очень редко используется.
// 2. вызов обработчика события в целевом элементе. Вызвалась назначенная функция.
// 3. всплытие. Событие после обработки в ЦЭ начинает подниматься вверх по дереву DOM от ЦЭ к родителю 
// до самого верха. 
//
//
// Как можно одному событию назначить несколько функций обработчиков. Т.е. чтобы по клику 
// выполнилось сразу несколько функций. 
obj.addEventListener('click', myFunc, false); // данный метод позволяет регистрировать обработчики событий.
// 1. параметр - тип события, для которго назначаем функции-обработчики. Имя события пишется без приставки "on".
// 2. функция, которая должна вызываться при отработке события(без скобок. Если укажем скобки, это будет вызов,
//   а так только ссылка). Можно указать анонимную функцию.
// 3. передается false или true. Обычно false. Если передаем true, функция обработчик будет зарегистрирована
//   как перехватывающий обработчик и будет вызывться в 1 фазе распространения события.
//
<h2 id='myId'>My text</h2>
window.onload = function() {
  h2 = document.getElementById('myId');
  h2.onclick = myFunc;  // так нельзя назначить несколько функций обработчиков.
  h2.addEventListener('click', myFunc, false);
  h2.addEventListener('click', myFunc2, false);
}
myFunc(e) {
  // когда отрабатывает addEventListener в переменную е приходит объект данного события.[object MouseEvent]
  console.log('1');
}
myFunc2(e) {
  console.log('2');
}  
//
//
// Кроссбраузерность!!!
// метод для IE8 и ниже
h2.attachEvent('onclick'. myFunc);  // 2 параметра. Тип события с приставкой on.
// Как написать кроссбраузерный скрипт. Для этого обычно пишется функция, которая будет выполнять роль регистратора
// обработчика событий.
function get_hendler(target, type, func) {
  if(target.addEventListener) {
    target.addEventListener(type, func, false);
  }
  else if(target.attachEvent) {
    target.attachEvent('on' + type, func);
  }
}
function myFunc(e) {
  e = e || window.event;
  alert(e);
}
function myFunc2(e) {
  e = e || window.event;
  alert(e);
}
window.onload = function() {
  get_hendler(h2, 'click',  myFunc);
  get_hendler(h2, 'click',  myFunc2);
}
//
//
//
// Как отменить действие по умолчанию для определенных элементов. 
<a href='http://ya.ru' onclick='myFunc'>link</a>
myFunc(e) {
  e.preventDefault();
}
// Что делать если мы хотим произвести над этой ссылкой какие-то действия по клику. Действия выполняться, но
// будет совершен преход по ссылке.
// У объекта события e есть метод
e.preventDefault();    // отменяет действие по умолчанию для выбранного эл.
// 
e.returnValue = false;  // IE8 подобный эффект достигается с помощью
myFunc(e) {
  e = e || window.event;
  if(e.preventDefault()) {
    e.preventDefault()
  }
  else if(e.returnValue) {
    e.returnValue = false;
  }
}
//
// также отменить действие по умолчанию
<a href="#" onclick='return false'>
//
//
// Методы позволяющие остановить распространение события.
stopPropagation();   // прерывает распространене события. Вызывается у одного из родителей. IE8 не поддерж.
window.event.cancelBubble = true;   // для IE8
removeEventListener()   // удаляет фунцию обработчик из объекта. Применяется для временных обработч соб.
detachEvent();   // для IE8

// 1. разворачивающиеся меню