Манипуляции с DOM на чистом JavaScript JavaScript DOM


Оглавление (нажмите, чтобы открыть):

Манипуляции с DOM на чистом JavaScript JavaScript DOM

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

innerHTML

Самый простой способ обновить часть DOM — это функция innerHTML

Эта функция целиком заменяет потомков элемента, на котором она была вызвана. Весь встречающийся внутри html парсится и становится частью дерева. Если вы пытаетесь вставить обычный текст, который потенциально может содержать html , то лучше воспользоваться другой, безопасной функцией textContent .

Работа с DOM

Введение в DOM

Одой из ключевых задач JavaScript является взаимодействие с пользователем и манипуляция элементами веб-страницы. Для JavaScript веб-страница доступна в виде объектной модели документа (document object model) или сокращенно DOM. DOM описывает структуру веб-станицы в виде древовидного представления и предоставляет разработчикам способ получить доступ к отдельным элементам веб-станицы.

Важно не путать понятия BOM (Browser Object Model — объектная модель браузера) и DOM (объектная модель документа). Если BOM предоставляет доступ к браузеру и его свойствам в целом, то DOM предоставляет доступ к отдельной веб-странице или html-документу и его элементам.

Например, рассмотрим простейшую страницу:

Дерево DOM для этой страницы будет выглядеть следующим образом:

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

Существует следующие виды узлов:

Attr : атрибут html-элемента

Document : корневой узел html-документа

DocumentType : DTD или тип схемы XML-документа

DocumentFragment : место для временного хранения частей документа

EntityReference : ссылка на сущность XML-документа

ProcessingInstruction : инструкция обработки веб-страницы

Comment : элемент комментария

Text : текст элемента

CDATASection : секция CDATA в документе XML

Entity : необработанная сущность DTD

Notation : нотация, объявленная в DTD

Несмотря на такое большое количество типов узлов, как правило, мы будем работать только с некоторыми из них.


Манипуляции с DOM

А теперь я буду долго и нудно рассказывать о том, как с помощью jQuery можно изменять DOM дерево на странице, т.е. добавлять и удалять элементы, но чего это я, глава в действительности не будет объёмной 🙂

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

Этот пример вполне рабочий, да вот только производительностью он блистать не будет, ведь внутри будет всё это разбираться с помощью метода «jQuery.parseHTML()», который совсем не быстрый. Но мы можем помочь парсеру если атрибуты элемента будем передавать вторым параметром:

Можем сделать ещё проще:

И этот способ будет работать даже быстрее (ну совсем капельку), но почему? Для того, чтобы ответить на данный вопрос – загляните в код jQuery, в самую главную функцию «init()», в её коде можно найти алгоритм разбора предыдущего примера:

  1. Парсим строку, и создаём DOM элемент в jQuery обёртке
  2. Заходим в цикл обработки переданных параметров:
    • Проверяем, а нет ли функции у нашего элемента с таким названием
    • Если нет, то устанавливаем атрибут элемента используя метод attr()

Выводы делайте сами, гдe мы тут время потеряли 🙂

Ну и на последок опишу самый быстрый способ, который я часто использую:

Да, это и есть «чистый» JavaScript, но как по мне – в данном случае он не менее удобен любых фреймворков. И вот вам домашнее задание – оптимизируйте такой скрипт:

Выполняйте тут, бумага стерпит:

Все необходимые нам методы собраны в одном разделе документации – Manipulation, с некоторыми из них мы уже познакомились, и осталось совсем чуть-чуть:

after(content) — вставляет контент после каждого элемента из выборки, т.е. если вы встречаете строку «$(«p»).after(» «)», читайте её как «после каждого параграфа будет вставлена линия»

insertAfter(element) — вставляет элементы из выборки после каждого элемента переданного в качестве аргумента, т.е. если вы встречаете строку «$(» «).insertAfter(«p»)» – читайте её как «линия будет вставлена после каждого параграфа»

— Хм, а я разницы не увидел! — тут всё легко, присмотритесь:

before(content) — вставляет контент перед каждым выбранным элементом

insertBefore(element) — вставляет элементы из выборки перед каждым элементом переданным в качестве аргумента

