====== Методи JS для роботи з DOM ======
===== getElementById =====
Повертає посилання елемент по його ідентифікатору (ID (en-US)); ідентифікатор є рядком, який може бути використаний для ідентифікації елемента; вона може бути визначена за допомогою атрибута id HTML або зі скрипта.
const categoriesList = document.getElementById('categories');
===== querySelectorAll =====
Метод querySelectorAll() Document повертає статичний (не динамічний) NodeList, що містить усі знайдені елементи документа, які відповідають зазначеному селектору.
const categoriesList = document.getElementById('categories');
const categoryItems = categoriesList.querySelectorAll('li.item');
console.log(`Number of categories: ${categoryItems.length}`);
===== element.querySelector=====
Використовується, якщо необхідно знайти тільки один, найчастіше унікальний елемент (по CSS селектору елемента).
* Повертає перший знайдений елемент усередині element, що відповідає рядку CSS-селектора selector.
* Навіть якщо їх декілька, завжди повернеться посилання тільки на перший елемент у DOM-дереві. Якщо нічого не знайдено, то поверне null
const listWithId = document.querySelector('#menu');
==== Заміна значень html за допомогою JS ====
const link = document.querySelector(".link");
console.log(link.href); // "https://goit.global" - було
link.href = "https://tro.net.ua";
console.log(link.href); // "https://tro.net.ua" - стало
===== textContent =====
повертає весь текстовий контент усередині елементів (__власних і вкладених елементів__).
const el = document.querySelector(".text")
const nested = document.querySelector(".sub-text")
console.log(el.textContent); // "Username: Mango"
console.log(nested.textContent); // "Mango"
===== classList =====
зберігається об'єкт із методами для роботи з CSS-класами елемента. Це спеціальний тип об’єкта, який подібний до масиву. Він схожий, але не є нативним JavaScript-масивом. Він зберігає в собі весь перелік класів DOM-елемента, властивість length і властивість value.
const link = document.querySelector(".link");
console.log(link.classList);
// ["link", "is-active", length: 2, value: "link is-active"]
==== classList.contains(className) ====
Метод classList.contains(className) очікує аргументом рядок з іменем класу та повертає true або false, залежно від наявності класу className в елемента.
Зверни увагу, що className передаємо як рядок без крапки (без селектора класу).
==== classList.add(className) ====
Метод classList.add(className) очікує аргументом рядок з іменем класу та додає клас className до списку класів елемента.
link.classList.add('fourClass');
==== classList.remove(className) ====
Метод classList.remove(className) очікує аргументом рядок з іменем класу та видаляє клас className зі списку класів елемента.Якщо спробувати видалити клас, якого не існує на елементі, то це не викличе помилку. Просто нічого не видалиться.
==== classList.toggle(className) ====
Працює як перемикач, якщо клас className відсутній, то додає його в кінець списку класів і навпаки, якщо клас className присутній — видаляє його
==== classList.replace(oldClassName, newClassName) ====
перший — стара назва класу, другий — нова назва класу - замінює існуючий клас oldClassName на вказаний newClassName.
===== elem.parentNode =====
містить посилання на батьківський вузол-елемент вузла elem
===== style =====
використовується для читання та зміни інлайнових стилів з DOM-елементів. Вона повертає об'єкт, який є екземпляром інтерфейсу CSSStyleDeclaration, і містить список лише всіх інлайнових властивостей елемента, а не увесь CSS.
const button = document.querySelector(".btn");
button.style.backgroundColor = "teal";
button.style.fontSize = "24px";
button.style.textAlign = "center";
console.log(button.style); // inline styles object
===== element.hasAttribute(nameAttribute) =====
приймає один аргумент — рядок nameAttribute, який містить ім’я атрибута для перевірки та повертає результат перевірки його наявності на елементі element — true чи false.
const image = document.querySelector(".image");
console.log(image.hasAttribute("src")); // true
console.log(image.hasAttribute("href")); // false
===== element.getAttribute(nameAttribute) =====
Метод element.getAttribute(nameAttribute) отримує один аргумент — рядок nameAttribute з іменем атрибута, і повертає значення цього атрибута для вказаного HTML-елемента element. Якщо атрибут не знайдено, метод повертає null.
===== element.setAttribute(nameAttribute, value) =====
Метод element.setAttribute(nameAttribute, value) приймає два аргументи: рядок nameAttribute з іменем атрибута, який потрібно встановити або змінити, та value зі значенням, яке цьому атрибуту треба присвоїти. Метод встановлює або змінює значення зазначеного атрибута для вказаного HTML-елемента element.
===== element.removeAttribute(nameAttribute) =====
Метод element.removeAttribute(nameAttribute) приймає один аргумент — рядок nameAttribute з іменем атрибута, який потрібно видалити зі вказаного HTML-елемента element — та видаляє його. Якщо зазначеного атрибута немає на елементі, метод не викликає жодних помилок та не робить нічого.
**Отримати доступ або змінити значення деяких атрибутів елемента можна безпосередньо, звернувшись до них як до властивостей DOM-об'єкта. Це буде менш затратно за кількістю коду.**
===== elem.childNodes =====
містить псевдомасив, у якому зібрані всі дочірні вузли-елементи і текстові вузли вузла elem
===== elem.children =====
містить псевдомасив, у якому зібрані всі дочірні вузли-елементи вузла elem, тобто ті, що відповідають тегам
===== elem.firstChild =====
містить посилання на перший дочірній вузол (вузол-елемент або текстовий вузол) вузла elem.
УВАГА - першим майже завжди буде текстовим вузлом бо між тегами є пробіл та перенос строки.
===== elem.firstElementChild =====
містить посилання на перший дочірній вузол-елемент усередині elem, тобто той, що відповідає тегу
===== elem.lastChild =====
містить посилання на останній дочірній вузол (вузол-елемент або текстовий вузол) вузла elem
===== elem.lastElementChild =====
містить посилання на останній дочірній вузол-елемент усередині elem, тобто той, що відповідає тегу
===== elem.previousSibling =====
містить посилання на попередній сусідній вузол відносно елемента elem, і це може бути як елемент, так і текстовий вузол
===== elem.previousElementSibling =====
містить посилання на попередній сусідній вузол-елемент відносно елемента elem, тобто той, що відповідає тегу
===== elem.nextSibling =====
містить посилання на наступний сусідній вузол відносно елемента elem, і це може бути як елемент, так і текстовий вузол
===== elem.nextElementSibling =====
містить посилання на наступний сусідній вузол-елемент відносно елемента elem, тобто той, що відповідає тегу
===== data-атрибути (Власні атрибути) =====
Специфікацією HTML визначено вичерпний перелік атрибутів, які ми можемо додавати на ті чи інші теги (DOM-елементи) для того, щоб розмітка лишалась валідною, але інколи цього переліку недостатньо. Бувають випадки, коли нам потрібно зберегти певну інформацію на тезі, наприклад, вказати тип дії кнопки, щоб потім у певний момент часу мати можливість отримати до неї доступ. І тут на допомогу приходять власні data-атрибути.
Власні атрибути дозволяють додати до тегу довільний атрибут і отримати його значення в JavaScript.
==== dataset ====
**Зберігає користувацькі дата-атрибути**. Зручніше працювати через **dataset**. Для отримання значення data-атрибута використовується властивість dataset, після якої через крапку пишеться ім'я атрибута без data-. Тобто data- відкидається, а інша частина імені записується як ім'я властивості об'єкта.
const saveBtn = document.querySelector('button[data-action="save"]');
console.log(saveBtn.dataset.action); // "save"
const closeBtn = document.querySelector('button[data-action="close"]');
console.log(closeBtn.dataset.action); // "close"
==== delete ====
Для видалення data-атрибута
===== Створення елементів у DOM =====
==== createDocumentFragment ====
Створює новий порожній DocumentFragment, до якого можна додати вузли DOM для побудови позаекранного дерева DOM.
const fragment = document.createDocumentFragment();
==== createElement ====
створює елемент з ім'ям tagName і повертає посилання на його об’єкт як результат свого виконання.
tagName — це рядок, що вказує тип елемента, який створюється.
Елемент створюється в пам'яті, у DOM його ще немає.
const heading = document.createElement("h1");
Після створення елемента heading отримуємо посилання на його об’єкт у пам'яті. З цього моменту можна звертатися до властивостей цього об’єкта і змінювати їх ще до того, як вставимо цей елемент у DOM.
const heading = document.createElement("h1");
headding.classList.add("title");
heading.textContent = "This is a heading";
console.log(heading); //
This is a heading
const image = document.createElement("img");
image.src = "";
image.alt = "Nature";
console.log(image); //
* **elem.append**(el1, el2, ...) — додає один або декілька елементів після всіх дітей елемента elem.
* **elem.prepend**(el1, el2, ...) — додає один або декілька елементів перед усіма дітьми елемента elem.
* **elem.after**(el1, el2, ...) — додає один або декілька елементів після елемента elem.
* **elem.before**(el1, el2, ...) — додає один або декілька елементів перед елементом elem.
===== innerHTML =====
Ще один спосіб створити DOM-елементи і помістити їх у DOM-дерево.Для цього треба використати рядки з тегами і дозволити браузеру зробити всю важку роботу. У такого підходу є свої плюси та мінуси.
==== Читання innerHTML ====
Властивість innerHTML зберігає вміст елемента, включно з тегами, у вигляді рядка. Значення, що повертається, — це **завжди валідний HTML-код**.
Він затира структуру що була і заміняє собою нову HTML-розмітку
const = ''
const myNewHtml = document.querySelector(".one");
link.innerHTML(myNewHtml);
==== Зміна innerHTML ====
Властивість innerHTML доступна і для читання, і для запису. Якщо записати в неї рядок з HTML-тегами, то браузер під час парсингу рядка перетворить його у валідні елементи і додасть у DOM-дерево.
===== Видалення елементів у DOM =====
==== element.remove() ====
щоб видалити елемент
const text = document.querySelector('.text');
text.remove();
===== insertAdjacentHTML =====
сучасний метод для додавання рядка з HTML-тегами перед, після або всередину елемента. Він вирішує проблему innerHTML з повторною серіалізацією вмісту елемента під час додавання розмітки до вже існуючої.
Аргумент position — це рядок, який визначає позицію щодо елемента element. Він приймає одне з чотирьох значень.
* "beforebegin" — перед element
* "afterbegin" — всередині element, перед усіма дітьми
* "beforeend" — всередині element, після усіх дітей
* "afterend" — після element
===== addEventListener =====
Додавання слухача подій: element.addEventListener(event, handler, options)
* **event** — рядок, що містить ім'я події, наприклад, "click"
* **handler** — колбек-функція, яка буде викликана під час настання події
* **options** — необов'язковий об'єкт параметрів із розширеними налаштуваннями
const myBtn = doucument.querySelector('.js-button-click');
myBtn.addEventListener('click',onButtonClick);
function onButtonClick (){
console.log('Hello');
}
або
const button = document.querySelector(".my-button");
button.addEventListener("click", () => {
console.log("The button was pressed and now the next image will appear");
});
або
const button = document.querySelector(".my-button");
const handleClick = () => {
console.log("The button was pressed and now the next image will appear");
};
button.addEventListener("click", handleClick);
====== removeEventListener ======
видаляє слухача події з елемента.
element.removeEventListener(event, handler, options);
element.removeEventListener('onclick', myfunction);
====== Об'єкт події ======
Кожна подія — це об'єкт, який містить інформацію про деталі події та автоматично передається першим аргументом в обробник події. Усі події відбуваються з базового класу Event.
const handleClick = event => {
console.log(event);
};
button.addEventListener("click", handleClick);
====== Події клавіатури ======
Існує дві основні події клавіатури:
* keydown — подія, що відбувається при натисканні клавіші
* keyup — подія, що відбувається, коли клавішу відпустили
події клавіатури обробляються **на документі**
document.addEventListener("keydown", event => {
console.log("Keydown: ", event);
});
document.addEventListener("keyup", event => {
console.log("Keyup: ", event);
});
**Нещодавно для обробки комбінації клавіш використовували властивість keyCode. Більшість постів на форумах і блогах все ще можуть використовувати її. Пам’ятай: keyCode вже застаріла, і замість неї варто використовувати властивості key і code.**
===== Клавіші-модифікатори =====
Для обробки комбінацій клавіш на об'єкті події є властивості:
* ctrlKey
* altKey
* shiftkey
* metaKey
document.addEventListener("keydown", event => {
if ((event.ctrlKey || event.metaKey) && event.code === "KeyS") {
console.log("«Ctrl + s» or «Command + s» combo");
}
});
====== Події елементів форм ======
===== reset =====
Очистка данних полів на формі
const registerForm = document.querySelector(".login-form");
registerForm.reset();
===== submit =====
Відправлення форми відбувається:
* при кліку на кнопку з атрибутом type="submit"
* Або при натисканні клавіші Enter під час перебування в будь-якому її текстовому полі форми
const form = document.querySelector("form");
form.addEventListener("submit", handleSubmit);
function handleSubmit(event) {
event.preventDefault();
console.log(event.elements.email.value);
.
.
.
}
або
const form = document.querySelector("form");
form.addEventListener("submit", event => {
// ...
});
або
const registerForm = document.querySelector(".form");
registerForm.addEventListener("submit", handleSubmit);
function handleSubmit(event) {
event.preventDefault();
cont form = event.target;
const login = form.elements.login.value;
const password = form.elements.password.value;
if (login === "" || password === "") {
return console.log("Please fill in all the fields!");
}
**event.preventDefault()** - відключення подіій браузер за замовченням. Наприклад перезавантаження сторінки при події submit
===== preventDefault =====
Для скасування дії браузера за замовчуванням в об'єкта події
const form = document.querySelector("form");
form.addEventListener("submit", event => {
event.preventDefault();
});
===== change =====
Подія відбувається після зміни значення елемента форми і одночасної втрати фокусу
===== input =====
Подія input відбувається тільки на текстових полях і textarea.
Вона створюється щоразу при зміні значення елемента, не чекаючи втрати фокусу. На практиці input — це найголовніша подія для роботи з текстовими полями форми.
const textInput = document.querySelector(".text-input");
const output = document.querySelector(".output");
textInput.addEventListener("input", (event) => {
output.textContent = event.currentTarget.value;
});
===== focus і blur =====
Елемент отримує фокус під час кліку миші або переходу клавішею Tab.
* подія focus відбувається під час фокусування на елементі
* подія blur відбувається при втраті фокусу, наприклад, користувач клікає в іншому місці екрана
const textInput = document.querySelector(".text-input");
const setFocusBtn = document.querySelector('[data-action="set"]');
const removeFocusBtn = document.querySelector('[data-action="remove"]');
setFocusBtn.addEventListener("click", () => {
textInput.focus();
});
removeFocusBtn.addEventListener("click", () => {
textInput.blur();
});
textInput.addEventListener("focus", () => {
textInput.value = "This input has focus";
});
textInput.addEventListener("blur", () => {
textInput.value = "";
});
Поточний елемент, на якому знаходиться фокус, доступний як **document.activeElement**
===== stopPropagation =====
Так як подія від дочерного обїекта сплаивє до батьківського і може бути перехоплена дсь "вище", то це сплаивання можна зупинити.
* Зупиняє "спливання" події в DOM-дереві. Це означає, що жоден батьківський елемент не зможе відловити цю подію.
* Не заважає іншим обробникам подій виконуватися на тому ж самому елементі.
const descendant = document.querySelector("#descendant");
descendant.addEventListener("click", (event) => {
event.stopPropagation();
alert("Descendant click handler");
});
===== stopImmediatePropagation() =====
* Зупиняє "спливання" події так само, як event.stopPropagation().
* Також зупиняє виконання всіх інших обробників подій, які слухають цю ж подію на даному елементі, навіть якщо вони були зареєстровані перед цим.
===== nodeName (перевірка відповідности типу єлементу) =====
function selectColor(event) {
if (event.target.nodeName !== "BUTTON") {
return; // користувач клікнув між кнопками
}
const selectedColor = event.target.dataset.color; // користувач клікнув на кнопку і ми маємо доступ до її атрибутів
}