Ще один блог веб-розробника. Маніпуляції з DOM на чистому JavaScript Що таке dom html

На цьому уроці ми розглянемо, що таке DOM, для чого він потрібен, а також те, як він будується.

Що таке DOM?

Браузер, коли запитує сторінку та отримує у відповіді від сервера її вихідний HTML-код, повинен спочатку його розібрати. У процесі аналізу та аналізу HTML-коду браузер будує на основі нього DOM-дерево.

Після виконання цієї дії та інших браузер приступає до відтворення сторінки. У цьому процесі він, звичайно, вже використовує створене ним DOM-дерево, а не вихідний HTML-код.

DOM – це об'єктна модель документа, яку браузер створює в пам'яті комп'ютера на підставі коду HTML, отриманого ним від сервера.

Якщо сказати по-простому, HTML-код – це текст сторінки, а DOM – це набір пов'язаних об'єктів, створених браузером при парсингу її тексту.

У Chrome вихідний код сторінки, який отримує браузер, можна переглянути у вкладці «Source» на панелі «Інструменти веб-розробника».


У Chrome інструменту, за допомогою якого можна було б переглянути створене ним DOM-дерево, немає. Але є представлення цього DOM-дерева у вигляді HTML-коду, воно є на вкладці «Elements». З таким уявленням DOM веб-розробнику, звичайно, набагато зручніше працювати. Тому інструменту, який DOM представляв у вигляді деревоподібної структури немає.


Об'єкти в цій моделі утворюються практично з усього, що є в HTML (тегів, текстового контенту, коментарів і т.д.), включаючи сам документ. Зв'язки між цими об'єктами моделі формуються на підставі того, як HTML-елементи розташовані у коді відносно один одного.

При цьому DOM документа після його формування можна змінювати. У разі зміни DOM браузер практично миттєво перемальовує зображення сторінки. В результаті у нас відображення сторінки завжди відповідає DOM.

Для читання та зміни DOM програмний браузер надає нам DOM API або, іншими словами, програмний інтерфейс. DOM API - це набір величезної кількості різних об'єктів, їх властивостей і методів, які ми можемо використовувати для читання та зміни DOM.

p align="justify"> Для роботи з DOM в більшості випадків використовується JavaScript, т.к. на сьогоднішній день це єдина мова програмування, скрипти якою можуть виконуватися в браузері.

Навіщо нам потрібний DOM API?Він нам потрібен для того, щоб ми могли за допомогою JavaScript змінювати сторінку на літу, тобто. робити її динамічною та інтерактивною.

DOM API надає нам (розробникам) безліч методів, за допомогою яких ми можемо змінювати все що є на сторінці, а також взаємодіяти з користувачем. Тобто. Цей програмний інтерфейс дозволяє нам створювати складні інтерфейси, форми, виконувати обробку дій користувачів, додавати та видаляти різні елементи на сторінці, змінювати їх вміст, властивості (атрибути) та багато іншого.

Зараз у вебі практично немає сайтів у сценаріях яких була б робота з DOM.

Із чого складається HTML-код сторінки?

Перед тим, як перейти до вивчення об'єктної моделі документа необхідно спочатку згадати, що являє собою вихідний код веб-сторінки (HTML-документа).

Вихідний код веб-сторінки складається з тегів, атрибутів, коментарів та тексту. Теги – це базова синтаксична конструкція HTML. Більшість із них є парними. У цьому випадку один з них відкриває, а інший - закриває. Одна така пара тегів утворює HTML-елемент. HTML-елементи можуть мати додаткові параметри – атрибути.

У документі для створення певної розмітки одні елементи знаходяться усередині інших. В результаті HTML-документ можна подати як безліч вкладених один в одного HTML-елементів.

Як приклад розглянемо наступний HTML код:

заголовок сторінки

Назва статті

Розділ статті

Вміст статті

У цьому коді кореневим елементом є html. У нього вкладені елементи head та body. Елемент head містить title, а body – h1 і div. Елемент div у свою чергу містить h2 і p.

Тепер розглянемо, як браузер на основі HTML коду будує DOM-дерево.

Як будується DOM-дерево документа?