append(content) — вставляет контент в конец каждого элемента из выборки, т.е. строку кода «$(«p»).append(» «)», следует читать как «в конец каждого параграфа будет добавлена линия»

appendTo(element) — вставляет выбранный контент в конец каждого элемента переданного в качестве аргумента: «$(» «).appendTo(«p»)» — «линия будет добавлена в конец каждого параграфа»

Опять про разницу:

prepend(content) — вставляет контент в начало каждого элемента из выборки


prependTo(element) — вставляет выбранный контент в начало каждого элемента переданного в качестве аргумента

Так, с этим кусочком документации вроде как разобрались, опять же – почувствуйте разницу перечисленных методов, ведь дальше будут ещё:

replaceWith(content) – заменяет найденные элементы новым

replaceAll(target) – вставляет контент в замен найденному

wrap(element) – оборачиваем каждый найденный элемент новым элементом, т.е. мы конфеты из коробки заворачиваем в фантики

wrapAll(element) – оборачивает найденные элементы новым элементом, мы берём все конфеты, и заворачиваем в один большой фантик

wrapInner(element) – оборачивает контент каждого найденного элемента новым элементом, берём конфеты, убираем фантики, заворачиваем в свой фантик, и сверху заворачиваем в родной фантик

unwrap() – удаляет родительский элемент у найденных элементов, фантики вон

clone(withDataAndEvents) – клонирует выбранные элементы, для дальнейшей вставки копий назад в DOM, позволяет так же копировать и обработчики событий

detach() – удаляет элемент из DOM, но при этом сохраняет все данные о нём в jQuery, следует использовать, если надо удалить элемент, а потом вернуть его обратно

empty() – удаляет текст и дочерние DOM элементы

remove() – удаляет элемент из DOM, насовсем

html() – вернёт HTML заданного элемента

html(newHtml) – заменит HTML в заданном элементе

Мастер Йода рекомендует:  Табличная вёрстка

text() – вернёт текст заданного элемента, если внутри элемента будут другие HTML тэги, то вернётся сборная солянка из текста всех элементов

text(newText) – заменит текст внутри выбранных элементов, при попытке вставить таким образом HTML, будет получен текст, где тэги будут приведены к HTML entities:

Переварили? Хорошо, теперь настал черёд методов, которые работают с размерами, и знают координаты элементов:

Но прежде чем продолжить, хотелось бы освежить в памяти информацию о вычислении высоты и ширины блочных элементов 😉

offset() – вернёт позицию DOM элемента относительно document’а, данные будут получены в виде объекта: «< top: 10, left: 30 >«

offset(< top: 10, left: 30 >) – устанавливаем расположение DOM элемента по указанным координатам

position() – вернёт позицию DOM элемента относительно родительского элемента

height() – возвращает высоту элемента за вычетом отступов и границ; если у нас несколько элементов в выборке, вернётся первый; значение, в отличии от метода «css(‘height’)», возвращается без указания единиц измерения

height(height) — устанавливает высоту всех элементов в выборке, если значение высоты передано без указания единиц измерения, то это будут «px»

width() и width(width) – ведут себя аналогично методу «height()», но работают с шириной элемента

Методы «height()» и «width()» не изменяют своего поведения в зависимости от выбранной блочной модели, т.е. они всегда возвращают параметры области внутри margin, padding и border’а элемента.


innerHeight() и innerWidth() – вернут соответственно высоту и ширину элемента, включая «padding»

outerHeight() и outerWidth() – вернут высоту и ширину элемента, включая «padding» и «border»

outerHeight(true) и outerWidth(true) – высота и ширина, включая «padding», «border» и «margin»

Для наглядности различий между методами «height()», «innerHeight()» и «outerHeight()» я создал страничку, а ещё переделал несколько картинок из официальной документации в одну полноценную иллюстрацию:

Получаем высоту

Лишь значение height

Значение height + padding

Значение height + padding + border

Значение height + padding + border + margin

Удалить все дочерние элементы узла DOM в JavaScript

как я могу удалить все дочерние элементы узла DOM в JavaScript?

