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
Запретить прокрутку

Иногда нам нужно сделать документ «непрокручиваемым». Например, при показе большого диалогового окна над документом – чтобы посетитель мог прокручивать это окно, но не документ.

Чтобы запретить прокрутку страницы, достаточно установить document.body.style.overflow = "hidden".

Аналогичным образом мы можем «заморозить» прокрутку для других элементов, а не только для document.body.

Недостатком этого способа является то, что сама полоса прокрутки исчезает. Если она занимала некоторую ширину, то теперь эта ширина освободится, и содержимое страницы расширится, текст «прыгнет», заняв освободившееся место.

Это выглядит немного странно, но это можно обойти, если сравнить clientWidth до и после остановки, и если clientWidth увеличится (значит полоса прокрутки исчезла), то добавить padding в document.body вместо полосы прокрутки, чтобы оставить ширину содержимого прежней.

#браузер #документ #размеры
👍9
Element.getBoundingClientRect()

Метод Element.getBoundingClientRect() возвращает размер элемента и его позицию относительно viewport (часть страницы, показанная на экране, и которую мы видим).

Результатом является самый маленький прямоугольник, в котором содержится весь элемент с read-only lefttoprightbottomxywidth и height свойствами, описывающие это в пикселях. Все свойства, кроме width и height, являются относительными к верхнему левому углу viewport-а.

#браузер #документ #координаты
👍5
Зачем вообще нужны зависимые свойства? Для чего существуют top/left, если есть x/y?

С математической точки зрения, прямоугольник однозначно задаётся начальной точкой (x,y) и вектором направления (width,height).

Так что дополнительные зависимые свойства существуют лишь для удобства.

Что же касается top/left, то они на самом деле не всегда равны x/y. Технически, значения width/height могут быть отрицательными. Это позволяет задать «направленный» прямоугольник, например, для выделения мышью с отмеченным началом и концом.

То есть, отрицательные значения width/height означают, что прямоугольник «растет» влево-вверх из правого угла.

#браузер #документ #координаты
👍3
elementFromPoint(x, y)

Вызов document.elementFromPoint(x, y) возвращает самый глубоко вложенный элемент в окне, находящийся по координатам (x, y).

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

#браузер #документ #координаты
👍3
Применение для fixed позиционирования

Чаще всего нам нужны координаты для позиционирования чего-либо.

Чтобы показать что-то около нужного элемента, мы можем вызвать getBoundingClientRect, чтобы получить его координаты элемента, а затем использовать CSS-свойство position вместе с left/top (или right/bottom).

Например, функция createMessageUnder(elem, html) выше показывает сообщение под элементом elem.

#браузер #документ #координаты
👍3
Введение в браузерные события

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

Вот список самых часто используемых DOM-событий, пока просто для ознакомления:

События мыши:
click – происходит, когда кликнули на элемент левой кнопкой мыши.
contextmenu – происходит, когда кликнули на элемент правой кнопкой мыши.
mouseover / mouseout – когда мышь наводится на / покидает элемент.
mousedown / mouseup – когда нажали / отжали кнопку мыши на элементе.
mousemove – при движении мыши.

События на элементах управления:
submit – пользователь отправил форму <form>.
focus – пользователь фокусируется на элементе.

Клавиатурные события:
keydown и keyup – когда пользователь нажимает / отпускает клавишу.

События документа:
DOMContentLoaded – когда HTML загружен и обработан.

CSS events:
transitionend – когда CSS-анимация завершена.

Существует множество других событий. О них в следующих постах.

#браузер #документ #события
👍12🔥2
Обработчики событий

Событию можно назначить обработчик, то есть функцию, которая сработает, как только событие произошло.

Именно благодаря обработчикам JavaScript-код может реагировать на действия пользователя.

Есть несколько способов назначить событию обработчик. Мы их рассмотрим, начиная с самого простого.

#браузер #документ #события
👍3
Использование атрибута HTML

Обработчик может быть назначен прямо в разметке, в атрибуте, который называется on<событие>.

Например, чтобы назначить обработчик события click на элементе input, можно использовать атрибут onclick.

#браузер #документ #события
👍4
Использование свойства DOM-объекта

Можно назначать обработчик, используя свойство DOM-элемента on<событие>.

К примеру, elem.onclick.

Если обработчик задан через атрибут, то браузер читает HTML-разметку, создаёт новую функцию из содержимого атрибута и записывает в свойство.

#браузер #документ #события
👍2
Обработчик в атрибуте и свойстве

Обработчик всегда хранится в свойстве DOM-объекта, а атрибут – лишь один из способов его инициализации.

Так как у элемента DOM может быть только одно свойство с именем onclick, то назначить более одного обработчика так нельзя.

P.S. Два примера кода на картинке работают одинаково.

#браузер #документ #события
👍1
HTML-атрибуты

