JavaScript заметки
8.56K subscribers
2.75K photos
4 videos
1.27K links
Регулярные заметки по практическому JavaScript. Обучащию посты позволят прокачать навыки во Frontend-разработке.

Можно почитать пока компилируется проект :)

Сотрудничество: @noname_media

Канал на бирже: telega.in/channels/notesjs/card?r=Wj7h1mbl
Download Telegram
Метрики для не показываемых элементов равны нулю.

Координаты и размеры в JavaScript устанавливаются только для видимых элементов.

Если элемент (или любой его родитель) имеет display:none или отсутствует в документе, то все его метрики равны нулю (или null, если это offsetParent).

Например, свойство offsetParent равно null, а offsetWidth и offsetHeight равны 0, когда мы создали элемент, но ещё не вставили его в документ, или если у элемента (или у его родителя) display:none.

Мы можем использовать это, чтобы делать проверку на видимость.

Заметим, что функция isHidden также вернёт true для элементов, которые в принципе показываются, но их размеры равны нулю (например, пустые <div>).

#браузер #документ #размеры
👍4🔥1
clientTop/Left

Пойдём дальше. Внутри элемента у нас рамки (border).

Для них есть свойства-метрики clientTop и clientLeft.

В нашем примере:
- clientLeft = 25 – ширина левой рамки
- clientTop = 25 – ширина верхней рамки

Но на самом деле эти свойства – вовсе не ширины рамок, а отступы внутренней части элемента от внешней.

#браузер #документ #размеры
🔥1
scrollWidth/Height

Эти свойства – как clientWidth/clientHeight, но также включают в себя прокрученную (которую не видно) часть элемента.

На рисунке выше:
- scrollHeight = 723 – полная внутренняя высота, включая прокрученную область.
- scrollWidth = 324 – полная внутренняя ширина, в данном случае прокрутки нет, поэтому она равна clientWidth.

Эти свойства можно использовать, чтобы «распахнуть» элемент на всю ширину/высоту.

#браузер #документ #размеры
👍1🔥1
matches

Предыдущие методы искали по DOM.

Метод elem.matches(css) ничего не ищет, а проверяет, удовлетворяет ли elem CSS-селектору, и возвращает true или false.

Этот метод удобен, когда мы перебираем элементы (например, в массиве или в чём-то подобном) и пытаемся выбрать те из них, которые нас интересуют.

#браузер #документ #поиск
👍3🔥31
closest

Предки элемента – родитель, родитель родителя, его родитель и так далее. Вместе они образуют цепочку иерархии от элемента до вершины.

Метод elem.closest(css) ищет ближайшего предка, который соответствует CSS-селектору. Сам элемент также включается в поиск.

Другими словами, метод closest поднимается вверх от элемента и проверяет каждого из родителей. Если он соответствует селектору, поиск прекращается. Метод возвращает либо предка, либо null, если такой элемент не найден.

#браузер #документ #поиск
👍5🔥3
getElementsBy*

Существуют также другие методы поиска элементов по тегу, классу и так далее.

На данный момент, они скорее исторические, так как querySelector более чем эффективен.

Здесь мы рассмотрим их для полноты картины, также вы можете встретить их в старом коде.

elem.getElementsByTagName(tag) - ищет элементы с данным тегом и возвращает их коллекцию. Передав "*" вместо тега, можно получить всех потомков.

elem.getElementsByClassName(className) - возвращает элементы, которые имеют данный CSS-класс.

document.getElementsByName(name) - возвращает элементы с заданным атрибутом name. Очень редко используется.

P.S. На картинке пример поиска всех input в таблице.

#браузер #документ #поиск
👍3🔥1
Живые коллекции

Все методы "getElementsBy*" возвращают живую коллекцию. Такие коллекции всегда отражают текущее состояние документа и автоматически обновляются при его изменении.

В приведённом выше примере есть два скрипта.
- Первый создаёт ссылку на коллекцию <div>. На этот момент её длина равна 1.
- Второй скрипт запускается после того, как браузер встречает ещё один <div>, теперь её длина – 2.

#браузер #документ #поиск
👍4🔥2
Статические коллекции

querySelectorAll возвращает статическую коллекцию. Это похоже на фиксированный массив элементов.

Если мы будем использовать его в примере выше, то оба скрипта вернут длину коллекции, равную 1.

Теперь мы легко видим разницу. Длина статической коллекции не изменилась после появления нового div в документе, в отличие от живой коллекции.

#браузер #документ #поиск
👍3🔥1
Итого по поиску в DOM

Есть 6 основных методов поиска элементов в DOM (см. изображение выше).

Безусловно, наиболее часто используемыми в настоящее время являются методы querySelector и querySelectorAll, но и методы getElement(s)By* могут быть полезны в отдельных случаях, а также встречаются в старом коде.

Кроме того:
- Есть метод elem.matches(css), который проверяет, удовлетворяет ли элемент CSS-селектору.
- Метод elem.closest(css) ищет ближайшего по иерархии предка, соответствующему данному CSS-селектору. Сам элемент также включён в поиск.

И, напоследок, давайте упомянем ещё один метод, который проверяет наличие отношений между предком и потомком:
- elemA.contains(elemB) вернёт true, если elemB находится внутри elemA (elemB потомок elemA) или когда elemA==elemB.

#браузер #документ #поиск
👍8
Классы DOM-узлов