скажем, у меня есть следующий (уродливый) HTML:

и я хватаю узел, который я хочу так:

как я мог удалить детей foo Так что просто

могу я просто сделать:

или я должен использовать некоторые комбинации removeElement ?

Я хотел бы, чтобы ответ был прямым до дома; хотя дополнительные очки, если вы также предоставляете ответ в jQuery вместе с ответом только DOM.

25 ответов

Вариант 1 (намного медленнее, см. комментарии ниже):

Вариант 2 (намного быстрее):

в настоящее время принятый ответ неверен о том, что innerHTML медленнее (по крайней мере, в IE и Chrome), Как правильно упоминалось m93a.

Chrome и FF значительно быстрее, используя этот метод (который уничтожит прикрепленные данные jquery):

в отдаленную секунду для FF и Chrome, и самый быстрый в IE:

innerHTML будет не уничтожит ваши обработчики событий или сломает ссылки jquery, он также рекомендуется в качестве решения здесь: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML

самый быстрый метод манипуляции DOM (все еще медленнее, чем предыдущие два) — удаление диапазона, но диапазоны не поддерживаются до IE9.


другие упомянутые методы кажутся сопоставимыми, но намного медленнее, чем innerHTML, за исключением выброса, jquery (1.1.1 и 3.1.1), который значительно медленнее, чем что-либо еще:

«per-test-loop» Jsperf часто понимается как «per-iteration», и только первая итерация имеет узлы для удаления, поэтому результаты бессмысленны, во время публикации были неправильно настроены тесты в этом потоке.

если есть шанс, что у вас есть jQuery пострадавших потомков, то вы должны используйте некоторый метод, который очистит данные jQuery.

в jQuery .empty() метод гарантирует, что все данные, связанные с удаляемыми элементами jQuery, будут очищены.

если вы просто использовать DOM методы удаления детей, что данные останутся.

JavaScript — Методы DOM HTML

Методы HTML DOM — это действия , которые можно выполнять (в HTML-элементах).

Свойства HTML DOM — это значения (элементов HTML), которые можно задать или изменить.

Интерфейс программирования DOM

Доступ к HTML DOM возможен с помощью JavaScript (и других языков программирования).

В DOM все элементы HTML определяются как объекты.

Интерфейс программирования — это свойства и методы каждого объекта.

свойство — это значение, которое можно получить или задать (например, изменение содержимого элемента HTML).

метод — это действие, которое можно выполнить (например, добавить или удалить элемент HTML).

Примере

В следующем примере изменяется содержимое (InnerHtml) элемента

JavaScript — DOM: добавление и удаление узлов

На этом уроке мы научимся создавать узлы-элементы ( createElement ) и текстовые узлы ( createTextNode ). А также рассмотрим методы, предназначенные для добавления узлов к дереву ( appendChild , insertBefore ) и для удаления узлов из дерева ( removeChild ).

Добавление узлов к дереву

Добавление нового узла к дереву обычно осуществляется в 2 этапа:

  1. Создать необходимый узел, используя один из следующих методов:
    • createElement() — создаёт элемент (узел) с указанным именем (тегом). Метод createElement(element) имеет один обязательный параметр ( element ) — это строка, содержащая имя создаваемого элемент (тега). Указывать имя элемента (тега) в параметре необходимо заглавными буквами. В качестве результата данный метод возвращает элемент, который был создан.
    • createTextNode() — создаёт текстовый узел с указанным текстом. Метод createTextNode(text) имеет один обязательный параметр ( text ) — это строка, содержащая текст текстового узла. В качестве результата данный метод возвращает текстовый узел, который был создан.
  2. Указать место в дереве, куда необходимо вставить узел. Для этого необходимо воспользоваться одним из следующих методов:
    • appendChild() — добавляет узел как последний дочерний узел элемента, для которого вызывается данный метод. Метод appendChild(node) имеет один обязательный параметр это узел ( node ), который Вы хотите добавить. В качестве результата данный метод возвращает добавленный узел.
    • insertBefore() — вставляет узел как дочерний узел элемента, для которого вызывается данный метод. Метод insertBefore(newNode,existingNode) имеет два параметра: newNode (обязательный) — узел, который Вы хотите добавить, existingNode (не обязательный) — это дочерний узел элемента перед которым, необходимо вставить узел. Если второй параметр ( existingNode ) не указать, то данный метод вставит его в конец, т.е. в качестве последнего дочернего узла элемента для которого вызывается данный метод. В качестве результата метод insertBefore() возвращает вставленный узел.

