html - Это документ со своей структурой, и эта структура может быть представлена как дерево узлов, мы ее видим когда в браузере открываем в инспекторе кода Elements. Узлы связаны между собой отношениями родительскими дочерними.
<!DOCTYPE html>
<html lang="en"> <!-- html родитель head и body -->
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body> <!-- body родитель section -->
<section class="section"> <!-- дочерний элемент body, его ребенок -->
<div class="bg">Я</div> <!-- Это дочерние элементы section-->
<div class="bg">г</div>
<div class="bg">i</div>
<div class="bg">й</div>
</section>
<div id="bg-id"> Это просто div </div>
<button class="btn">кнопка btn</button>
<button>кнопка 2</button>
<button>кнопка 1</button>
<script src="script.js"></script>
</body>
</html>
Когда документ сформирован, то мы можем его представить ввиде обычного объекта поэтому это называется Объектная Модель Документа - Document Object Model (DOM)
.
Браузер как бы создает DOM
дерево на основе нашего html
документа, каждый элемент становится объектом.
И как у любого объекта у него могут быть свои методы и некоторые из них мы будем использовать что бы получить доступ к определенным элементам на странице.
Обращаемся к DOM
мы через объект document
, этот объект содержит в себе всю структуру html
. Получать элементы и работать мы будем с html
структурой которую разбирали выше.
getElementById() - получаем элемент через id
. Внутри скобок указываем id
в виде строки.
// обращаемся к объекту document, а потом обращаемя к методу getElementById
const bg = document.getElementById('bg-id');
// в переменной bg находится элемент нашего DOM Дерева.
console.log(bg);
getElementsByTagName() - получаем псевдомассив по тегу (Даже если будет один элемент, мы все равно получим псевдомассив)
const btns = document.getElementsByTagName('button');
console.log(btns);
Для получения нужного элемента указываем индекс.
const btns = document.getElementsByTagName('button')[2];
console.log(btns);
// или же указываем уже у готовой html коллекции при использовании console.log(btns[2]);
getElementsByClassName() - получаем по имени класса
// Точку не ставим, этот метод уже знает, что работает с классом
const className = document.getElementsByClassName('bg');
console.log(className);
До этого мы получали html коллекции(HTMLCollection), c querySelectorAll мы будем получать NodeList. Это все псевдомассивы, но разница в том, что у NodeList есть метод forEach и еще пара методов. Их все можно узнать с помощью console.dir(). Напомню, что псевдомассив - это тоже самое, что и обычный массив, но только не имеющий методов обычного массива.
querySelectorAll()
- позволяет получать псевдомассив за счет селекторов css
const inSection = document.querySelectorAll('.bg'); // тут мы получаем через класс, здесь обязательно ставить точку
const bgId = document.querySelectorAll('#bg-id'); // через решетку получаем id
Все тоже самое, только получаем самый первый элемент который встретит (ПОЛУЧАЕМ ЭЛЕМЕНТ, НЕ ПСЕВДОМАССИВ!).
const inSectionOneElement = document.querySelector('.bg');
console.log(inSectionOneElement); // получили самый первый bg
Так же если нам нужно получить элемент внутри какого-то родителя, а этого родителя мы уже получили, то нам не обязательно использовать document
Например:
const section = document.querySelector('.section'); // наш родитель
// пишем вместо document нашу переменную с родителем
const inSection = section.querySelectorAll(.bg); // мы говорим получить наши элементы которые находятся только ВНУТРИ section
Вторая фишка - мы можем сразу указать нужный тег при получении.
const section = document.querySelector('.section div'); // получаем первый div в .section
// если будем использовать querySelectorAll, то получим все div.
Здесь нам поможет console.dir()
- напомню, что этот метод отображает список свойств указанного JavaScript объекта
const inSectionOneElement = document.querySelector('.bg');
console.dir(inSectionOneElement); // смотрим на элемент в качестве объекта
В консоли браузера мы с помощью этой команды можем увидеть все свойства этого элемента(все что можем с ним сделать!)
Так же мы можем узнать нужные стили, что бы поменять их. для этого ищем объект style
, внутри этого объекта находятся все css
свойства которые мы можем применить. Это все inline
стили (inline
стили самые важные!).
inline
стили перебивают остальные. Сделано это для того, что бы с помощью js
мы могли манипулировать такими стилями.
Внутри объекта style находим нужные css свойства.
const inSectionOneElement = document.querySelector('.bg');
const btns = document.querySelectorAll('button');
// обращаемся к нашему элементу и далее к объекту style внутри него и к backgroundColor внутри style
inSectionOneElement.style.backgroundColor = 'green';
// в js все css свойства пишем через CamelCase.
inSectionOneElement.style.width = '100px'; // указываем все строками и с четкими ед измерениями
btns[0].style.borderRadius = '100%'; // выбираем нашу первую кнопочку из псевдо массива..
Так же с помощью свойства cssText, можно вставлять строки прямо в style.
const inSectionOneElement = document.querySelector('.bg');
let red = 'red';
inSectionOneElement.style.cssText = `background-color: ${red}; width: 400px;`; // пишем уже обычный css код. Так же можем пользоваться интерполяцией
Меняем сразу несколько элементов с помощью цилка for (редко используется)
const btns = document.querySelectorAll('button');
for (let i = 0; i < btns.length; i++) { // говорим, что перебираем пока не закончатся элементы в нашем псевдомассиве
btns[i].style.backgroundColor = 'green'; // обращаемся к нашему псевдомассиву и будем получать каждый элемент начиная с 0 (так как i = 0)
}
Но легче использовать forEach()
const btns = document.querySelectorAll('button');
btns.forEach(item => {
item.style.backgroundColor ='green';
});
createElement()
- создает элемент.
const div = document.createElement('div'); // Обращаемся к документу, к методу createElement('Тут элемент который хотим создать')
// после элемент создан, но он хранится пока что только внутри js файла.
createTextNode()
- Текстовый узел, элемент без оболочки тега
const text = document.createTextNode('Тут был я'); // создали текст.
Для работы с селекторами используем свойство classList
const div = document.createElement('div');
div.classList.add('black'); // add - это метод у свойства classList
//add() - добавляет класс к элементу
Есть также старое свойство className, оно больше не используется.
append()
- помещает наш элемент в самый конец.
const div = document.createElement('div');
div.classList.add('black');
document.body.append(div); // в нашем случае мы в конец body кладем div который создали.
Так же можем при получении родителя, добавить в него элемент.
document.querySelector('.section').append(div); // Мы получили наш элемент по селектору и в него сразу добавили div
prepend()
- помещает элемент в самое начало.
const section = document.querySelector('.section');
section.prepend(div);
before()
и after()
- говорим перед before
каким элементом вставить наш элемент или после after
какого.
const div = document.createElement('div');
const div2 = document.createElement('div');
div.classList.add('black');
div2.classList.add('red');
const inSection = document.querySelectorAll('.bg');
inSection[1].before(div); // ставим наш див перед 1 элементом (по индексу)
inSection[2].after(div2); // ставим после 2 элемента наш див (все по индексу!)
remove()
- удаляет элемент.
replaceWith()
- заменяет один элемент на другой
const inSection = document.querySelectorAll('.bg'); // получули все из section
const btns = document.querySelectorAll('button'); // получили button
inSection[0].replaceWith(btns[0]); // поменяли первый элемент в section на первый элемент из btns
inSection.forEach(item => { // удалили все элементы из section
item.remove();
});
Так как в inSection находятся только div с классом bg которые мы получили, то кнопка которой мы заменили div осталась.
appendChild()
- по сути тот же append.
insertBefore()
- указываем перед каким эдементом вставить наш. 2 аргумента первый - это то что вставляем, а второй, перед чем.
removeChild()
- Обращаемся к родителю и пишем какой элемент удалить section.removeChild(inSection[1])
replaceChild()
- тот же replaceWith()
только супер неудобный section.replaceChild(div,inSection[0])
replaceChild()
- два аргумента. 1 - тот элемент на который хотим менять 2 - то, что меняем и опять через родителя.
Старые способы очень неудобные! Но знать как они выглядят нужно.
innerHTML
- добавляет html код
const div = document.createElement('div');
const section = document.querySelector('.section');
div.innerHTML = '<h1> ПРивет </h1>'; // добавили в див h1 с текстом. Можно и просто без тега вставить текст.
section.append(div);
textContent
- Добавляет только текст
Сделано это для безопасности. Когды мы получаем данные прямо от пользователя (может ввел в модал окне и тд)
суть такова, что если мы будем использовать innerHTML то пользователь сможет менять структуру DOM и сломать верстку. Поэтому для простого текста используется textContent.
insertAdjacentHTML
- позволяет вставлять html
код но так же указывать перед каким элементом или после
Принимает два аргумента. 1 - это позиция. 2 - тот html
код который нужно вставить.
В первый аргумент принимается 4 значения:
beforebegin
- вставляет html
структуру перед элементом (до открывающего тега).afterbegin
- вставялет структуру вначало ВНУТРИ элемента (перед первым потомком).beforeend
- вставляет в конец структуру внутри! (после последнего потомка).afterend
- после элемента (после закрывающего тега).const section = document.querySelector('.section');
section.insertAdjacentHTML('afterbegin', '<h2> привет </h2>');