Гладкий Максим Валерьевич / github:MaksHladki
"use strict";
myFunction();
function myFunction() {
y = 3.14;
}
var PI = 3.14;
myFunction();
function myFunction() {
"use strict";
var y = 3.14;
}
Удалено в спецификации ES2015
var colors = {
red: '#FF0000',
green: '#00FF00',
blue: '#0000FF',
red: '#FF0000'
};
//Ex: An object literal cannot have multiple
//properties with the same name in strict mode.
PI = 3.14;
//Ex: PI is not defined
function log(arg, arg) {
console.log(arguments);
}
log(1, 2, 4);
//Ex: Duplicate parameter name not allowed in this context
delete Object.prototype;
//Ex: Cannot delete property 'prototype' of function Object()
var x = 17;
var evalX = eval("var x = 42;x");
console.log(x); //17
console.log(evalX); //42
var x = 17;
with (obj)
{
x;
}
//Ex: syntax error
В JavaScript все глобальные переменные и функции являются свойствами специального объекта, который называется « глобальный объект » (global object).
В браузере этот объект доступен под именем window
Объект window одновременно является глобальным объектом и содержит ряд свойств и методов для работы с окном браузера.
var browser = 'Chrome';
console.log(window.browser); //Chrome
window.browser = 'Opera';
console.log(window.browser); //Opera
//window = { f: function, log: undefined, browser: undefined }
var browser = 'Chrome';
//window = { f: function, log: undefined, browser: 'Chrome' }
var log = function (msg) {
console.log(msg);
}
//window = { f: function, log: function, browser: 'Chrome' }
function f() {}
var N = 10;
var i;
for (i = 0; i < N; i++) {}
for (var i = 0; i < N; i++) {}
var i = 0;
while (i < N) {}
var i = 100;
var res = N * i;
function logger(msg) {
//LexicalEnvironment = { msg: 'Test', date: undefined}
var date = new Date().toDateString();
//LexicalEnvironment = { msg: 'Test', date: 'Sun Oct 30 2016'}
console.log(date + ' : ' + msg);
}
logger('Test');
logger.[[Scope]] = window;
var date = new Date().toDateString();
function logger(msg) {
//LexicalEnvironment = { msg: 'Test', date: 'Sun Oct 30 2016'}
console.log(date + ' : ' + msg);
}
logger('Test');
var date = new Date().toDateString();
function logger(msg) {
console.log(date + ' : ' + msg);
}
logger('Test'); //Sun Oct 30 2016 : Test
date = '30.10.2016';
logger('Test 2'); //30.10.2016 : Test 2
function makeCounter() {
var currentCount = 1;
return function () {
return currentCount++;
};
}
var counter = makeCounter();
//каждый вызов увеличивает счётчик и возвращает результат
console.log(counter()); //1
console.log(counter()); //2
console.log(counter()); //3
//если создать другой счётчик, он будет независим от первого
var counter2 = makeCounter();
console.log(counter2()); //1
window.a = 1;
function getFunc() {
var a = 2;
var func = new Function('', 'alert(a)');
return func;
}
getFunc()();//1
Замыкание – это функция вместе со всеми внешними переменными, которые ей доступны
var counter = 5;
var add = (function () {
var counter = 0;
return function () {
return counter += 1;
}
})();
add();
add();
console.log(add());//???
counter = 3
var student1 = {
course: 3,
print: function(){
console.log(course);
}
};
student1.print();
//Ex: Uncaught ReferenceError: course is not defined
var student2 = {
name: 'Max',
print: function(){
console.log(this.name);
}
};
student2.print();//Max
var student2 = {
name: 'Max',
print: function(){
console.log(student2.name);
}
};
student2.print();//Max
function func(){
console.log(this);
}
func();//[object Window]
Если одну и ту же функцию запускать в контексте разных объектов, она будет получать разный this. Это значение не зависит от того, как функция была создана, оно определяется в момент вызова
function print (){
console.log(this.name);
}
var person = {
name: 'Irina',
print: print
};
var student = {
name: 'Ivan',
print: print
};
person.print();//Irina
student.print();//Ivan
Вызывает функцию с указанным значением this и предоставленными аргументами
fun.call(thisArg[, arg1[, arg2[, ...]]])
function showFullName() {
console.log(this.firstName + " " + this.lastName);
}
var user = {
firstName: "Василий",
lastName: "Петров"
};
//this = user
showFullName.call(user);//Василий Петров
Вызывает функцию с указанным значением this и аргументами, предоставленными в виде массива
func.apply(context, [argsArray])
var x = 10;
var o = { x: 15 };
function f(message)
{
console.log(message);
console.log(this.x);
}
f("test");//test 10
f.apply(o, ["test"]);//test 15
/* мин/макс числа в массиве */
var numbers = [5, 6, 2, 3, 7];
/* используем apply к Math.min/Math.max */
var max = Math.max.apply(null, numbers);
/* Это эквивалентно Math.max(numbers[0], ...)
или Math.max(5, 6, ...) */
var min = Math.min.apply(null, numbers);
var wrapper = func.bind(context[, arg1, arg2...])
function f(a, b) {
console.log(this);
console.log(a + b);
}
var g = f.bind("Context");
g(1, 2); //Context 3
Создание новой функции путем фиксирования аргументов существующей (термин из функционального программирования)
function mul(a, b) {
return a * b;
}
//double умножает только на два
var double = mul.bind(null, 2);
//контекст фиксируем null, он не используется
console.log(double(3));//mul(2, 3) = 6
console.log(double(4));//mul(2, 4) = 8
console.log(double(5));//mul(2, 5) = 10
function showArgs() {
//arguments.length [0] ... [n]
var argStr = arguments.join(':');
console.log(argStr);
}
showArgs(1, 2, 3);//arguments.join is not a function(…)
function showArgs() {
var join = [].join; //скопируем ссылку на функцию в переменную
//вызовем join с this = arguments,
//этот вызов эквивалентен arguments.join(':')
var argStr = join.call(arguments, ':');
console.log(argStr);
}
showArgs(1, 2, 3);//1:2:3
Array | массив пронумерованных элементов |
Boolean | объект для булевых значений |
Date | функции для работы с датой и временем |
Error | объект для представления ошибок |
Function | каждая функция в JS является объектом класса Function |
JSON | содержит методы для разбора объектной нотации JS |
Math | константы и методы для математических вычислений |
Number | объект для работы с числами |
Object | базовый объект javascript |
RegExp | позволяет работать с регулярными выражениями. |
String | управление, форматирование и другие операции с текстовыми строками |
SyntaxError | ошибка при интерпретации синтаксически неверного кода |
window | определяет глобальный объект и окно браузера |
function Person(name, age){
this.name = name;
this.age = age;
this.getName = function(){
return this.name;
}
this.getAge = function(){
return this.age;
}
}
var person = new Person('Max', 18);
console.log(person.getName());//Max
console.log(person.getAge()); //18
console.log(person instanceof Object);//true
console.log(person instanceof Person);//true
function Person(name, age) {
this.name = name;
this.age = age;
this.getName = new Function('return this.name;');
}
var p1 = new Person('Ira', 23);
var p2 = new Person('Max', 25);
console.log(p1.getName());//Ira
console.log(p2.getName());//Max
console.log(p1.getName == p2.getName); //false
function Person(name, age) {
this.name = name;
this.age = age;
this.getName = function() {
return this.name;
}
}
var p1 = new Person('Ira', 23);
var p2 = new Person('Max', 25);
console.log(p1.getName()); //Ira
console.log(p2.getName()); //Max
console.log(p1.getName == p2.getName); //false
function Person(name, age) {
this.name = name;
this.age = age;
this.getName = getName
}
function getName(){
return this.name;
}
var p1 = new Person('Ira', 23);
var p2 = new Person('Max', 25);
console.log(p1.getName == p2.getName); //true
Публичное и приватное свойство
function Person(name, age) { var fAge = 'лет'; this.name = name; this.getAge = function(){ return age + ' ' + fAge; } } var person = new Person('Max', 20); person.name = 'Maxim'; console.log(person.name);//Maxim console.log(person.getAge());//20 лет
Публичный и приватный метод
function Person(name, age) { this.name = name; this.getAge = function(){ return formatAge(age); } function formatAge(age){ return age + ' лет'; } } var person = new Person('Max', 20); console.log(person.formatAge);//undefined console.log(person.getAge());//20 лет
function Person() {
var _age = 0;
this.setAge = function (age) {
if (age <= 0 || age >= 100)
throw "Значение должно быть больше 0 и меньше 100";
_age = age;
}
this.getAge = function () {
return _age;
}
}
var person = new Person();
person.setAge(20);
console.log(person.getAge());//20
person.setAge(100);//Ex. Значение должно быть больше 0 и меньше 100
function Person(name, age){
this.name = name;
this.age = age;
this.getName = function(){
return this.name;
}
this.getAge = function(){
return this.age;
}
}
function Student(course, group) {
Person.call(this);
this.course = course;
this.group = group;
}
var student = new Student(1, 1);
student.name = 'Peter';
student.age = 24;
console.log(student.name);//Peter
console.log(student.group);//1
Person.call(this);
function Student(course, group) {
Person.call(this);
this.course = course;
this.group = group;
this.getAge = function () {
return this.age + ' лет';
}
}
var student = new Student(1, 1);
student.age = 20;
console.log(student.getAge()); //20 лет
function Person(name, age) {
this.age = age;
this.printAge = function () {
setTimeout(console.log(formatAge()), 1000);
}
function formatAge() {
return this.age + ' лет';
}
}
var person = new Person('Max', 20);
person.printAge(); //undefined лет
function Person(name, age) {
var self = this;
this.age = age;
this.printAge = function(){
setTimeout(console.log(formatAge()), 1000);
}
function formatAge(){
return self.age + ' лет';
}
}
var person = new Person('Max', 20);
person.printAge(); //20 лет
THIS в JS не привязывается к объекту, а зависит от контекста вызова. В случае с конструктором this ссылается на созданный экземпляр при условии использования ключевого слова new.
function Person(name, age){
this.name = name;
this.age = age;
this.getName = function(){
return this.name;
}
this.getAge = function(){
return this.age;
}
Person.counter++;
}
Person.counter = 0;
Person.getCount = function(){
return Person.counter;
}
new Person('Max', 26);
new Person('Yulia', 21);
console.log(Person.getCount());//2
var person = {
age: 24,
name: 'Alex'
};
var student = {
course: 1,
group: 6
};
student.__proto__ = person;
console.log(student.age);//24
console.log(student.name);//Alex
var person = {
age: 24,
name: 'Alex'
};
var student = {
course: 1,
group: 6
};
student.__proto__ = person;
student.age = 10;
console.log(student.age);//10
console.log(person.age);//24
delete student.age;
console.log(person.age);//24
console.log(student.age);//24
var person = {
age: 24,
name: 'Alex'
};
function Student(course, group) {
this.course = course,
this.group = group;
//this.__proto__ = person; не работает в IE10-
};
//!!! свойство доступно через тип, а не через объект
Student.prototype = person;
var student = new Student(1, 1);
console.log(student.age);//24
function Person(age, name){
this.Age = age;
this.Name = name;
}
Person.prototype.getAge = function(){
return this.Age;
}
var person = new Person(20, 'Max');
console.log(person.getAge());//20
var person2 = new Person(18, 'Yulia');
console.log(person.getAge == person2.getAge);//true
var o1 = new Object();
console.log(o1);//{}
var o2 = {};
console.log(o2);//{}
Объект Object.prototype – вершина иерархии, единственный, у которого __proto__ равно null
Cоздает новый объект с указанными объектом прототипа и свойствами
Object.create(proto[, propertiesObject])
var person = {
age: 20
}
var student = Object.create(person);
console.log(student.age);//20
function Person(name) {
this.name = name;
}
function Student(course, name) {
Person.call(this, name);
this.course = course;
}
Student.prototype = Object.create(Person.prototype);
var student = new Student(5, 'Anna');
console.log(student.name);//Anna
console.log(student.course);//5
function Person(){
this.age = 0;
}
Person.prototype.setAge = function(age){
this.age = age;
}
Person.prototype.getAge = function(){
return this.age;
}
var person = new Person();
person.setAge(100);
console.log(person.getAge());//100
function Person(name) {
this.name = name;
}
Person.prototype.setName = function (name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
function Student(course, name) {
Person.call(this, name);
this.course = course;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.getCourse = function () {
return this.course;
}
var student = new Student(10, 'Anna');
console.log(student.getName());//Anna
function Person(name) {
this.name = name;
}
Person.prototype.setName = function (name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
function Student(name) {
Person.call(this, name);
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.getName = function () {
return 'Name: ' + Person.prototype.getName.call(this);
}
var student = new Student('Anna');
console.log(student.getName());//Name: Anna
function Person(){
this.age = 0;
}
var person = new Person();
alert(person);//[object Object]
Person.prototype.toString = function(){
return this.age;
}
alert(person);//0
//Вывод ключей без использования метода hasOwnProperty
var person = {
age: 24,
name: 'Alex'
};
var student = {
course: 1,
group: 6
};
student.__proto__ = person;
for(var key in student)//course group name age
console.log(key);
//Вывод ключей с использованием метода hasOwnProperty
var person = {
age: 24,
name: 'Alex'
};
var student = {
course: 1,
group: 6
};
student.__proto__ = person;
for(var key in student)//course group
if(student.hasOwnProperty(key)) console.log(key);
function Person(name) {
this.name = name;
}
Person.prototype.setName = function (name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
function Student(course) {
this.course = course;
}
Student.prototype = Object.create(Person.prototype);
var student = new Student(20);
console.log(Object.keys(student));//["course"]
function Person(name) {
this.name = name;
}
var person = new Person(20);
Object.defineProperty(person, 'age', {
enumerable: true,
configurable: true,
//writable: true, нельзя использовать совместно с get/set
//value: 0, нельзя использовать совместно с get/set
get: function(){
return age + ' лет';
},
set: function(newAge){
age = newAge;
}
});
person.age = 10;
console.log(person.age);//10 лет
function Person(name) {
this.name = name;
Object.defineProperty(this, 'age', {
enumerable: false,
configurable: true,
value: 0,
});
}
var person = new Person(20);
console.log(Object.getOwnPropertyNames(person));//["name", "age"]
console.log(Object.keys(person));//["name"]
function Person(){
this.age = 0;
}
var person = new Person();
alert(person);//[object Object]
Person.prototype.toString = function(){
return this.age;
}
alert(person);//0
function A(){}
function B(){}
B.prototype = Object.create(A.prototype);
console.log(typeof undefined);//undefined
console.log(typeof 0);//number
console.log(typeof true );//boolean
console.log(typeof "foo"); //string
console.log(typeof {}); //object
console.log(typeof null); //object
console.log(typeof function(){}); //function
var a = new A();
console.log(typeof a);//object
var b = new B();
console.log(typeof b);//object
function A(){}
function B(){}
B.prototype = Object.create(A.prototype);
var a = new A();
var b = new B();
console.log(a instanceof A);//true
console.log(b instanceof B);//true
console.log(a instanceof B);//false
console.log(b instanceof A);//true
console.log(a instanceof Object);//true
console.log(b instanceof Object);//true
console.log(A.prototype instanceof Object);//true
console.log(B.prototype instanceof Object);//true
console.log(A.prototype instanceof B);//false
console.log(B.prototype instanceof A);//true
console.log(Object.prototype instanceof Object);//false
<!DOCTYPE HTML>
<html>
<head>
<title>Какой-то заголовок</title>
</head>
<body>
Какой-то текст
</body>
</html>
Пробелы и переводы строки – это тоже текст, полноправные символы, которые учитываются в DOM
interface Node {
//Всевозможные значения nodeType
const unsigned short ELEMENT_NODE = 1;
const unsigned short ATTRIBUTE_NODE = 2;
const unsigned short TEXT_NODE = 3;
const unsigned short CDATA_SECTION_NODE = 4;
const unsigned short ENTITY_REFERENCE_NODE = 5;
const unsigned short ENTITY_NODE = 6;
const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
const unsigned short COMMENT_NODE = 8;
const unsigned short DOCUMENT_NODE = 9;
const unsigned short DOCUMENT_TYPE_NODE = 10;
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12;
...
}
Интерфейс HTMLCollection является обобщённой коллекцией (объектом, ведущим себя подобно массиву) элементов (в порядке упоминания в документе) и предоставляет методы и свойства для получения хранящихся в нём элементов
item | возвращает узел с порядковым номером index; отсчёт ведётся от нуля. Возвращает null, если index выходит за границы допустимого диапазона |
namedItem | возвращает узел, идентификатор или имя которого совпадает со строкой, переданной в аргументе name. Возвращает null, если элемент отсутствует |
length | возвращает количество элементов в коллекции |
var images = document.images;
console.log(images.length);//1
var img = document.createElement('img');
document.body.appendChild(img);
console.log(images.length);//2
function foreach(){
var collections = document.body.childNodes;
[].forEach.call(collections, function(item, index){
console.log(item);
console.log(index);
});
}
<!DOCTYPE>
<html>
<head>
<title>Navigation</title>
</head>
<body>
<div id="container">
<div class="content" name="content">
<div class="title">
<h3 name="title_1">Title 1</h3>
</div>
<div class="message">
<a href="google.com">google</a>
</div>
</div>
<div class="content">
<div class="title">
<h3>Title 2</h3>
</div>
<div class="message">
<img src="https://www.wired.com/wp-content/uploads/2015/09/google-logo-1200x630.jpg" alt="">
</div>
</div>
</div>
<script src="navigation.js"></script>
<script>
var example = new NavigationExample();
example.title();
</script>
</body>
</html>
Запись запрещена, только чтение
Только getter, запись без сохранения результата
function head() {
console.log(document.head);
document.head = 'Test
';
console.log(document.head);
}
Getter + Setter
function title() {
console.log(document.title);//Navigation
document.title = 'Test';
console.log(document.title);//Test
}
Только getter, запись без сохранения результата
function links(){
console.log(document.links);
document.links = [];
console.log(document.links);
}
Только getter, запись без сохранения результата
function images(){
console.log(document.images);
document.images = [];
console.log(document.images);
}
console.log(document.documentElement);
//root element in document (html)
Дочерние элементы (дети) – элементы, которые лежат непосредственно внутри данного. Например, внутри <HTML> обычно лежат <HEAD> и <BODY>
Потомки – все элементы, которые лежат внутри данного, вместе с их детьми, детьми их детей и так далее. То есть, всё поддерево DOM
console.log(document.body.childNodes);
console.log(document.body.childNodes[1].childNodes);
for (var i = 0; i < document.body.childNodes.length; i++) {
console.log( document.body.childNodes[i] );
}
var container = document.getElementById('container');
for (var i = 0; i < container.childNodes.length; i++) {
console.log( document.body.childNodes[i] );
}
function firstChild() {
console.log(document.body.firstChild);
console.log(document.body.childNodes.firstChild);
console.log(document.body.childNodes[1].firstChild);
}
function firstChild() {
console.log(document.body.lastChild);
console.log(document.body.childNodes.lastChild);
console.log(document.body.childNodes[1].lastChild);
}
В отличии от childNodes, children удаляет текстовые узлы и комментарии
function children(){
console.log(document.body.children);
console.log(document.body.children[0].children);
}
Доступное только для чтения свойство, возвращает первый дочерний элемент объекта (Element) или null, если дочерних элементов нет
function firstElementChild(){
console.log(document.body.firstElementChild);
console.log(document.body.childNodes.firstElementChild);
console.log(document.body.childNodes[1].firstElementChild);
}
Доступное только для чтения свойство, возвращает первый дочерний элемент объекта (Element) или null, если дочерних элементов нет
function lastElementChild() {
console.log(document.body.lastElementChild);
console.log(document.body.childNodes.lastElementChild);
console.log(document.body.childNodes[1].lastElementChild);
}
Содержит узел, который следует сразу за узлом, вызвавшим это свойство или null, если такового не существует
function nextElement() {
console.log(document.body.nextElementSibling);
console.log(document.getElementById('container').children[0].nextElementSibling);
console.log(document.body.childNodes[1].childNodes[2].nextElementSibling);
}
Содержит узел, который следует перед узлом, вызвавшим это свойство или null, если такового не существует
function prevElement() {
console.log(document.body.previousElementSibling);
console.log(document.getElementById('container').children[1].previousElementSibling);
console.log(document.body.childNodes[1].childNodes[2].previousElementSibling);
}
Возвращает родителя узла DOM Element, или null если узел не имеет родителя, или его родитель не DOM Element
function parentElement(){
console.log(document.getElementById('container').children[1].parentElement);
console.log(document.body.childNodes[1].firstElementChild.parentElement);
}
table.rows | коллекция строк TR таблицы |
table.caption/tHead/tFoot | ссылки на элементы таблицы CAPTION, THEAD, TFOOT |
table.tBodies | коллекция элементов таблицы TBODY, по спецификации их может быть несколько |
tbody.rows | коллекция строк TR секции TBODY |
tr.cells | коллекция ячеек TD/TH |
tr.sectionRowIndex | номер строки в текущей секции THEAD/TBODY |
tr.rowIndex | номер строки в таблице |
td.cellIndex | номер ячейки в строке |
<table id="table">
<thead>
<tr>
<th>Key</th><th>Value</th>
</tr>
</thead>
<tfoot>
<tr>
<td>1</td><td>1</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>A</td><td>1</td>
</tr>
</tbody>
</table>
function rows(){
var table = document.getElementById('table');
console.log(table.rows);
}
function tbody() {
var table = document.getElementById('table');
console.log(table.tBodies);
}
function cells(){
var row = document.getElementById('table').rows[0];
console.log(row.cells);
}
Оптимизация баузера (работает быстро). Внутреннее соответствие id -> элемент
function getElementById(){
console.log(document.getElementById('container'));
console.log(document.getElementById('tag'));
}
При изменении документа – изменяется и результат запроса
function getElementsByTagName(){
console.log(document.getElementsByTagName('img'));
console.log(document.getElementsByTagName('div'));
console.log(document.getElementsByTagName('bla'));
}
function getElementsByName() {
console.log(document.getElementsByName('title__1'));
console.log(document.getElementsByName('content'));
console.log(document.getElementsByName('img'));
}
function getElementsByClassName() {
console.log(document.getElementsByClassName('content'));
console.log(document.getElementsByClassName('title'));
console.log(document.getElementsByClassName('img'));
}
Firefox + IE + Edge
var elems = document.getElementsByTagName('div');
console.log(elems[0]);
console.log(elems[995]);
console.log(elems[500]);
console.log(elems.length);
Webkit (Chrome + Safari + Opera)
Перебирает подэлементы body. Запоминает только последний найденный элемент, а также, по окончании перебора – длину коллекции
Отличия от предыдущего способа
var elems = document.getElementsByTagName('div');
console.log(elems[0]);
console.log(elems[995]);
console.log(elems[500]);
console.log(elems.length);
Перебирает все подэлементы внутри элемента и проверяет каждый элемент на соответствие запросу
//Результаты поиска сохраняются в кеше пока документ не изменится
function querySelectorAll(){
console.log(document.querySelectorAll('#container'));
console.log(document.querySelectorAll('div.content .title'));
}
function querySelector(){
console.log(document.querySelector('#container'));
console.log(document.querySelector('div.content .title'));
}
function closest() {
var link = document.getElementsByTagName('a')[0];
console.log(link.closest('.content'));
console.log(document.querySelector('#container'));
}
attributes | возвращает все атрибуты элемента |
classList | возвращает псевдомассив DOMTokenList |
className | возвращает/задает атрибута class элемента |
clientHeight | CSSheight + CSSpadding - horizontalScrollHeight |
clientWidth | CSSwidth + CSSpadding - horizontalScrollWidth |
data | содержимое тестового узла |
firstElementChild | возвращает первый дочерний элемент объекта |
id | возвращает идентификатор элемента в DOM |
innerHTML | возвращает/задает HTML-содержимое в виде строки |
hidden | возвращает/задает видимость узла |
name | возвращает/задает атрибут name |
outerHTML | возвращает HTML (при записи заменяется на новый) |
scroll[Height...] | высота контента, включая содержимое, невидимое из-за прокрутки |
shadowRoot | внутренний DOM элемента |
tagName | возвращает HTML-тег элемента |
function attributes() {
var container = document.getElementById('container');
console.log(container.attributes);
var link = document.getElementsByTagName('a')[0];
console.log(link.attributes);
}
function html() {
var container = document.getElementById('container');
console.log(container.innerHTML);
console.log(container.outerHTML);
container.outerHTML = 'Text';
console.log(container.outerHTML);//empty
console.log(document.getElementById('container'));//null
}
hasAttribute | проверяет наличие атрибута |
getAttribute | получает значение атрибута |
setAttribute | устанавливает атрибут |
removeAttribute | удаляет атрибут |
contains | проверка вложенности элементов |
matches | проверка соответствия указанному css-селектору |
remove | удаляет узел из дерева DOM |
function attribute() {
var link = document.getElementsByTagName('a')[0];
console.log(link.hasAttribute('href'));//true
console.log(link.getAttribute('href'));//http://google.com
console.log(link.getAttribute('class'));//link
link.setAttribute('href', 'habrahabr.ru');
console.log(link.getAttribute('href'));//habrahabr.ru
link.removeAttribute('href');
}
function matches() {
var link = document.getElementsByTagName('a')[0];
console.log(link.matches('a'));//true
console.log(link.matches('.link'));//true
console.log(link.matches('#container a'));//true
console.log(link.matches('.message a'));//true
console.log(link.matches('a.message'));//false
}
createElement | Создает новый элемент с указанным тегом |
createTextNode | Создает новый текстовый узел с указанным текстом |
appendChild | Добавляет elem в конец дочерних элементов parentElem |
insertBefore | Вставляет elem в коллекцию детей parentElem, перед элементом nextSibling |
cloneNode | Клонирование узлов |
removeChild | Удаляет elem из списка детей parentElem |
replaceChild | Среди детей parentElem удаляет elem и вставляет на его место newElem |
function create(){
var div = document.createElement('div');
div.className = 'test';
div.id = 'test';
var container = document.querySelector('#container');
container.appendChild(div);
}
function clone(){
var title = document.querySelector('.title');
console.log(title.cloneNode());
console.log(title.cloneNode(true));
}
function replace() {
var title = document.querySelector('.title'),
h3 = title.firstElementChild;
var div = document.createElement('div');
div.className = 'test';
div.id = 'test';
div.innerHTML = 'Test';
title.replaceChild(div, h3);
console.log(title);
}
Событию можно назначить обработчик, то есть функцию, которая сработает, как только событие произошло. Именно благодаря обработчикам JavaScript-код может реагировать на действия посетителя
Существует несколько способов назначения обработчика события
Click me to change my text color
function setColor() {
document.getElementById("text").style.color = "red";
}
Внутри обработчика события this ссылается на текущий элемент, то есть на тот, на котором он сработал. Это можно использовать, чтобы получить свойства или изменить элемент
//Нажми
element.addEventListener(event, handler[, phase]);
elem.addEventListener( "click" , function() {
console.log('Thank you!');
});
function thanks(){
console.log('Thank you!');
}
elem.addEventListener( "click" , thanks);
<input id="elem" type="button" value="Нажми"/>
<script>
function handler1() {
alert('Спасибо!');
};
function handler2() {
alert('Спасибо ещё раз!');
}
elem.onclick = function() { alert("Привет"); };
elem.addEventListener("click", handler1); //Спасибо!
elem.addEventListener("click", handler2); //Спасибо ещё раз!
</script>
Передается таже функция-обработчик, которая была назначена на событие
//передать те же аргументы, что были у addEventListener
element.removeEventListener(event, handler[, phase]);
elem.addEventListener( "click" , function() {alert('Спасибо!')});
//....не сработает
elem.removeEventListener( "click", function() {alert('Спасибо!')});
function handler() {
alert( 'Спасибо!' );
}
input.addEventListener("click", handler);
//....
input.removeEventListener("click", handler);
event = new Event(typeArg, eventInit);
var ev = new Event("look", {"bubbles":true, "cancelable":false});
document.dispatchEvent(ev);
cancelled = !target.dispatchEvent(event)
//event - объект события, который инициализируется
//target - используется для инициализации Event.target
//и установки события, которое обработчик вызывает
//return - false если хотя бы один из обработчиков
//этого события вызовал preventDefault
<button id="elem" onclick="alert('Клик');">Автоклик</button>
<script>
var event = new Event("click");
elem.dispatchEvent(event);
</script>
Идентичен Event(), НО у второго аргумента-объекта есть дополнительное свойство detail, в котором можно указывать дополнительную информацию
<h1 id="elem">Element</h1>
<script>
var elem = document.getElementById('elem');
elem.addEventListener("hello", function(event) {
console.log( event.detail.name );
}, false);
var event = new CustomEvent("hello", {
detail: { name: "something" }
});
elem.dispatchEvent(event);
</script>
type | тип события |
currentTarget | элемент, на котором сработал обработчик |
target | целевой элемент (там, где произошло событие) |
bubbles | является ли данное событие всплывающим |
cancelable | является ли событие отменяемым |
isTrusted | было ли событие инициировано действиями пользователя |
preventDefault() | останавливает событие (если оно cancelable) без остановки всплытия |
stopImmediatePropagation() | останавливает цепочку вызова событий для последующих слушателей DOM элемента и текущих событий |
stopPropagation() | останавливает цепочку вызова событий для последующих слушателей DOM элемента (на текущем элементе все обработчики отработают) |
click | нажатие на элемент левой кнопкой мыши |
dblclick | двойное нажатие на элемент левой кнопкой мыши |
contextmenu | нажатие на элемент правой кнопкой мыши |
mouseover | при наведении мыши на элемент |
mousedown | при нажатии мышью на элемент |
mouseup | при отжатии мыши на элементе |
mousemove | при движении мыши |
onwheel | при передвижении колеса мыши над элементом |
DOMContentLoaded | HTML загружен и обработан, DOM полностью построена и доступна |
load | браузер загрузил все ресурсы |
beforeunload/unload | при уходе со страницы |
resize | браузер изменил размеры окна |
error | при запуске/загрузке ресурса происходит ошибка |
<script>
function ready() {
console.log( 'DOM готов' );
console.log( "Размеры картинки: "
+ img.offsetWidth + "x"
+ img.offsetHeight );
//не дожидаемся загрузки картинки ( 0x0 )
}
document.addEventListener("DOMContentLoaded", ready);
</script>
<img id="img" src="/logos/doodles/2016/holidays-2016-2748273943.gif">
<script>
window.onload = function() {
console.log('Документ и все ресурсы загружены');
};
</script>
<iframe src="https://example.com/" style="height:60px"></iframe>
<script src="index.js"></script>
keyup | отпускание клавиши |
keydown | нажатие клавиши |
keypress | приводит к появлению символа |
//event.type должен быть keypress
function getChar(event) {
if (event.which == null) { //IE
if (event.keyCode < 32) return null; //спец. символ
return String.fromCharCode(event.keyCode)
}
if (event.which != 0 && event.charCode != 0) { //все кроме IE
if (event.which < 32) return null; //спец. символ
return String.fromCharCode(event.which); //остальные
}
return null; //спец. символ
}
//Код символа хранится в свойствах: charCode и which.
//Не совместимость
blur | при потере элементов фокуса |
change | по окончании изменении значения элемента формы |
focus | при получении элементов фокуса |
invalid | при получении элементом статуса invalid |
select | при выборе пользователем элемента |
submit | при отправке формы на сервер |
input | срабатывает тут же при изменении значения текстового элемента |
Для текстовых элементов означает, что событие произойдёт не при каждом вводе, а при потере фокуса
copy | копирование значения |
paste | вставки значения |
cut | вырезании значения |
clipboardData использует объект dataTransfer
void dataTransfer.setData(format, data);
//text/plain
//text/uri-list
//text/html
DataTransfer.clearData([format]);
void dataTransfer.setData(format, data);
DOMString dataTransfer.getData(format);
<input type="text" id="text">
<script>
function onCopy(e) {
e.clipboardData.setData('text/plain', 'Something');
}
document.getElementById('text').addEventListener('copy', onKeyUp);
</script>
drag | при перетаскивании элемента |
dragstart | когда элемент начинает перемещаться |
dragenter | когда перемещаемый элемент попадает на элемент-назначение |
drop | после отпускания элемента |
DataTransfer | объект используется для хранения данных, перетаскиваемых мышью во время операции drag and drop |
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<img id="drag1" src="img.gif" draggable="true" ondragstart="drag(event)">
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
onpause | медиа-объект приостанавливает выполнение программно или в ответ на действие пользователя |
play | медиа-объект готов к началу выполнению |
playing | медиа-объект выполняется |
progress | возникает при изменении состояния получения данных медиа-объектом |
volumechange | возникает при изменении уровня громкости |
<video id="myVideo" width="320" height="176" controls>
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<script>
var vid = document.getElementById("myVideo");
vid.onpause = function() {
alert("The video has been paused");
};
</script>
<video controls id="myVideo">
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<script>
document.getElementById("myVideo").addEventListener("volumechange", myFunction);
function myFunction(e) {
alert(e.target.volume);//[0-1]
alert("The volume has been changed!");
}
</script>
transitionend | при завершении CSS-анимации |
/*
* Прослушиваем событие transitionend на определенном элементе,
* Затем, вызваем определенную функцию (showMessage)
*/
function showMessage() {
alert('Transition закончил свое выполнение');
}
var element = document.getElementById("slidingMenu");
element.addEventListener("transitionend", showMessage, false);
//Без пространства имен
function Person() {}
function Student() {}
var some_var = 1;
var module1 = {};
module1.data = {a: 1, b: 2};
var module2 = {};
var MYAPP = {};
MYAPP.Person = function () {};
MYAPP.Student = function () {};
MYAPP.some_var1 = 1;
MYAPP.some_var2 = 2;
MYAPP.modules = {};
MYAPP.modules.modulel = {};
MYAPP.modules.modulel.data = {
a: 1,
b: 2
};
MYAPP.modules.module2 = {};
//применение функции пространства имен
MYAPP.namespace('MYAPP.modules.module2');
//вызов эквивалентен следующей конструкции:
var MYAPP = {
modules: {
module2: {}
}
};
var MYAPP = MYAPP || {};
MYAPP.namespace = function (namespaceStr) {
var parts = namespaceStr.split('.'),
parent = MYAPP,
i;
//отбросить начальный префикс - имя глобального объекта
if (parts[0] === "MYAPP") {
parts = parts.slice(1);
}
for (i = 0; i < parts.length; i += 1) {
//создать свойство, если оно отсутствует
if (typeof parent[parts[i]] === "undefined") {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
};
//присваиваение возвращаемого значение локальной переменной
var module2 = MYAPP.namespace('MYAPP.modules.module2');
module2 === MYAPP.modules.module2; //true
//отсутствие начального префикса 'MYAPP'
MYAPP.namespace('modules.module51');
//создание глубоко вложенных пространств имен
MYAPP.namespace('very.long.nested.property');
;(function () {
//приватные переменные
var version = '0.0.1',
faculties = ['EEF', 'ITF'];
//приватные функции
function Student(name) {
this.name = name;
}
function addStudent(student) {}
function assignStudentToFaculty(student, faculty) {}
//основная функция библиотеки
function bstu(params) {}
//публичные переменные и функции
bstu.Student = Student;
bstu.FACULTY = faculties;
//экспортируем публичные члены наружу из модуля
window.BSTU = bstu;
}());
var student = new BSTU.Student('Max');
console.log(student.name);//Max
Javascript работает в одном потоке
function f(b) {
var a = 12;
return a + b + 35;
}
function g(x) {
var m = 4;
return f(m * x);
}
g(21);
Объекты размещаются в куче. Куча — это ссылка на определённую неструктурированную области памяти
Очередь событий — это список событий, подлежащих обработке
while(queue.waitForMessage()){
queue.processNextMessage();
}
Задержка – это минимальное время, которое требуется среде выполнения на обработку запроса
Если событие обрабатывается слишком долго, то приложение в это время не имеет возможности обработать действия пользователя (например, скролл, или клик). Internet Explorer, в таком случае, выводит сообщение "A script on this page is causing Internet Explorer to run slowly"
Таймеры - это не sleep(), они создают события, которые используют Event Loop
var timeMark = new Date;
setTimeout(function go() {
//выполнится через 100 мс
var diff = new Date - timeMark;
console.log(diff);
timeMark = new Date;
setTimeout(go, 100); //снова в очередь
}, 100); //положили go() в очередь через 100 мс
//101
//100
//102
//101
//103
//100
$.get('/api/data.json', function(data) {
getFile(data.filename, function() {
alert('tada!');
});
showLoading('reading file');
});
showLoading('loading data');
$.get('/api/data.json', function(data) {//выполняется
getFile(data.filename, function() {
alert('tada!');
});
showLoading('reading file');
});
showLoading('loading data');//выполняется
$.get('/api/data.json', function(data) {
getFile(data.filename, function() {//выполняется
alert('tada!');
});
showLoading('reading file');//выполняется
});
showLoading('loading data');
$.get('/api/data.json', function(data) {
getFile(data.filename, function() {
alert('tada!');//выполняется
});
showLoading('reading file');
});
showLoading('loading data')
+ | - |
---|---|
отсутствие состояния "гонки" | процессороемкие задачи блокируют работу event loop |
веб-приложения не тратят время на ожидание ввода-вывода | выполняется на 1 ядре, а остальные ядра простаивают |
относительно проста для освоения | утечки памяти |
var worker = new Worker('task.js');//инициализация
worker.postMessage(); //запуск
worker.postMessage('Hello World');//отправление сообщения воркеру
worker.terminate()//завершение работы
//или
this.close()//внутри объекта
Основной скрипт main.js
var commandStop = 'Stop';
var worker = new Worker("worker.js");
worker.addEventListener('message', function(e) {
console.log('Worker said: ', e.data);
if(e.data === commandStop){
worker.terminate();
}
}, false);
worker.postMessage('Hello World');
Второй скрипт worker.js
var self = this;
self.addEventListener('message', function(e) {
console.log('Main said: ', e.data);
}, false);
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
};
setInterval(function(){
var number = getRandomInt(0, 10);
if(number === 5){
self.postMessage('Stop');
//self.close();
}else{
self.postMessage(number);
}
}, 1000);
Main said: Hello World
Worker said: 8
Worker said: 0
Worker said: 1
Worker said: 7
Worker said: Stop
Воркеры, которые могут использоваться несколькими скриптами совместно, работающими в разных окнах, IFrames и т.д. в пределах одного домена, что и воркер. Они должны связываться через активный порт (MessagePort)
var worker = new SharedWorker("worker.js");
worker.port.start();//вызывается в главном потоке
this.port.start();//вызывается в рабочем потоке
worker.port.postMessage('Hello World');
//отправление сообщения воркеру
this.port.postMessage('Hello World');
//отправление сообщения основному потоку
worker.port.close()//завершение работы
//или
this.port.close()//внутри объекта
Основной скрипт main.js
var commandStop = 'Stop';
var worker = new SharedWorker("worker.js");
worker.port.addEventListener('message', function(e) {
console.log('Worker said: ', e.data);
if(e.data === commandStop){
worker.port.close();
}
}, false);
worker.port.start();
worker.port.postMessage('Hello world');
Второй скрипт worker.js
var self = this, port = null;
self.addEventListener("connect", function (e) {
port = e.ports[0];
port.addEventListener('message', function (e) {
console.log('Main said: ', e.data);
}, false);
setInterval(sendMessage, 1000);
});
function sendMessage() {
var number = getRandomInt(0, 10);
if (number === 5) {
port.postMessage('Stop');
//port.close();
} else {
port.postMessage(number);
}
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
};
Worker said: 2
Worker said: 4
Worker said: 2
Worker said: 9
Worker said: 3
Worker said: 0
Worker said: 7
Worker said: Stop