15.6.3. Удаление и замена узлов

Метод removeChild() удаляет элемент из дерева документа. Но будьте внимательны: этот метод вызывается не относительно узла, который должен быть удален, а (как следует из фрагмента «child» в его имени) относительно родителя удаляемого узла. Этот метод вызывается относительно родителя и принимает в виде аргумента дочерний узел, который требуется удалить. Чтобы удалить узел n из документа, вызов метода должен осуществляться так:

n.parentNode.removeChild(n);

Метод replaceChild() удаляет один дочерний узел и замещает его другим. Этот метод должен вызываться относительно родительского узла. В первом аргументе он принимает новый узел, а во втором - замещаемый узел. Например, ниже показано, как заменить узел n текстовой строкой:

n.parentNode.replaceChild(document.createTextNode("[ ИСПРАВЛЕНО ]"). n);

Следующая функция демонстрирует еще один способ применения метода replaceChild():

// Замещает узел n новым элементом <b> и делает узел п его дочерним элементом,

function embolden(n) {

  // Если вместо узла получена строка, интерпретировать ее как значение

  // атрибута id элемента

  if (typeof n == "string") n = document.getElementByld(n);

  var parent = n.parentNode; // Ссылка на родителя элемента n

  var b = document.сreateElement("b"); // Создать элемент <b>

  parent.replaceChild(b, n); // Заменить n элементом <b>

  b.appendChild(n); // Сделать n дочерним элементом элемента <b>

}

В разделе 15.5.1 было представлено свойство outerHTML элементов и говорилось, что оно не реализовано в текущей версии Firefox. Пример 15.5 демонстрирует, как можно реализовать это свойство в Firefox (и в любом другом броузере, поддерживающем свойство innerHTML, позволяющем расширять объект-прототип Element.prototype и имеющем методы определения методов доступа к свойствам). Здесь также демонстрируется практическое применение методов removeChild() и cloneNode().

Пример 15.5. Реализация свойства outerHTML с помощью свойства innerHTML

И Реализация свойства outerHTML для броузеров, не поддерживающих его.

// Предполагается, что броузер поддерживает свойство innerHTML, возможность

// расширения Element.prototype и позволяет определять методы доступа к свойствам.

(function() {

  // Если свойство outerHTML уже имеется - просто вернуть управление

  if (document.createElement("div").outerHTML) return;

  // Возвращает окружающую разметку с содержимым элемента,

  // на который указывает ссылка this

  function outerHTMLGetter() {

    var container = document.createElement("div");    // Фиктивный элемент

    container.appendChild(this.cloneNode(true));      // Копировать this

                                                      // в фиктивный элемент

    return container.innerHTML;                   // Вернуть содержимое

                                                  // фиктивного элемента

  }

  // Замещает указанным значением value содержимое элемента, на который

  // указывает ссылка this, вместе с окружающей разметкой HTML

  function outerHTMLSetter(value) {

    // Создать фиктивный элемент и сохранить в нем указанное значение

    var container = document.createElement("div");

    container.innerHTML = value;

    // Переместить все узлы из фиктивного элемента в документ

    while(container.firstChild) // Продолжать, пока в контейнере

                                // не останется дочерних элементов

      this.parentNode.insertBefore(container.firstChild, this);

    // И удалить замещаемый узел

    this.parentNode.removeChild(this);

  }

  // Использовать эти две функции в качестве методов чтения и записи свойства outerHTML

  // всех объектов Element. Использовать метод Object.defineProperty, если имеется,

  // в противном случае использовать __defineGetter__ и __defineSetter__.

  if (Object.defineProperty) {

    Object.defineProperty(Element.prototype,

                    "outerHTML",

                    { get: outerHTMLGetter,

                      set: outerHTMLSetter,

                      enumerable: false,

                      configurable: true

                    }):

  }

  else {

    Element.prototype.__defineGetter__("outerHTML", outerHTMLGetter);

    Element.prototype.__defineSetter__("outerHTML", outerHTMLSetter);

  }

}());