Як вже було описано вище, браузер будує дерево на основі HTML-елементів та інших сутностей вихідного коду сторінки. За виконання цього процесу він враховує вкладеність елементів друг в друга.

В результаті браузер, отримане DOM-дерево використовує не тільки у своїй роботі, але також надає нам API для зручної роботи з ним через JavaScript.

Під час будівництва DOM браузер створює з HTML-елементів, тексту, коментарів та інших сутностей цієї мови об'єкти (вузли DOM-дерева).

Найчастіше веб-розробників цікавлять лише об'єкти (вузли), утворені з HTML-елементів.

При цьому браузер не просто створює об'єкти з HTML-елементів, а також пов'язує їх між собою певними зв'язками залежно від того, як кожен з них відноситься до іншого коду.

Елементи, які знаходяться безпосередньо в деякому елементі, є по відношенню до нього дітьми. А він для кожного є батьком. Крім цього, всі ці елементи стосовно один одного є сиблінгами (братами).

При цьому HTML будь-який елемент завжди має одного з батьків (HTML-елемент, в якому він безпосередньо розташований). У HTML елемент може бути кілька батьків. Виняток становить лише елемент html. В нього немає батька.

Щоб отримати DOM-дерево, оскільки його будує браузер, необхідно просто «вибудувати» всі елементи залежно від їхнього ставлення один до одного.

Створення DOM-дерева виконується зверху донизу.

У цьому коренем DOM-дерева завжди є сам документ (вузол document). Далі дерево будується залежно від структури HTML-коду.

Наприклад, HTML-код, який ми розглядали вище, матиме наступне DOM-дерево:


У самому верху цього дерева знаходиться вузол document. Цей вузол пов'язаний з html, він є його дитиною. Вузол html утворений елементом html ( ...). Вузли head ( ...) та body ( ...) мають батьківський зв'язок із html . По відношенню один до одного є сиблингами, т.к. мають одного з батьків. Вузол head пов'язаний з title (lt;title>...), він є його дитиною. Вузли h1 і div пов'язані з body, їм він є батьком. Вузол div пов'язаний з h2 (

...

) та p(), вони є його дітьми.

Починається дерево як було зазначено вище з об'єкта (вузла) document . Він у свою чергу має один дочірній вузол, утворений елементом html ( ...). Елементи head ( ...) та body ( ...) знаходяться у html і, отже, є його дітьми. Далі вузол head є батьківським для title (lt;title>...). Елементи h1 і div вкладені в body, отже є його дітьми. У div безпосередньо розташовані елементи h2 (

...

) та p(). Це означає, що вузол div для кожного є батьківським.

Ось так просто будується DOM-дерево в браузері на основі HTML-коду.

Навіщо знати, як будується DOM дерево?По-перше, це розуміння того середовища, в якому ви хочете щось змінювати. По-друге, більшість дій під час роботи з DOM зводиться до пошуку (вибору) потрібних елементів. Не знаючи як влаштовано DOM-дерево та зв'язки між вузлами знайти якийсь певний елемент у ньому буде досить складно.

Завдання

На основі DOM-дерева, представленого на малюнку, створіть HTML-код.


Модель DOM часто називають деревом DOM, оскільки вона складається з дерева об'єктів, які називаються вузлами. Ви дізналися, що таке Document Object Model (DOM), як отримати доступ до об'єкта document і змінити його властивості за допомогою консолі, також ми різницю між вихідним кодом HTML і DOM.

У цьому мануалі ви знайдете термінологію HTML, яка необхідна для роботи з JavaScript та DOM, дізнаєтесь, що таке дерево та вузли DOM, та навчитеся визначати найпоширеніші типи вузлів. Також ви зможете створити програму JavaScript у консолі для інтерактивної зміни DOM.

Термінологія HTML

Розуміння термінів HTML і JavaScript є критично необхідним для роботи з DOM. Давайте коротко розглянемо основні терміни.

Подивіться цей елемент HTML:

Home

У ньому є анкор, який є посиланням на index.html.

  • a – тег
  • href – атрибут
  • html – значення атрибуту
  • Home – текст.

Все, що знаходиться між тегами, що відкривається і закривається, становить HTML-елемент.

Повернемося до файлу index.html з попереднього мануалу:




Learning the DOM


Document Object Model



Найпростіший спосіб доступу до елемента JavaScript – це атрибут id. Давайте додамо вказане вище посилання на файл index.html з id=»nav».

...

Document Object Model


Home

...

Завантажте (або оновіть) сторінку у вікні браузера і перегляньте DOM, щоб переконатися, що код був оновлений.

Потім використовуйте метод getElementById() для доступу до всього елемента. Введіть в консолі наступне:

document.getElementById("nav");
Home

Метод getElementById() витягне весь елемент. Тепер замість того, щоб вводити цей об'єкт і метод щоразу, коли вам потрібно отримати доступ до посилання nav, ви можете помістити елемент у змінну, щоб з ним було легше працювати.

let navLink = document.getElementById("nav");

Змінна navLink містить анкор. Тут можна легко змінювати атрибути та значення. Наприклад, щоб змінити місце посилання, змініть атрибут href:

navLink.href = "https://www.wikipedia.org";

Також можна змінити текст, переназначивши властивість textContent:

navLink.textContent = "Navigate to Wikipedia";

Тепер, переглянувши елемент у консолі або перевіривши тег Elements, ви побачите, як він оновився.

navLink;
Navigate to Wikipedia

Зміни позначаться і на фронт-енді.

Оновлення сторінки поверне усі вихідні значення.

На цьому етапі ви повинні розуміти, як використовувати метод document для доступу до елемента, як присвоїти елемент змінної та як змінити властивості та значення в елементі.

Дерево та вузли DOM

Всі елементи DOM визначаються як вузли. Існує безліч типів вузлів, але є три основних, з якими ви працюватимете найчастіше:

  1. Вузол елемента
  2. Текстовий вузол
  3. Вузол коментаря

Коли елемент HTML є елементом DOM, він називається вузлом елемента. Будь-який одиночний текст поза елементом є текстовим вузлом, а коментар HTML – вузлом коментаря. Крім цих трьох типів вузлів, сам об'єкт document – ​​це вузол документа, який є кореневим вузлом решти вузлів.

DOM складається з деревоподібної структури вкладених вузлів, часто називається деревом DOM. Ви напевно знаєте, що являє собою генеалогічне дерево – це схематичне уявлення родинних зв'язків, яке складається з батьків, дітей та найближчих родичів. Вузли в DOM також називаються батьківськими та дочірніми залежно від їхнього ставлення до інших вузлів.

Наприклад створіть файл nodes.html. додайте до нього текстовий вузол, а також вузли коментаря та елемента.




Learning About Nodes


An element node



A text node.

Вузол елемента HTML є батьківським. head та body – дочірні вузли html. body містить три дочірні вузли, і всі вони знаходяться на одному рівні – тип вузла не впливає на рівень вкладення.

Примітка: При роботі з DOM, згенерованим HTML, відступи вихідного коду HTML створюють багато порожніх текстових вузлів, які не будуть видно у вкладці DevTools Elements. Більше про це за посиланням.

Визначення типу вузла

Кожен вузол у документі має тип, доступ якого здійснюється через властивість nodeType. Mozilla Developer Network містить оновлений список усіх констант типів вузлів. Нижче наведено таблицю найпоширеніших типів вузлів.

У вкладці Elements у Developer Tools ви можете помітити, що кожного разу, коли ви натискаєте та виділяєте будь-який рядок у DOM, поруч із нею з'являється значення == $0. Це дуже зручний спосіб отримати доступ до активного елемента.

У консолі node.html натисніть на перший елемент body (h1).

За допомогою консолі дізнайтесь тип вибраного вузла за допомогою властивості nodeType.

$0.nodeType;
1

Вибравши елемент h1, ви побачите 1 як висновок, який відноситься до ELEMENT_NODE. Зробіть те саме з іншими вузлами, і вони повернуть 3 і 8 відповідно.

Знаючи, як отримати доступ до елемента, можна побачити тип вузла, не виділяючи елементи в DOM.

document.body.nodeType;
1

