IE поддерживает DOM importNode - PullRequest
5 голосов
/ 28 ноября 2009

Я искал в Интернете, и я почти уверен, что уже знаю ответ («нет»), но я хотел бы проверить:

IE еще поддерживает importNode ()? Есть ли лучшая альтернатива, чем ходить по DOM и создавать узлы? (Я видел классическую статью Энтони Холденера , но ей уже больше года, и я надеюсь, что либо IE эволюционировал, либо у кого-то есть другое решение)

Спасибо.

Ответы [ 3 ]

5 голосов
/ 27 марта 2012

В API Internet Explorer 9 DOM есть функция document.importNode (). Тем не менее, IE9 выдает ошибку сценария, когда он называется

SCRIPT16386: такой интерфейс не поддерживается

Также необходимо определить пространство имен исходного узла (например, когда мы хотим импортировать SVG - * В IE9 импортированные узлы, похоже, не распознаются как элементы SVG )

Phrogz предложил этот полезный обходной путь. Однако, когда мы импортируем элемент со специальным пространством имен (объявленным в атрибуте xmlns, например, <svg xmlns="http://www.w3.org/2000/svg" …>…</svg>), будет ошибка в clone.setAttributeNS(a.namespaceURI,a.nodeName,a.nodeValue), поскольку namespaceURI для атрибута xmlns имеет значение null.

Есть обходной путь, который мне подходит:

var newNode;
try {
  newNode = document.importNode(sourceDocumentElement, true);
}
catch(e) {
  newNode = importNode(sourceDocumentElement, true);
}

function importNode(node, allChildren) {
  switch (node.nodeType) {
    case document.ELEMENT_NODE:
      var newNode = document.createElementNS(node.namespaceURI, node.nodeName);
      if(node.attributes && node.attributes.length > 0)
        for(var i = 0, il = node.attributes.length; i < il; i++)
          newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i].nodeName));
      if(allChildren && node.childNodes && node.childNodes.length > 0)
        for(var i = 0, il = node.childNodes.length; i < il; i++)
          newNode.appendChild(importNode(node.childNodes[i], allChildren));
      return newNode;
      break;
    case document.TEXT_NODE:
    case document.CDATA_SECTION_NODE:
    case document.COMMENT_NODE:
      return document.createTextNode(node.nodeValue);
      break;
  }
}
4 голосов
/ 28 ноября 2009

Я не слышал, чтобы это изменилось, и в недавнем сообщении Джона Резига *1002* он утверждает:

Internet Explorer не поддерживает importNode или acceptNode

Также см. Эту статью A List Apart по кросс-браузерный importnode () , поскольку он включает специальный обходной путь для Internet Explorer.

Цитировать для потомков,

Решением всех моих проблем было не использовать метод DOM, а использовать собственную реализацию. Здесь, во всей своей красе, мое окончательное решение проблемы importNode (), закодированное кросс-браузерным способом: (Обтекание строк отмечено »- Ред.)

if (!document.ELEMENT_NODE) {
  document.ELEMENT_NODE = 1;
  document.ATTRIBUTE_NODE = 2;
  document.TEXT_NODE = 3;
  document.CDATA_SECTION_NODE = 4;
  document.ENTITY_REFERENCE_NODE = 5;
  document.ENTITY_NODE = 6;
  document.PROCESSING_INSTRUCTION_NODE = 7;
  document.COMMENT_NODE = 8;
  document.DOCUMENT_NODE = 9;
  document.DOCUMENT_TYPE_NODE = 10;
  document.DOCUMENT_FRAGMENT_NODE = 11;
  document.NOTATION_NODE = 12;
}

document._importNode = function(node, allChildren) {
  switch (node.nodeType) {
    case document.ELEMENT_NODE:
      var newNode = document.createElement(node »
.nodeName);
      /* does the node have any attributes to add? */
      if (node.attributes && node.attributes »
.length > 0)
        for (var i = 0; il = node.attributes.length;i < il)
          newNode.setAttribute(node.attributes[i].nodeName, 
          node.getAttribute(node.attributes[i++].nodeName));
      /* are we going after children too, and does the node have any? */
      if (allChildren && node.childNodes && node.childNodes.length > 0)
        for (var i = 0; il = node.childNodes.length; i < il)
          newNode.appendChild(document._importNode(node.childNodes[i++], allChildren));
      return newNode;
      break;
    case document.TEXT_NODE:
    case document.CDATA_SECTION_NODE:
    case document.COMMENT_NODE:
      return document.createTextNode(node.nodeValue);
      break;
  }
};

Вот оно используется:

var newNode = null, importedNode = null;

newNode = xhrResponse.responseXML.getElementsByTagName('title')[0].childNodes[0];
if (newNode.nodeType != document.ELEMENT_NODE)
  newNode = newNode.nextSibling;
if (newNode) {
  importedNode = document._importNode(newNode, true);
  document.getElementById('divTitleContainer').appendChild(importedNode);
  if (!document.importNode)
    document.getElementById('divTitleContainer').innerHTML = document.getElementById('divTitleContainer').innerHTML;
}
0 голосов
/ 16 марта 2011

Для более легкого решения (при условии, что вы не возражаете против добавления зависимости) вы всегда можете использовать jQuery:

$(dom_to_import_into).find('element-to-import-into').append($(dom_to_import).clone());

Это добавит dom_to_import в конце 'element-to-import-into'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...