В HTML у тегов могут быть атрибуты. Когда браузер парсит HTML, чтобы создать DOM-объекты для тегов, он распознаёт стандартные атрибуты и создаёт DOM-свойства для них.

Таким образом, когда у элемента есть id или другой стандартный атрибут, создаётся соответствующее свойство. Но этого не происходит,
если атрибут нестандартный.

#браузер #документ #атрибуты_свойств
👍3
Расширенная демонстрация работы с атрибутами

Пожалуйста, обратите внимание:

1. getAttribute('About') – здесь первая буква заглавная, а в HTML – строчная. Но это не важно: имена атрибутов регистронезависимы.

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

3. Все атрибуты, в том числе те, которые мы установили, видны в outerHTML.

4. Коллекция attributes является перебираемой. В ней есть все атрибуты элемента (стандартные и нестандартные) в виде объектов со свойствами name и value.

#браузер #документ #атрибуты_свойств
👍2
Свойства className и classList

Когда-то давно в JavaScript существовало ограничение: зарезервированное слово типа "class" не могло быть свойством объекта. Это ограничение сейчас отсутствует, но в то время было невозможно иметь свойство elem.class.
Поэтому для классов было введено схожее свойство "className": elem.className соответствует атрибуту "class".

Если мы присваиваем что-то elem.className, то это заменяет всю строку с классами. Иногда это то, что нам нужно, но часто мы хотим добавить/удалить один класс.
Для этого есть другое свойство: elem.classList - это специальный объект с методами для добавления/удаления одного класса.

#браузер #документ #свойства
👍5🔥1
DOM-свойства типизированы

DOM-свойства не всегда являются строками. Например, свойство input.checked (для чекбоксов) имеет логический тип.

Есть и другие примеры. Атрибут style – строка, но свойство style является объектом (как в примере на картинке).

#браузер #документ #свойства_узлов
👍2
Методы вставки

Чтобы наш div появился, нам нужно вставить его где-нибудь в document. Например, в document.body.

Для этого есть метод append, в нашем случае: document.body.append(div).

На картинке выше полный пример
👍4
Нестандартные атрибуты, dataset

Все атрибуты, начинающиеся с префикса «data-», зарезервированы для использования программистами. Они доступны в свойстве dataset.

Например, если у elem есть атрибут "data-about", то обратиться к нему можно как elem.dataset.about.

Как в примере на картинке.
👍7
Function Declaration

В отличие от переменных, объявленных с помощью let, они полностью инициализируются не тогда, когда выполнение доходит до них, а раньше, когда создаётся лексическое окружение.

Для верхнеуровневых функций это означает момент, когда скрипт начинает выполнение.

Вот почему мы можем вызвать функцию, объявленную через Function Declaration, до того, как она определена.

Следующий код демонстрирует, что уже с самого начала в лексическом окружении что-то есть. Там есть say, потому что это Function Declaration. И позже там появится phrase, объявленное через let

#функции #function_declaration
👍5
Вложенные функции

Функция называется «вложенной», когда она создаётся внутри другой функции. Это очень легко сделать в JavaScript.

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

Здесь вложенная функция getFullName() создана для удобства. Она может получить доступ к внешним переменным и, значит, вывести полное имя. В JavaScript вложенные функции используются очень часто.

Что ещё интереснее, вложенная функция может быть возвращена: либо в качестве свойства нового объекта (если внешняя функция создаёт объект с методами), либо сама по себе. И затем может быть использована в любом месте. Не важно где, она всё так же будет иметь доступ к тем же внешним переменным.

#функции #вложенные
👍3
For, while

Для цикла у каждой итерации своё отдельное лексическое окружение. Если переменная объявлена в for(let ...), то она также в нём

Обратите внимание: let i визуально находится снаружи {...}. Но конструкция for – особенная в этом смысле, у каждой итерации цикла своё собственное лексическое окружение с текущим i в нём.

И так же, как и в if, ниже цикла i невидима.

#циклы #for #while
👍3
Блоки кода

Мы также можем использовать «простые» блоки кода {...}, чтобы изолировать переменные в «локальной области видимости».

Например, в браузере все скрипты (кроме type="module") разделяют одну общую глобальную область. Так что, если мы создадим глобальную переменную в одном скрипте, она станет доступна и в других. Но это становится источником конфликтов, если два скрипта используют одно и то же имя переменной и перезаписывают друг друга.

Это может произойти, если название переменной – широко распространённое слово, а авторы скрипта не знают друг о друге.

Если мы хотим этого избежать, мы можем использовать блок кода для изоляции всего скрипта или какой-то его части(на картинке выше)

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

#функции #блоки
👍5
Не используйте setAttribute для обработчиков

Такой вызов работать не будет, т.к. setAttribute приводит все в строковый тип.

#браузер #документ #события
👍8