DOM
Document Object Model или объектная модель документа — способ представления разметки страницы в виде связанных между собой объектов.
Каждому элементу на странице — тегу, текстовому блоку, комментарию — в JS ставится в соответствие объект. Каждый из объектов знает про свой родительский объект, соседние объекты и объекты, расположенные внутри него (дочерние элементы).
В каждом DOM-дереве есть корневой объект, из которого «растут» все остальные объекты, он называется document. Этот глобальный объект доступен во всех программах, которые работают в браузере. document — это страница, которая содержит все элементы разметки (объекты).
DOM-дерево состоит из:
Дерево может иметь только один корень. У каждого элемента должно быть не более одного родителя
Виды обхода деревьев:
Родительские элементы
Возвращает родителя узла DOM Element, или null если узел не имеет родителя, или его родитель не DOM Element.
parentElement = node.parentElement; // parentElement — родительский элемент текущего узла
ParentNode
Возвращает родителя определенного элемента DOM дерева.
parentNode = node.parentNode; // parentNode — родитель текущего элемента
Соседние элементы
Возвращает элемент стоящий перед применяемым, из списка дочерних элементов родителя или возвращает null, если таковых не имеется.
prevNode = elementNodeReference.previousElementSibling;
PreviousSibling
Возвращает узел предшедствующий указанному в родительском элементе childNodes, или null, если указанный узел первый в своём родителе.
previousNode = node.previousSibling;
NextElementSibling
Возвращает последующий элемент перед текущим, или null, если элемент является последним в своём родительском узле.
var nextNode = elementNodeReference.nextElementSibling;
NextSibling
Возвращает узел, непосредственно следующий за данным узлом в списке childNodes его родительского элемента, или null если данный узел последний в этом списке.
nextNode = node.nextSibling;
Внутренние элементы
Возвращает динамическую коллекцию HTMLCollection дочерних элементов узла. Структура данных, в которой хранятся дети children очень похожа на массив — у неё есть индексы и поле length.
// elList – живая коллекция, состоящая из дочерних элементов узла elementNodeReferencevar
elList = elementNodeReference.children;
ChildNodes
// ndList – упорядоченная коллекция объектов элементов, которые являются детьми данного элемента.
var ndList = elementNodeReference.childNodes;
Contains
Указывает, является ли узел потомком данного узла.
node.contains( otherNode )
Возвращает true если otherNode является потомком node, или непосредственно самим node. В противном случае возвращает false.
Имя элемента
Возвращает HTML-тег элемента (“div”, “p”, “a” и т.д).
// elementName это строка, содержащая название HTML-тега элемента element.
var elementName = element.tagName;
NodeName
Возвращает имя текущего узла в виде строки.
var str = node.nodeName;
Поиск элементов в DOM
Возвращает ссылку на элемент по его идентификатору (ID); может быть вызван только на всём документе; идентификатор является строкой, которая может быть использована для идентификации элемента; она может быть определена при помощи
атрибута id в HTML или из скрипта.
element = document.getElementById(id);
QuerySelector()
Принимает любой CSS-селектор и возвращает первый элемент внутри документа (используется предупорядоченный обход узлов в глубину до первого найденного узла), который совпадает с определенной группой
селекторов.
// Поиск элемента по тегу
var list = document.querySelector(‘ul’);
// Поиск последнего элемента из списка
var lastProduct = document.querySelector(‘li:last-child’);
// Поиск элемента по классу
var price = document.querySelector(‘.price’);
// Поиск третьего элемента из списка товаров
var thirdProduct = document.querySelector(‘.product:nth-child
‘);
QuerySelectorAll()
Принимает любой CSS-селектор и возвращает статичную коллекцию списка элементов (поиск осуществляется в пределах указанного элемента), которые соответствуют указанной группе селекторов. Возвращает объект
типа NodeList, содержащий все найденные элементы в том порядке, в котором они находятся в документе.
// Поиск всех элементов, подходящих по селектору
var listItems = document.querySelectorAll(‘.product’);
Коллекция элементов DOM-дерева является живой коллекцией, т.е. любое изменение в DOM сразу же изменяет эту коллекцию.
ActiveElement
Возвращает текущий сфокусированный элемент, то есть элемент, на котором будут вызываться события клавиатуры, если пользователь начнёт с неё ввод. Этот атрибут доступен только для чтения.
var curElement = document.activeElement;
Атрибуты DOM-элемента
Большинство HTML-атрибутов доступны в виде свойств DOM-элемента, и к ним можно обращаться напрямую. Исключения составляют те
атрибуты, названия которых являются ключевыми или зарезервированными для будущих версий словами JS, например class или for у лейблов. Чтобы обратиться к классу, нужно воспользоваться свойством className, а чтобы
прочитать лейбл, нужно воспользоваться свойством htmlFor.
Style
// Устанавливает несколько стилей в одном выражении
elt.style.cssText = “color: blue; border: 1px solid black”;
// Или
elt.setAttribute(“style”, “color:red; border: 1px solid blue;”);
// Устанавливает определенный стиль оставляя другие значения стиля нетронутыми
elt.style.color = “blue”;
ClassName
Отвечает за значение атрибута class элемента.
var pageHeading = document.querySelector(‘h1’);
pageHeading.className = ‘myclass’;
GetAttribute()
Возвращает значение указанного атрибута элемента.
var pageHeading = document.querySelector(‘h1’);
console.log(pageHeading.getAttribute(‘class’)); // Вернет название класса pageHeading
SetAttribute()
Добавляет новый атрибут или изменяет значение существующего атрибута у выбранного элемента.
var pageHeading = document.querySelector(‘h1’);
pageHeading.setAttribute(‘style’, ‘background: red;’);
ClassList
Специальный объект для работы с классами. Возвращает псевдомассив, содержащий все классы элемента.
var product = document.querySelector(‘.product’); // Когда ищем элемент по классу, используем точку
product.classList.add(‘product–sale’); // Но когда добавляем класс, точки нет!
var popup = document.querySelector(‘.popup’); // Перед названием селектора ставим точку
popup.classList.remove(‘popup–open’); // Перед названием класса точка не ставится
Содержимое DOM-элемента
Позволяет задавать или получать текстовое содержимое элемента и его потомков.
var text = element.textContent;
element.textContent = “Это просто текст”;
InnerHTML
Устанавливает или получает разметку дочерних элементов. Позволяет создавать новые элементы на странице. Все элементы удаляются и создаются вновь каждый раз, когда мы вставляем новую разметку.
element.innerHTML = content;
В случае с .innerHTML браузер будет рисовать текст как HTML разметку. В то время как .textContent вставляет текст как есть.
InsertAdjacentHTML()
Разбирает указанный текст как HTML или XML и вставляет полученные узлы (nodes) в DOM дерево в указанную позицию (точечно). Данная функция не переписывает имеющиеся элементы, что предовращает дополнительную сериализацию и поэтому работает
быстрее, чем манипуляции с innerHTML.
position указывает положение element, и может принимать одно из следующих значений:
text — строка, которая будет проанализирована как HTML или XML и вставлена в DOM дерево документа.
InsertAdjacentText()
Помещает заданный текстовый узел в указанную позицию относительно элемента, который передан в вызове метода.
position — позиция для вставки текста относительно элемента element. Указывается по аналогии с .insertAdjacentHTML().
text — текст, который будет помещен в заданную позицию.
CreateElement()
Принимает на вход строку с именем тега и возвращает созданный DOM-элемент. Созданный элемент по умолчанию не находится в DOM-дереве и не отображается на странице.
RemoveChild
Удаляет дочерний элемент из DOM. Возвращает удаленный элемент.
var oldChild = element.removeChild(child);
element.removeChild(child);
Удаленный дочерний элемент остается в памяти, но больше не является частью DOM. Вы можете повторно использовать удаленный элемент с помощью ссылки на объект – oldChild.
Remove()
Удаляет узел из дерева DOM.
То, что элемент удален из DOM, еще не значит, что он удален совсем! Он остался объектом и исчезнет только тогда, когда исчезнут все ссылки на него.
Node – любой узел DOM
AppendChild()
Добавляет элемент в конец списка дочерних элементов родителя. Если элемент уже существует он удаляется из текущего родителя и вставляется заново. Возвращает ссылку на добавленный узел(элемент).
var list = document.querySelector(‘.cards’);
var card = document.createElement(‘li’); // Создаём новый элемент
card.classList.add(‘card’);
list.appendChild(card); // После вызова этого метода новый элемент отрисуется на странице
InsertBefore()
Добавляет элемент в список дочерних элементов родителя перед указанным элементом. Если вторым параметром передать null, то добавляемый элемент встанет в конец блока.
var insertedElement = parentElement.insertBefore(newElement, referenceElement);
ReplaceChild
Заменяет дочерний элемент на выбранный. Возвращает замененный элемент.
replacedNode = parentNode.replaceChild(newChild, oldChild);
CompareDocumentPosition
Сравнивает позицию текущего узла и другого узла в любом другом документе.
Возвращаемое значение (битовая маска) вычисляется как отношение, которое имеется между otherNode и node.
Шаблонизация
Создает новый пустой DocumentFragment. Позволяет сгруппировать однотипные или разнотипные элементы и вставить их все вместе.
var fragment = document.createDocumentFragment();
fragment это ссылка на пустой объект DocumentFragment.
CloneNode
Возвращает дубликат узла, из которого этот метод был вызван.
var dupNode = node.cloneNode(deep);
var p = document.getElementById(“para1”);
var p_prime = p.cloneNode(true);
<template>
Позволяет создавать элементы на основе шаблона, копировать структуру и заполнять её необходимыми данными. Имеет свойство content, которое хранит элемент DocumentFragment всего содержимого.
// Находим элемент для вставки в него копии шаблона
var div = document.querySelector(‘.div’);
// Создаем элемент из шаблона
var template = document.querySelector(‘#element-template’).content.querySelector(‘div’);
// Клонируем шаблон с вложенным содержимым
var element = template.cloneNode(true);
// Вставляем склонированный шаблон
div.appendChild(element);
События
События — это механизм, который позволяет описать реакцию на определённые асинхронные действия пользователя или браузера. Например, ввод данных пользователем, окончание загрузки или наступление ошибки.
Всплытие и перехват
Существует три стадии прохода события:
То есть, при клике событие путешествует по цепочке родителей сначала вниз к элементу («погружается»), а потом наверх («всплывает»), по пути задействуя обработчики.
В современных браузерах по умолчанию все обработчики событий регистрируются в фазе всплытия.
Всплывают почти все события. Например, события focus, blur, invalid не всплывают.
Event. stopPropagation()
Прекращает дальнейшую передачу (всплытие) текущего события. Event.stopPropagation() препятствует продвижению события дальше, но на текущем элементе все обработчики отработают.
Event. eventPhase
Отображает текущую фазу процесса обработки события (погружение = 1, всплытие = 3).
Делегирование
Заключается в том, что если у нас есть много элементов, события на которых нужно обрабатывать похожим образом, то вместо того, чтобы назначать обработчик каждому – мы ставим один обработчик на их общего предка. Из него можно получить
целевой элемент event.target, понять на каком именно потомке произошло событие и обработать его.
Представляет собой любое событие, которое происходит в DOM; некоторые из них генерируемые пользователем (клик мышью или нажатие клавиши на клавиатуре), а
некоторые – генерируемые API (события, обозначающие завершение процесса анимации, приостановка видео и т.д.). Существует много типов событий, некоторые из них используют интерфейсы, базирующиеся на главном интерфейсе Event. Содержит общие свойства и методы для всех событий.
Объект Event — также называемый объект события, параметр функции-обработчика. Он всегда передаётся браузером в функцию .addEventListener() в момент наступления события.
Чтобы использовать Event, достаточно указать этот объект параметром функции-обработчика и написать инструкции. Принято называть параметр сокращённо — evt.
Сравнение разных Event Targets
Event. target
Ссылка на объект (элемент), который был инициатором события. Он может отличаться от event.currentTarget, если обработчик события вызывается во время всплытия (bubbling) или захвата события.
Event. currentTarget
Определяет элемент, в котором в данный момент обрабатывается событие, при движении события внутри DOM. Всегда совпадает с текущим элементом, в отличие от свойства event.target, идентифицируещее элемент, на котором событие
возникло.
Event.currentTarget === this
Event. preventDefault()
Отменяет действие элемента по умолчанию.
AddEventListener()
Регистрирует определенный обработчик события, вызванный на EventTarget. EventTarget должен быть либо существующим элементом в документе, либо Document, либо Window, либо любым другим объектом, который
поддерживает события. Обработчик события — это функция, которая будет запущена, когда наступит соответствующее событие.
button.addEventListener(“click”, function, true);
.addEventListener() принимает на вход три параметра:
Существует два способа именования обработчиков:
Стоит помнить разницу между обращением к функции и запуском ее кода. Для того, чтобы обратиться к функции, достаточно просто написать ее название. Если же за названием следуют круглые скобки — код функции выполнится немедленно, и в
качестве обработчика в .addEventListener() будет передан результат работы этой функции.
Функции, которые создаются в момент передачи и не имеют имени, называются анонимными функциями.
С помощью метода .addEventListener() можно регистрировать сколько угодно обработчиков одного и того же события на одном и том же элементе. Обе функции будут выполняться при щелчке элемента:
myElement.addEventListener(‘click’, functionA);
myElement.addEventListener(‘click’, functionB);
RemoveEventListener()
Удаляет обработчик события, который был зарегистрирован при помощи .addEventListener(). Обработчик определяется типом события, самой функцией обработки события, и дополнительными параметрами, переданными при регистрации
обработчика.
Анонимную функцию-обработчик удалить невозможно, чтобы корректно удалить обработчик, нужно обратиться к той же самой функции, которая была передана в качестве параметра в .addEventListener(). Это возможно только в том случае, если
функция была создана заранее и не является анонимной.
‘click’
Событие click срабатывает, когда кнопка указывающего устройства (например, основная кнопка мыши) одновременно нажата и отпущена, когда указатель находится внутри элемента. Т.е. когда произошло mousedown и затем mouseup.
KeyboardEvent
Объекты KeyboardEvent описывают работу пользователя с клавиатурой. Каждое событие описывает клавишу; тип события (keydown, keypress или keyup) определяет произведённый тип действия.
Событие «нажатие на клавишу» носит название — ‘keydown’. Такое событие срабатывает при нажатии на любую клавишу.
Слушать это событие можно только на элементах, которые имеют состояние фокуса: поля ввода, кнопки,
элементы с атрибутом tabindex, документ. При нажатии фокус должен находиться на соответствующем элементе.
Если необходимо поймать нажатие какой-то конкретной клавиши, можно обратиться к свойству keyCode объекта event. Это свойство содержит код нажатой клавиши.
В настоящий момент свойство keyCode устарело, вместо него стоит использовать KeyboardEvent.code.
Для встроенных активных элементов (input, button, a), не нужно описывать дополнительно поведение работы с клавиатурой, достаточно просто добавить обработчик события ‘click’.
Формы и валидация
Используется для создания интерактивных элементов управления в веб-формах для принятия данных от пользователя.
Value
Для получения текста из поля ввода нужно обратиться к свойству поля ввода value. Оно хранит информацию, введённую в поле.
// Находим input
var newItemTitle = newItemForm.querySelector(‘.add-form-input’);
// Сохраняем введенный текст
var taskText = newItemTitle.value;
‘change’
Если не нужно отправлять форму в каких-то случаях, отмените действие по умолчанию с помощью preventDefault.
‘invalid’
Событие ‘invalid’ запускается, когда отправляемый элемент был проверен, но его содержимое не удовлетворило установленные ограничения. Валидность отправляемого элемента проверяется до отправления формы или после вызова методаcheckValidity() на элементе.
‘input’
Представляет состояния достоверности, в которых может находиться элемент, относительно проверки ограничения. Вместе они помогают объяснить, почему значение элемента не проверяется, если оно недопустимо.
Возможные значения ValidityState:
Можно не только переопределять стандартное поведение валидации, а также расширять его и добавлять свои собственные обработчики форм.
SetCustomValidity()
Устанавливает специальное сообщение для выбранного элемента. Если элемент не имеет пользовательской ошибки в параметре укажите пустую строку.
Перемещение элемента
Позволяют использовать функции перетаскивания. Например, пользователь может выбрать перетаскиваемые элементы с помощью мыши, перетащить элементы в сбрасываемый элемент и отбросить эти элементы, отпустив кнопку мыши. Полупрозрачное представление перетаскиваемых элементов следует за указателем мыши во время операции перетаскивания.
Drag and drop (на русском)
HTML Drag and Drop API (на английском)
MouseEvent
Представляет собой событие, которое происходит в результате взаимодествия пользователя с манипулятором (например, мышью). Наиболее частые из таких событий: click, dblclick, mouseup, mousedown.
‘mousedown’
Событие mousedown срабатывает, когда кнопка указывающего устройства (к примеру, мыши) нажата над элементом.
‘mousemove’
Событие mousemove вызывается для элемента, когда указательное устройство (обычно мышь) перемещается, когда в нем находится курсор.
‘mouseup’
Событие mouseup вызывается у Element, когда кнопка указательного устройства (такого как мышь или трекпад) отпускается, когда указатель находится внутри него.
OffsetTop
Возвращает расстояние текущего элемента по отношению к верхней части узла.
topPos = element.offsetTop;
topPos – количество пикселей на которые делается отступ с верху, отсносительно родительского элемента.
OffsetLeft
Возвращает смещение в пикселях верхнего левого угла текущего элемента от родительского узла.
Прочее
Часть процесса программирования, во время которой разработчик пытается найти и устранить ошибки в программе.
JavaScript в браузере
Скрипты подключаются к странице с помощью тега script двумя способами:
Эти два способа не сочетаются друг с другом. Если у тега script указан атрибут src, инлайновый код игнорируется и не выполняется, поэтому он должен находиться в другом теге script.
Скрипты выполняются по мере подключения на страницу. Если за тегом script находится разметка, она не отрисуется пока не выполнится скрипт (в случае с инлайновым кодом) или пока он не скачается с внешнего ресурса и не будет выполнен
(при подключении внешнего файла).
Синхронное и асинхронное подключение скриптов:
Canvas
Тег предназначенный для отрисовки графики в браузере. Чтобы начать с ним работу, нужно добавить этот тег в разметку.
// DOM-элемент канваса
var canvas = document.getElementById(‘canvas’);
// Контекст отрисовки
var ctx = canvas.getContext(‘2d’);
FillRect
Отрисовывает закрашенный прямоугольник.
Первые два параметра задают координаты левого верхнего угла, третий и четвёртый — ширину и высоту объекта.
ctx.fillRect(0, 0, 300, 150);
FillStyle
Задает стиль заливки, вызывается перед отрисовкой фигуры.
Цвет заливки задается так же, как это делается в CSS — с помощью названия цвета, HEX-кода, rgb или rgba.
ctx.fillStyle = ‘blue’;
Последний заданный fillStyle будет применён ко всем вызовам fill (или к отрисовке заранее закрашенных фигур). Чтобы залить следующую фигуру другим цветом, нужно переопределить fillStyle.
ctx.fillStyle = ‘blue’;
ctx.fillRect(0, 0, 200, 150); // Закрасит синим
ctx.fillStyle = ‘lightgreen’;
ctx.fillRect(210, 40, 30, 30); // Закрасит светлозеленым
Для заливки фигуры градиентом в fillStyle нужно записать объект, полученный с помощью метода контекста ctx.createLinearGradient или ctx.createRadialGradient. Цвета градиентов задаются с помощью метода addColorStop у объекта градиента.
var gradient = ctx.createLinearGradient(0, 0, 300, 150);
gradient.addColorStop(0, ‘green’);
gradient.addColorStop(1, ‘rgba(0, 255, 0, 0)’);
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 300, 150);
Заливает отрисованный контур. Контур зальётся так, как это указано в свойстве fillStyle.
Существуют два способа заливки:
StrokeStyle
Задает стиль обводки фигуры.
ctx.strokeStyle = ‘blue’;
Рисует обводку контура фигур цветом strokeStyle.
ClearRect
Используется для очистки холста.
ctx.clearRect(0, 0, 300, 150);
Сложные фигуры
Сложные фигуры рисуются с помощью контуров. Контур — это описание формы фигуры, без заливки или обводки. Контуры описываются с помощью простых фигур, а потом управление, например, заливка или обводка, производится целиком над фигурами.
Начало контура задается методом beginPath, конец контура closePath, все, что будет нарисовано между этими вызовами, будет считаться одной фигурой.
ctx.beginPath(); // начало контура
ctx.moveTo(100, 100); // перемещает начальную точку нового фрагмента контура
ctx.lineTo(150, 100); // рисует линию из последней точки
ctx.bezierCurveTo(140, 90, 110, 90, 100, 100); //рисует кривую Безье
ctx.closePath(); //конец контура
ctx.stroke(); // рисует обводку
ctx.fill(); // заливает отрисованный контур
Работа с текстом
Вывод текста осуществляется одним из двух методов: fillText или strokeText, которые выводят, соответственно, залитый или обведённый текст.
ctx.fillText(‘Привет’, 0, 10); // выводит залитый текст
ctx.strokeText(‘Привет’, 0, 10); // выводит обведённый текст
Параметры текста задаются свойствами контекста font, textAlign и textBaseline.
ctx.font = ’30px Tahoma’;
ctx.textBaseline = ‘hanging’; // выравнивает текст
ctx.fillText(‘Текст’, 0, 10);
Особенность текстов на канвасе: они не переносятся.
Чтобы написать текст с переносами, нужно каждую новую строку вынести в отдельный вызов метода fillText (или strokeText). Можно автоматизировать этот процесс, написав функцию, разбивающую текст на строчки, если они не помещаются в
указанную
ширину.
Размеры
Размер канваса по умолчанию — 300×150px. Координатная сетка канваса изначально имеет такой же размер.
Если изменить размеры канваса, используя css, то изменятся внешние размеры блока, а координатная сетка останется прежней — 300×150px.
Чтобы изменить и размеры канваса и координатную сетку, нужно воспользоваться свойствами width и height DOM-элемента канваса.
Алгоритмы
Законченный и упорядоченный набор действий, которые нужно предпринять, чтобы достигнуть прогнозируемого результата
Модули
Обособленная часть программы (ограниченная в доступности к служебным переменным с помощью функций), которая может заменяться, использоваться повторно в разных местах программы (или даже в нескольких проектах). Или же часть программы, решающая узкий набор задач.
Области видимости в модулях:
Инкапсуляция
Изоляция служебных переменных, объектов, функций с целью сокрытия доступа и предотвращения возможности управления ими.
Экспорт
Возможность использовать части модуля в других модулях, для этого они должны быть доступны снаружи.
Порядок подключения модулей: сначала подключаются модули, которые не зависят от других модулей и только потом подключаются зависимые модули.
Чтобы воспользоваться значениями одного модуля из другого необходимо экспортировать их в глобальную область видимости window.
Затем, чтобы воспользоваться экспортированными значениями необходимо импортировать их из глобальной области видимости window.
Объекты для хранения значений именуются также как сам модуль. Если имя модуля состоит из нескольких слов, то они записываются через дефис, а объект в котором хранится экспортируемое значение записывается по правилам именования переменных — через camelCase.