Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Использование DOM (Document Object Model)
DOM (Document Object Model) — это программный интерфейс для работы с HTML и XML документами. Он представляет структуру документа в виде иерархического дерева объектов, позволяя скриптам (обычно JavaScript) читать, изменять и удалять элементы страницы.
Основное назначение DOM
DOM используется для:
- Манипуляция структурой страницы — добавление, удаление, изменение элементов
- Изменение стилей — динамическое применение CSS
- Обработка событий — реакция на клики, вводы, скроллы и т.д.
- Получение данных — чтение значений из форм и элементов
- Создание интерактивности — динамическое обновление содержимого без перезагрузки
Структура DOM
DOM представляет HTML как дерево:
<!DOCTYPE html>
<html>
<head>
<title>Пример</title>
</head>
<body>
<div id="main">
<p class="text">Привет</p>
<button>Нажми меня</button>
</div>
</body>
</html>
В памяти браузера это выглядит как дерево объектов:
Document
├── html (HTMLElement)
│ ├── head (HTMLElement)
│ │ └── title (HTMLElement) "Пример"
│ └── body (HTMLElement)
│ └── div#main (HTMLElement)
│ ├── p.text (HTMLElement) "Привет"
│ └── button (HTMLElement) "Нажми меня"
API для работы с DOM
Выбор элементов:
// По ID
const element = document.getElementById('main');
// По селектору
const para = document.querySelector('p.text');
const allParas = document.querySelectorAll('p');
// По тегу
const divs = document.getElementsByTagName('div');
// По классу
const textElements = document.getElementsByClassName('text');
Изменение содержимого:
const el = document.getElementById('main');
// Изменить текст
el.textContent = 'Новый текст';
// Изменить HTML
el.innerHTML = '<span>HTML содержимое</span>';
// Создать новый элемент
const newDiv = document.createElement('div');
newDiv.textContent = 'Новый div';
el.appendChild(newDiv);
// Удалить элемент
el.removeChild(newDiv);
// или
newDiv.remove();
Работа с атрибутами:
const input = document.querySelector('input');
// Получить атрибут
const value = input.getAttribute('placeholder');
// Установить атрибут
input.setAttribute('placeholder', 'Введи текст');
// Проверить наличие
if (input.hasAttribute('disabled')) {
input.removeAttribute('disabled');
}
// Использовать свойства
input.value = 'Новое значение';
input.disabled = true;
Работа с классами:
const btn = document.querySelector('button');
// Добавить класс
btn.classList.add('active');
// Удалить класс
btn.classList.remove('active');
// Переключить класс
btn.classList.toggle('active');
// Проверить наличие
if (btn.classList.contains('active')) {
// ...
}
Навигация по дереву:
const el = document.querySelector('p');
// Родитель
const parent = el.parentElement;
// Дети
const children = el.children;
const firstChild = el.firstElementChild;
const lastChild = el.lastElementChild;
// Соседи
const next = el.nextElementSibling;
const prev = el.previousElementSibling;
События DOM
Основной механизм интерактивности:
const button = document.querySelector('button');
// Слушатель события
button.addEventListener('click', (event) => {
console.log('Кнопка нажата');
event.preventDefault(); // Отменить действие по умолчанию
});
// Другие события
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM загружена');
});
window.addEventListener('resize', () => {
console.log('Окно изменено');
});
const input = document.querySelector('input');
input.addEventListener('change', (e) => {
console.log('Значение изменилось:', e.target.value);
});
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
console.log('Нажата Enter');
}
});
Производительность DOM
Проблемы:
// ❌ Плохо: перерисовка после каждого добавления
const container = document.getElementById('container');
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
div.textContent = `Item ${i}`;
container.appendChild(div); // Каждое добавление вызывает перерисовку!
}
// ✅ Хорошо: батчинг изменений
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
div.textContent = `Item ${i}`;
fragment.appendChild(div);
}
container.appendChild(fragment); // Одна перерисовка
// ✅ Или innerHTML
const html = Array.from({ length: 1000 })
.map((_, i) => `<div>Item ${i}</div>`)
.join('');
container.innerHTML = html;
Оптимизация:
// Избегай частых обращений к DOM
const container = document.getElementById('main');
let height = 0;
// ❌ Плохо
for (let i = 0; i < 1000; i++) {
height += document.getElementById('main').offsetHeight; // N+1 обращений!
}
// ✅ Хорошо
const mainHeight = container.offsetHeight;
for (let i = 0; i < 1000; i++) {
height += mainHeight;
}
// Используй requestAnimationFrame для анимаций
function animate() {
element.style.left = `${x}px`;
requestAnimationFrame(animate);
}
DOM в современных фреймворках
В React, Vue, Angular DOM изменяется косвенно через фреймворк:
// React (JSX)
function MyComponent() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Увеличить
</button>
</div>
);
}
// Vue
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="count++">Увеличить</button>
</div>
</template>
Фреймворки автоматически обновляют DOM через Virtual DOM или реактивность.
Практический пример
// Простой список задач
class TodoApp {
private todos: string[] = [];
private todoList = document.getElementById('todo-list');
private input = document.querySelector('input');
private addBtn = document.querySelector('button');
constructor() {
this.addBtn.addEventListener('click', () => this.addTodo());
this.input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') this.addTodo();
});
}
addTodo(): void {
const text = this.input.value.trim();
if (!text) return;
this.todos.push(text);
this.input.value = '';
this.render();
}
render(): void {
this.todoList.innerHTML = this.todos
.map((todo, i) => `
<li>
${todo}
<button data-index="${i}">Удалить</button>
</li>
`)
.join('');
// Добавить обработчики для кнопок
this.todoList.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', (e) => {
const index = parseInt(e.target.dataset.index);
this.todos.splice(index, 1);
this.render();
});
});
}
}
new TodoApp();
Вывод
DOM — это критический API для фронтенда:
- Выбор элементов — querySelector, getElementById
- Изменение содержимого — textContent, innerHTML
- Работа с событиями — addEventListener
- Навигация по дереву — parentElement, children
- Производительность — батчинг, fragment
Это основа интерактивности веб-приложений. В современных приложениях DOM обновляется фреймворками, но понимание его работы критично для оптимизации производительности.