На додаток до nodeType ви також можете використовувати властивість nodeValue, щоб дізнатися про значення текстового вузла або вузла коментаря, а nodeName – для отримання тега елемента.

Зміна DOM за допомогою подій

До цього часу ви бачили, як змінювати DOM в консолі, а такі зміни, як відомо, тимчасові; щоразу, коли сторінка оновлюється, всі зміни губляться. Ви оновлювали колір фону сторінки в консолі. Спробуйте об'єднати те, чого ви навчилися в цьому мануалі, з тим, що ви вже знаєте, щоб створити інтерактивну кнопку, яка змінюватиме колір фону.

Поверніться у файл index.html та додайте елемент button з id. Також потрібно додати посилання на новий файл до нового js-каталогу js/scripts.js.




Learning the DOM


Document Object Model





Подія JavaScript – це дія, яку виконує користувач. Користувач наводить вказівник миші на елемент, натискає на нього або певну клавішу на клавіатурі – це всі події. У цьому випадку кнопка повинна виконати дію, коли користувач натисне на неї. Для цього слід додати слухача подій. Створіть файл scripts.js та збережіть його в новому каталозі js. У файлі потрібно визначити елемент button і присвоїти його змінній.

Використовуючи метод addEventListener(), кнопка прослуховуватиме кліки та виконуватиме свою функцію після кліка.

...
button.addEventListener("click", () => (
// action will go here
});

Всередині функції потрібно помістити код попереднього мануалу, щоб змінити колір фону на fuchsia.

...

Так виглядає скрипт:

let button = document.getElementById("changeBackground");
button.addEventListener("click", () => (
document.body.style.backgroundColor = "fuchsia";
});

Збережіть та закрийте файл. Оновіть сторінку index.html у браузері. Натисніть нову кнопку, і колір фону сторінки зміниться.

Tags: ,

Об'єктна модель документа, або DOM, є програмним інтерфейсом доступу до елементів веб-сторінок. По суті, це API сторінки, що дозволяє читати та маніпулювати вмістом, структурою та стилями сторінки. Давайте розберемося як це влаштовано та як це працює.

Як будується веб-сторінка?

Процес перетворення вихідного HTML-документу на відображувану стилізовану та інтерактивну сторінку називається “Critical Rendering Path” (“Критичним шляхом рендерингу”). Хоча цей процес можна розбити на кілька етапів, як я описав це у статті «Розуміння критичного шляху рендерингу», ці етапи можна умовно згрупувати у два етапи. У першому браузер аналізує документ, щоб визначити, що зрештою відображатиметься на сторінці, а в другому браузер виконує рендеринг.

Результатом першого етапу є те, що називається "render tree" ("дерево рендерінгу"). Дерево рендерингу– це представлення елементів HTML, які будуть відображатися на сторінці та пов'язаних з ними стилів. Щоб збудувати це дерево, браузеру потрібні дві речі:

  1. CSSOM, представлення стилів, пов'язаних з елементами
  2. DOM, представлення елементів

З чого складається DOM?

DOM – це об'єктне уявлення вихідного HTML-документа. Він має деякі відмінності, як ми побачимо нижче, але насправді це спроба перетворити структуру і зміст документа HTML в об'єктну модель, яка може використовуватися різними програмами.

Структура об'єктів DOM представлена ​​тим, що називається "деревом вузлів". Воно так називається, тому що його можна розглядати як дерево з одним батьківським елементом, що розгалужується на кілька дочірніх гілок, кожна з яких може мати листя. І тут батьківський «елемент» – це кореневий елемент, дочірні «гілки» – це вкладені елементи, а «листя» – це вміст усередині елементів.

Давайте розглянемо цей HTML-документ як приклад:

My first web page

Hello, world!

How are you?

Цей документ може бути представлений у вигляді наступного дерева вузлів:

  • html
    • head
      • title
        • My first web page
    • body
      • h1
        • Hello, world!
      • p
        • How are you?

Чим DOM не є

У наведеному прикладі здається, що DOM є відображенням 1: 1 вихідного HTML-документа. Проте, як я вже казав, є різницю. Щоб повністю зрозуміти, що таке DOM, нам потрібно поглянути на те, що він не є.

DOM не є копією вихідного HTML

Хоча DOM створений з HTML-документа, він не завжди такий самий. Є два випадки, коли DOM може відрізнятися від вихідного HTML.

1. Коли HTML містить помилки розмітки

DOM – це інтерфейс доступу до дійсних (тобто вже відображається) елементів документа HTML. У процесі створення DOM браузер сам може виправити деякі помилки в коді HTML.

Розглянемо як приклад цей HTML-документ:

Hello, world!

У документі відсутні елементи і що є обов'язковою вимогою для HTML. Але якщо ми подивимося на дерево DOM, то побачимо, що це було виправлено:

  • html
    • head
    • body
      • Hello, world!

    2. Коли DOM модифікується кодом Javascript

    Крім того, що DOM є інтерфейсом для перегляду вмісту документа HTML, він також може бути змінений.

    Ми можемо, наприклад, створити додаткові сайти для DOM, використовуючи Javascript.

    Var newParagraph = document.createElement("p"); var paragraphContent = document.createTextNode("I"m new!");newParagraph.appendChild(paragraphContent); document.body.appendChild(newParagraph);

    Цей код змінить DOM, але зміни не відобразяться у документі HTML .

    DOM – це не те, що ви бачите у браузері (тобто дерево рендерингу)

    У вікні перегляду браузера ви бачите дерево рендеринга, яке є комбінацією DOM і CSSOM. Чим відрізняється DOM від дерева рендерингу, так це те, що останнє складається тільки з того, що зрештою буде відображено на екрані.

    Оскільки дерево рендерингу стосується лише того, що відображається, воно виключає елементи, які візуально приховані. Наприклад, елементи, які мають стилі з display: none.

    Hello, world!

    How are you?

    DOM включатиме елемент

    • html
      • head
      • body
        • h1
          • Hello, world!
        • p
          • How are you?

    Проте дерево рендерингу і, отже, те, що видно у вікні перегляду, не буде включено до цього елемента.

    • html
      • body
        • h1
          • Hello, world!

    DOM – це не те, що відображається у DevTools

    Ця різниця трохи менша, тому що інспектор елементів DevTools забезпечує найближче наближення до DOM, яке ми маємо в браузері. Проте інспектор DevTools містить додаткову інформацію, якої немає у DOM.

    Найкращий приклад цього – псевдоелементи CSS. Псевдоелементи, створені за допомогою селекторів ::beforeі ::after, є частиною CSSOM та дерева рендерингу, але технічно не є частиною DOM. Це пов'язано з тим, що DOM створюється тільки з вихідного документа HTML, не включаючи стилі, застосовані до елемента.

    Незважаючи на те, що псевдоелементи не є частиною DOM, вони є в нашому інспекторі елементів devtools.


    Резюме

    DOM – це інтерфейс HTML-документу. Він використовується браузерами як перший крок до визначення того, що візуалізувати у вікні перегляду, та кодом Javascript для зміни вмісту, структури чи стилю сторінки.

W3C
Творці DOM

Перш ніж приступити до вивчення технології DOM, ви вже повинні знати основи мов HTML, CSS і, крім цього, вам необхідно прочитати статті, присвячені HTML-форм (знати як створювати кнопки, текстові поля і т.д.).

DOM (document object model)- Об'єктна модель документа, створений W3C (World Wide Web Consortium) - консорціумом всесвітньої павутини.

DOM— це веб-технологія, що дозволяє керувати HTML-тегами сторінки через мову JavaScript. DOM представляє HTML-теги у вигляді об'єктів із властивостями та методами. Кожен HTML-тег (об'єкт) на HTML-сторінці, завдяки DOM, має свою унікальну адресу. Отримуючи доступ до цієї адреси, JavaScript може керувати HTML-тегом.

Адреси в DOM створюються автоматично, але вони надто довгі та складні. Тому творці DOM зробили для веб-програмістів можливість самостійного написання коротких адрес через селектор id (унікальний ідентифікатор).

Принцип роботи DOM

