Один узел имеет одно место в дереве
DOM представляет документ как дерево связанных узлов. У обычного элемента, находящегося внутри другого элемента, есть родитель. Когда существующий узел передают методу appendChild другого допустимого родителя, он перемещается в конец списка его дочерних узлов. Представим два списка: ожидающие задачи и выполненные. Одна карточка находится в первом. Если добавить именно этот объект во второй список, карточка сменит родителя. Предварительно удалять её отдельной операцией для такого переноса не требуется. Но и независимая вторая карточка сама собой не появляется.
Копирование создаёт другой объект
Если нужны два отдельных экземпляра, можно создать новый элемент или использовать cloneNode. Параметр этого метода определяет, копируется ли также содержимое поддерева. Без глубокого копирования вложенные узлы, включая текстовые, не переносятся в новый экземпляр автоматически. Клон после создания ещё не включён в документ: его нужно добавить в нужное место. Изменения оригинала и копии также не синхронизируются сами собой. Поэтому перед операцией сформулируйте задачу: перенести существующую карточку, получить независимый экземпляр или показывать одни данные в нескольких представлениях. Это разные решения.
Похожий вид не гарантирует одинаковое поведение
При клонировании копируются атрибуты, поэтому можно случайно получить повторяющийся идентификатор. Его нужно проверить перед размещением копии в том же документе. Обработчики, добавленные через addEventListener, методом cloneNode не копируются. Следовательно, визуально одинаковые кнопки могут реагировать по-разному. Для отладки проверяйте дерево и поведение отдельно. Сначала выясните, сколько объектов создано и кто является родителем каждого. Затем посмотрите содержимое и атрибуты, после этого проверьте необходимые действия. Такая последовательность помогает не лечить стилями проблему структуры и не считать совпадение внешнего вида доказательством полной готовности элемента.
Попробуйте на практике
Разберите на бумаге перенос и копирование карточки между двумя списками.
- Нарисуйте два контейнера и одну карточку внутри первого, обозначив связь с родителем.
- Изобразите результат добавления существующей карточки во второй контейнер методом appendChild.
- Вернитесь к исходной схеме, создайте отдельную копию карточки и только её разместите во втором контейнере.
- Для варианта с копией составьте проверки содержимого, уникальности идентификатора и нужного поведения кнопок.
Как проверить результат. После переноса на схеме остаётся одна карточка во втором контейнере. После копирования существуют два разных узла. Новый клон сначала не имеет родителя, а после вставки получает его. Нельзя автоматически считать, что обработчики событий оригинала появились у копии.
Частые вопросы
Если две переменные ссылаются на карточку, карточек становится две?
Нет. Несколько переменных могут указывать на один и тот же объект. Для понимания результата нужно считать созданные узлы, а не имена переменных. Перенос общего объекта будет виден через любую ссылку на него.
Нужно ли всегда использовать глубокое клонирование?
Нет. Оно требуется, когда нужен также набор вложенных узлов. Иногда достаточно нового пустого элемента, который затем заполняют отдельно. Выбор зависит от задачи; после клонирования всё равно проверяют атрибуты, связи и необходимое поведение.
Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.