У разных DOM-узлов могут быть разные свойства. Например, у узла, соответствующего тегу <a>, есть свойства, связанные со ссылками, а у соответствующего тегу <input> – свойства, связанные с полем ввода и т.д. Текстовые узлы отличаются от узлов-элементов. Но у них есть общие свойства и методы, потому что все классы DOM-узлов образуют единую иерархию.

Каждый DOM-узел принадлежит соответствующему встроенному классу.

Корнем иерархии является EventTarget, от него наследует Node и остальные DOM-узлы.

На рисунке выше изображены основные классы.

#браузер #документ #свойства_узлов
👍5🔥1
EventTarget – это корневой «абстрактный» класс. Объекты этого класса никогда не создаются. Он служит основой, благодаря которой все DOM-узлы поддерживают так называемые «события», о которых мы поговорим позже.

P.S. На картинке описание интерфейса на TypeScipt.

#браузер #документ #свойства_узлов
👍8
Node – также является «абстрактным» классом, и служит основой для DOM-узлов. Он обеспечивает базовую функциональность: parentNodenextSiblingchildNodes и т.д. (это геттеры). Объекты класса Node никогда не создаются. Но есть определённые классы узлов, которые наследуют от него: Text – для текстовых узлов, Element – для узлов-элементов и более экзотический Comment – для узлов-комментариев.

#браузер #документ #свойства_узлов
👍2🔥1
Element – это базовый класс для DOM-элементов. Он обеспечивает навигацию на уровне элементов: nextElementSiblingchildren и методы поиска: getElementsByTagNamequerySelector. Браузер поддерживает не только HTML, но также XML и SVG. Класс Element служит базой для следующих классов: SVGElementXMLElement и HTMLElement.

#браузер #документ #свойства_узлов
👍3
HTMLElement – является базовым классом для всех остальных HTML-элементов.

От него наследуют конкретные элементы:
- HTMLInputElement – класс для тега <input>,
- HTMLBodyElement – класс для тега <body>,
- HTMLAnchorElement – класс для тега <a>,
…и т.д, каждому тегу соответствует свой класс, который предоставляет определённые свойства и методы.

#браузер #документ #свойства_узлов
👍4🔥2
Как узнать имя класса DOM-узла?

Есть 2 способа сделать это:
- вспомним, что обычно у объекта есть свойство constructor. Оно ссылается на конструктор класса, и в свойстве constructor.name содержится его имя
- мы можем просто привести его к строке

Например, для тега <body> JavaScript-класс HTMLBodyElement.

#браузер #документ #свойства_узлов
👍4🔥1
Наследование классов DOM-узлов

Проверить наследование можно также при помощи instanceof.

Как видно, DOM-узлы – это обычные JavaScript объекты. Для наследования они используют классы, основанные на прототипах.

В этом легко убедиться, если вывести в консоли браузера любой элемент через console.dir(elem). Или даже напрямую обратиться к методам, которые хранятся в HTMLElement.prototypeElement.prototype и т.д.

#браузер #документ #свойства_узлов
👍4
Свойство «nodeType»

Свойство nodeType предоставляет ещё один, «старомодный» способ узнать «тип» DOM-узла.

Его значением является цифра:
- elem.nodeType == 1 для узлов-элементов,
- elem.nodeType == 3 для текстовых узлов,
- elem.nodeType == 9 для объектов документа,
- В спецификации можно посмотреть остальные значения.

В современных скриптах, чтобы узнать тип узла, мы можем использовать метод instanceof и другие способы проверить класс, но иногда nodeType проще использовать. Мы не можем изменить значение nodeType, только прочитать его.

P.S. Пример с nodeType на картинке выше.

#браузер #документ #свойства_узлов
👍4
Тег: nodeName и tagName

Получив DOM-узел, мы можем узнать имя его тега из свойств nodeName и tagName.

Есть ли какая-то разница между tagName и nodeName?

Да, она отражена в названиях свойств, но не очевидна.

- Свойство tagName есть только у элементов Element.
- Свойство nodeName определено для любых узлов Node:
- - для элементов оно равно tagName.
- - для остальных типов узлов (текст, комментарий и т.д.) оно содержит строку с типом узла.

Другими словами, свойство tagName есть только у узлов-элементов (поскольку они происходят от класса Element), а nodeName может что-то сказать о других типах узлов.

Например, сравним tagName и nodeName на примере объекта document и узла-комментария (см. картинку выше).

#браузер #документ #свойства_узлов
👍7
Имена тегов (кроме XHTML) всегда пишутся в верхнем регистре

В браузере существуют два режима обработки документа: HTML и XML. HTML-режим обычно используется для веб-страниц. XML-режим включается, если браузер получает XML-документ с заголовком: Content-Type: application/xml+xhtml.

В HTML-режиме значения tagName/nodeName всегда записаны в верхнем регистре. Будет выведено BODY вне зависимости от того, как записан тег в HTML <body> или <BoDy>.

В XML-режиме регистр сохраняется «как есть». В настоящее время XML-режим применяется редко.

#браузер #документ #свойства_узлов
👍5🔥1
innerHTML: содержимое элемента

Свойство innerHTML позволяет получить HTML-содержимое элемента в виде строки.

Мы также можем изменять его. Это один из самых мощных способов менять содержимое на странице.

Пример выше показывает содержимое document.body, а затем полностью заменяет его.

#браузер #документ #свойства_узлов
👍7