Браузер відкриваючи HTML-сторінку, створює на основі її тегів - структуру DOM, де кожен HTML-тег постає у вигляді об'єкта зі своєю унікальною адресою. Структуру DOM також називають деревом DOM, це дерево складається з вузлів, які є HTML-теги, атрибути, текст.

Історія DOM

Спочатку DOM не був стандартизований і два браузери Netscape Navigator і Internet Explorer, що існували на той момент, створювали DOM за своїм розумінням. На той час, веб-програмістам доводилося вивчати дві версії DOM.

На даний момент W3C стандартизував DOM і всі браузери намагаються дотримуватися цього стандарту.

Як правило, коли потрібно виконати якісь дії з DOM, розробники використовують jQuery. Проте практично будь-яку маніпуляцію з DOM можна зробити і на чистому JavaScript за допомогою його DOM API.

Розглянемо цей API докладніше:

Насамкінець ви напишете свою простеньку DOM-бібліотеку, яку можна буде використовувати в будь-якому проекті.

DOM-запити

DOM-запити здійснюються за допомогою методу.querySelector() , який як аргумент приймає довільний СSS-селектор.

Const myElement = document.querySelector("#foo > div.bar")

Він поверне перший відповідний елемент. Можна і навпаки - перевірити, чи елемент селектору відповідає:

MyElement.matches("div.bar") === true

Якщо потрібно отримати всі елементи, що відповідають селектору, використовуйте таку конструкцію:

Const myElements = document.querySelectorAll(".bar")

Якщо ж ви знаєте, на який батьківський елемент потрібно послатися, можете просто проводити пошук серед його дочірніх елементів замість того, щоб шукати по всьому коду:

Const myChildElemet = myElement.querySelector("input") // Замість: // document.querySelector("#foo > div.bar input")

Виникає питання: навіщо тоді використовувати інші, менш зручні методи на зразок. getElementsByTagName()? Є маленька проблема - результат виводу.querySelector() не оновлюється, і коли ми додамо новий елемент (див.), він не зміниться.

Const elements1 = document.querySelectorAll("div") const elements2 = document.getElementsByTagName("div") const newElement = document.createElement("div") document.body.appendChild(newElement) elements1.length === elements2.length // false

Також querySelectorAll() збирає все в один список, що робить його не дуже ефективним.

Як працювати зі списками?

До того ж у.querySelectorAll() є два маленькі нюанси. Ви не можете просто викликати методи на результати і очікувати, що вони застосовуються до кожного з них (як ви могли звикнути, що робити це з jQuery). У будь-якому випадку необхідно буде перебирати всі елементи в циклі. Друге - об'єкт, що повертається, є списком елементів, а не масивом. Отже, методи масивів не спрацюють. Звичайно, є методи і для списків, щось на зразок. forEach (), але, на жаль, вони підходять не для всіх випадків. Так що краще перетворити список на масив:

// Використання Array.from() Array.from(myElements).forEach(doSomethingWithEachElement) // Або прототип масиву (до ES6) Array.prototype.forEach.call(myElements, doSomethingWithEachElement) // Простіше: .forEachscal , doSomethingWithEachElement)

Кожен елемент має деякі властивості, що посилаються на «сім'ю».

MyElement.children myElement.firstElementChild myElement.lastElementChild myElement.previousElementSibling myElement.nextElementSibling

Оскільки інтерфейс елемента (Element) успадкований від інтерфейсу вузла (Node), такі властивості також присутні:

MyElement.childNodes myElement.firstChild myElement.lastChild myElement.previousSibling myElement.nextSibling myElement.parentNode myElement.parentElement

Перші властивості посилаються на елемент, а останні (крім.parentElement) можуть бути списками елементів будь-якого типу. Відповідно, можна перевірити і тип елемента:

MyElement.firstChild.nodeType === 3 // Цей елемент буде текстовим вузлом

Додавання класів та атрибутів

Додати новий клас дуже просто:

myElement.classList.add("foo") myElement.classList.remove("bar") myElement.classList.toggle("baz")

Додавання властивості для елемента відбувається так само, як і для будь-якого об'єкта:

// Отримання значення атрибута const value = myElement.value // Встановлення атрибута як властивість елемента myElement.value = "(!LANG:foo" // Для установки нескольких свойств используйте.Object.assign() Object.assign(myElement, { value: "foo", id: "bar" }) // Удаление атрибута myElement.value = null !}

Можна використовувати методи .getAttibute() , .setAttribute() та .removeAttribute() . Вони відразу ж поміняють HTML-атрибути елемента (на відміну від DOM-властивостей), що викличе браузерне перемальовування (ви зможете побачити всі зміни, вивчивши елемент за допомогою інструментів розробника в браузері). Такі перемальовки не тільки вимагають більше ресурсів, ніж установка DOM-властивостей, але можуть призвести до непередбачених помилок.

Як правило, їх використовують для елементів, які не мають відповідних DOM-властивостей, наприклад colspan . Або якщо їх використання дійсно необхідно, наприклад для HTML-властивостей при успадкування (дивіться ).

Додавання CSS-стилів

Додають їх точно так, як і інші властивості:

MyElement.style.marginLeft = "2em"

Якісь певні властивості можна задавати за допомогою .style , але якщо ви хочете отримати значення після деяких обчислень, то краще використовувати window.getComputedStyle() . Цей метод отримує елемент і повертає CSSStyleDeclaration , що містить стилі як елемента, так і його батька:

Window.getComputedStyle(myElement).getPropertyValue("margin-left")

Зміна DOM

Можна переміщати елементи:

// Додавання element1 як останнього дочірнього елемента element2 element1.appendChild(element2) // Вставка element2 як дочірнього елемента element1 перед element3 element1.insertBefore(element2, element3)

Якщо не хочеться переміщати, але потрібно вставити копію, використовуємо:

// Створення клону const myElementClone = myElement.cloneNode() myParentElement.appendChild(myElementClone)

Метод.cloneNode() приймає булеве значення як аргумент, при true також клонуються і дочірні елементи.

Звичайно, ви можете створювати нові елементи:

Const myNewElement = document.createElement("div") const myNewTextNode = document.createTextNode("some text")

А потім вставляти їх як було показано вище. Видалити елемент безпосередньо не вийде, але це можна зробити через батьківський елемент:

MyParentElement.removeChild(myElement)

Можна звернутись і побічно:

MyElement.parentNode.removeChild(myElement)

Методи для елементів

У кожного елемента є такі властивості, як .innerHTML і .textContent , вони містять HTML-код і, відповідно, сам текст. У наступному прикладі змінюється вміст елемента:

// Змінюємо HTML myElement.innerHTML = `

New content

beep boop beep boop

` // Таким чином вміст видаляється myElement.innerHTML = null // Додаємо до HTML myElement.innerHTML += ` continue reading...

Насправді зміна HTML – погана ідея, тому що губляться всі зміни, які були зроблені раніше, а також перевантажуються обробники подій. Краще використовувати такий спосіб, тільки повністю відкинувши весь HTML і замінивши його копією з сервера. Ось так:

Const link = document.createElement("a") const text = document.createTextNode("continue reading...") const hr = document.createElement("hr") link.href = "foo.html" link.appendChild( text) myElement.appendChild(link) myElement.appendChild(hr)

Однак це спричинить дві перемальовки в браузері, в той час як.innerHTML призведе лише до однієї. Обійти це можна, якщо спочатку додати все в DocumentFragment, а потім додати потрібний вам фрагмент:

Const fragment = document.createDocumentFragment() fragment.appendChild(text) fragment.appendChild(hr) myElement.appendChild(fragment)

Обробники подій

Один із найпростіших обробників:

MyElement.onclick = function onclick (event) ( console.log(event.type + "got fired") )

Але, як правило, його слід уникати. Тут.onclick - властивість елемента, і за ідеєю ви можете його змінити, але ви не зможете додавати інші обробники, використовуючи ще одну функцію, яка посилається на стару.

Для додавання обробників краще використовувати addEventListener() . Він приймає три аргументи: тип події, функцію, яка буде викликатися щоразу при спрацьовуванні, і об'єкт зміни (до нього ми повернемося пізніше).

MyElement.addEventListener("click", function (event) ( console.log(event.type + "got fired") )) myElement.addEventListener("click", function (event) ( console.log(event.type + " got fired again")))

Властивість event.target звертається до елемента, за яким закріплено подію.

А так ви зможете отримати доступ до всіх властивостей:

// Властивість `forms` - масив, що містить посилання на всі форми const myForm = document.forms const myInputElements = myForm.querySelectorAll("input") ", function (event) ( console.log(event.target.value) )) ))

Запобігання стандартним діям

Для цього використовується метод preventDefault(), який блокує стандартні дії. Наприклад, він заблокує відправлення форми, якщо авторизація на стороні клієнта не була успішною:

MyForm.addEventListener("submit", function (event) ( const name = this.querySelector("#name") if (name.value === "(!LANG:Donald Duck") { alert("You gotta be kidding!") event.preventDefault() } }) !}

Метод.stopPropagation() допоможе, якщо у вас є певний обробник події, закріплений за дочірнім елементом, і другий обробник тієї ж події, закріплений за батьком.

Як уже говорилося, метод.addEventListener() приймає третій необов'язковий аргумент у вигляді об'єкта з конфігурацією. Цей об'єкт повинен містити будь-які з наступних булевих властивостей (за умовчанням все у значенні false):

  • capture: подія буде прикріплена до цього елемента перед будь-яким іншим елементом нижче DOM;
  • once: подія може бути закріплена лише один раз;
  • passive: event.preventDefault() ігноруватиметься (виключення під час помилки).

Найбільш поширеною властивістю є .capture і воно настільки поширене, що для цього існує короткий спосіб запису: замість того, щоб передавати його в об'єкті конфігурації, просто вкажіть його значення тут:

MyElement.addEventListener(type, listener, true)

Обробники видаляються за допомогою методу .removeEventListener() , що приймає два аргументи: тип події та посилання на обробник для видалення. Наприклад, властивість once можна реалізувати так:

MyElement.addEventListener("change", function listener (event) ( console.log(event.type + " got triggered on " + this) this.removeEventListener("change", listener) ))

успадкування

Допустимо, у вас є елемент, і ви хочете додати обробник подій для всіх його дочірніх елементів. Тоді вам довелося прогнати їх у циклі, використовуючи метод myForm.querySelectorAll("input") , як було показано вище. Однак ви можете просто додати елементи у форму та перевірити їх вміст за допомогою event.target.

MyForm.addEventListener("change", function (event) ( const target = event.target if (target.matches("input")) ( console.log(target.value) ) ))

І ще один плюс даного методу полягає в тому, що до нових дочірніх елементів обробник буде прив'язуватися автоматично.

Анімація

Найпростіше додати анімацію використовуючи CSS із властивістю transition. Але для більшої гнучкості (наприклад, для гри) краще підходить JavaScript.

Викликати метод window.setTimeout() , доки анімація не закінчиться, - не найкраща ідея, тому що ваша програма може зависнути, особливо на мобільних пристроях. Найкраще використовувати window.requestAnimationFrame() для збереження всіх змін до наступного перемальовування. Він приймає функцію як аргумент, який у свою чергу отримує мітку часу:

Const start = window.performance.now() const duration = 2000 window.requestAnimationFrame(function fadeIn (now)) ( const progress = now - start myElement.style.opacity = progress / duration if (progress< duration) { window.requestAnimationFrame(fadeIn) } }

У такий спосіб досягається дуже плавна анімація. У своїй статті Марк Браун розмірковує на цю тему.

Пишемо свою бібліотеку

Той факт, що DOM для виконання будь-яких операцій з елементами весь час доводиться перебирати їх, може здатися дуже стомлюючим в порівнянні з синтаксисом jQuery $(".foo").css((color: "red")) . Але чому б не написати кілька своїх методів, що полегшує це завдання?

Const $ = function $ (selector, context = document) ( const elements = Array.from(context.querySelectorAll(selector)) return ( elements, html (newHtml) ( this.elements.forEach(element => ( element.innerHTML = newHtml )) return this ), css (newCss) ( this.elements.forEach(element => ( Object.assign(element.style, newCss) )) return this ), on (event, handler, options) ( this.elements .forEach(element => ( element.addEventListener(event, handler, options) )) return this ) ) )