Рассмотрим более сложный пример, в котором добавим к дереву узел LI , содержащий текстовый узел с текстом «Смартфон», в конец списка ul .

Для этого необходимо выполнить следующее:

  1. Создать элемент (узел) LI .
  2. Создать текстовый узел, содержащий текст «Смартфон».
  3. Добавить созданный текстовый узел как последний дочерний узел только что созданному элементу LI
  4. Добавить недавно созданный узел LI как последний дочерний узел элемента ul


Методы appendChild() и insertBefore() при работе с существующими узлами

Работа с существующими узлами методами appendChild() и insertBefore() также осуществляется в 2 этапа:

  1. Получить существующий узел в дереве.
  2. Указать место, куда необходимо вставить узел, с помощью метода appendChild() или insertBefore() . При этом узел будет удалён из предыдущего места.
Мастер Йода рекомендует:  Размеры в jQuery Javascript

Например, добавить существующий элемент li , содержащий текст “Планшет» в начало списка (при этом он будет удалён из предыдущего места):

Задание

  • Имеется два списка в документе. Необходимо переместить элементы из второго списка в первый.
  • Создать список, текстовое поле и 2 кнопки. Написать код на языке JavaScript, который в зависимости от нажатой кнопки добавляет текст, находящийся в текстовом поле, в начало или в конец списка.

Удаление узлов

Удаление узла из дерева осуществляется в 2 этапа:

  1. Получить (найти) этот узел в дереве. Это действие обычно осуществляется одним из следующих методов: getElementById() , getElementsByClassName() , getElementsByTagName() , getElementsByName() , querySelector() или querySelectorAll() .
  2. Вызвать у родительского узла метод removeChild() , которому в качестве параметра необходимо передать узел, который мы хотим у него удалить.
    Метод removeChild() возвращает в качестве значения удалённый узел или null , если узел, который мы хотели удалить, не существовал.

Например, удалить последний дочерний элемент у элемента, имеющего :

Например, удалить все дочерние узлы у элемента, имеющего :

Манипулирование документами

Одной из наиболее распространенных вещей, которые вы хотите сделать при написании веб-страниц и приложений — это каким-то образом манипулировать структурой документа. Обычно это делается с помощью Document Object Model (DOM), набора API для управления разметкой HTML и стилями, которая сильно использует объект и

), а также обеспечивает функциональность, которая является глобальной для документа, например, для получения URL-адреса страницы или создания новых элементов в документе).»> Document . В этой статье мы подробно рассмотрим, как использовать DOM и некоторые другие интересные API, которые могут изменить вашу среду интересными способами.

Предпосылки: Базовая компьютерная грамотность, базовое понимание HTML, CSS и JavaScript — включая объекты JavaScript.
Задача: Чтобы познакомиться с основными API-интерфейсами DOM и другими API-интерфейсами, обычно связанными с DOM и манипулированием документами

Важные части веб-браузера

Веб-браузеры — очень сложные части программного обеспечения с множеством движущихся частей, многие из которых не могут управляться или управляться веб-разработчиком с использованием JavaScript. Вы можете подумать, что такие ограничения — это плохо, но браузеры заблокированы по уважительным причинам, главным образом, в центре внимания безопасности. Представьте себе, что веб-сайт может получить доступ к вашим сохраненным паролям или другой конфиденциальной информации и войти на веб-сайты так, как если бы это были вы?

Несмотря на ограничения, веб-API по-прежнему дают нам доступ к множеству функциональных возможностей, которые позволяют нам многое делать с веб-страницами. Есть несколько действительно очевидных моментов, на которые вы будете регулярно ссылаться в своем коде. Рассмотрим следующую диаграмму, которая представляет основные части браузера, непосредственно участвующие в просмотре веб-страниц: