Книга: JavaScript. Подробное руководство, 6-е издание

15.6.4. Использование объектов DocumentFragment

15.6.4. Использование объектов DocumentFragment

Объекты DocumentFragment - это особая разновидность объектов Node; они служат временным контейнером для других узлов. Создаются объекты DocumentFragment следующим образом:

var frag = document.createDocumentFragment();

Как и узел Document, объекты DocumentFragment являются самостоятельными и не входят в состав какого-либо другого документа. Его свойство parentNode всегда возвращает значение null. Однако, как и узлы Element, объекты DocumentFragment могут иметь любое количество дочерних элементов, которыми можно управлять с помощью методов appendChild(), insertBefore() и т. д.

Одна из особенностей объекта DocumentFragment состоит в том, что он позволяет манипулировать множеством узлов как единственным узлом: если объект DocumentFragment передать методу appendChild(), insertBefore() или replaceChild(), в документ будут вставлены дочерние элементы фрагмента, а не сам фрагмент. (Дочерние элементы будут перемещены из фрагмента в документ, а сам фрагмент опустеет и будет готов для повторного использования.) Следующая функция использует объект DocumentFragment для перестановки в обратном порядке дочерних элементов узла:

// Выполняет перестановку дочерних элементов узла n в обратном порядке
function reverse(n) {
  // Создать пустой объект DocumentFragment, который будет играть роль
  // временного контейнера
  var f = document.сreateDocumentFragment();
  // Выполнить обход дочерних элементов в обратном порядке и переместить каждый
  // из них в объект фрагмента. Последний дочерний элемент узла n станет первым
  // дочерним элементом фрагмента f, и наоборот. Обратите внимание, что при добавлении
  // дочернего элемента в фрагмент f он автоматически удаляется из узла n.
  while(n.lastChild) f.appendChild(n.lastChild);
  // В заключение переместить сразу все дочерние элементы
  // из фрагмента f обратно в узел n.
  n.appendChild(f);
}

В примере 15.6 представлена реализация метода insertAdjacentHTML() (раздел 15.5.1) с применением свойства innerHTML и объекта DocumentFragment. В нем также определяются функции вставки разметки HTML с более логичными именами, чем неочевидное insertAdjacentHTML(). Вложенная вспомогательная функция fragment() является, пожалуй, наиболее интересной частью этого примера: она возвращает объект DocumentFragment, содержащий разобранное представление указанной ей строки с разметкой HTML.

Пример 15.6. Реализация метода insertAdjacentHTML() с использованием свойства innerHTML

// Этот модуль определяет метод Element.insertAdjacentHTML для броузеров,
// не поддерживающих его, а также определяет переносимые функции вставки HTML,
// имеющие более логичные имена, чем имя insertAdjacentHTML:
// Insert.before(), Insert.after(), Insert.atStart(), Insert.atEnd()
var Insert = (function() {
  // Если элементы имеют собственный метод insertAdjacentHTML, использовать
  // его в четырех функциях вставки HTML, имеющих более понятные имена,
  if (document.createElement("div").insertAdjacentHTML) {
    return {
      before: function(e,h) {e.insertAdjacentHTML("beforebegin",h);},
      after: function(e,h) {e.insertAdjacentHTML("afterend",h);},
      atStart: function(e,h) {e.insertAdjacentHTML("afterbegin",h);},
      atEnd: function(e,h) {e.insertAdjacentHTMLC'beforeend",h);}
    };
  }
  // Иначе, в случае отсутствия стандартного метода insertAdjacentHTML,
  // реализовать те же самые четыре функции вставки и затем использовать их
  // в определении метода insertAdjacentHTML.
  // Сначала необходимо определить вспомогательный метод, который принимает
  // строку с разметкой HTML и возвращает объект DocumentFragment,
  // содержащий разобранное представление этой разметки
  function fragment(html) {
    var elt = document.createElement("div"); // Пустой элемент
    var frag = document.createDocumentFragment(); // Пустой фрагмент
    elt.innerHTML = html; // Содержимое элемента
    while(elt.firstChild) // Переместить все узлы
      frag.appendChild(elt.firstChild); // из elt в frag
    return frag; // И вернуть frag
  }
  var Insert = {
    before: function(elt, html) {
      elt.parentNode.insertBefore(fragment(html), elt):
    },
    after: function(elt, html) {
      elt.parentNode.insertBefore(fragment(html),elt.nextSibling);
    },
    atStart: function(elt, html) {
      elt.insertBefore(fragment(html), elt.firstChild);
    },
    atEnd: function(elt, html) { elt.appendChild(fragment(html)); }
  };
  // Реализация метода insertAdjacentHTML на основе функций выше
  Element.prototype.insertAdjacentHTML = function(pos, html) {
    switch(pos.toLowerCase()) {
    case "beforebegin": return Insert.before(this, html);
    case "afterend": return Insert.after(this, html);
    case "afterbegin": return Insert.atStart(this, html);
    case "beforeend": return Insert.atEnd(this, html);
    }
  };
  return Insert; // Вернуть четыре функции вставки
}());

Оглавление книги


Генерация: 1.186. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз