IE支持DOM importNode

时间:2009-11-28 00:28:00

标签: javascript internet-explorer dom

我一直在寻找网络,我很确定我已经知道答案(“不”),但我想查一下:

IE是否支持importNode()?有没有比走DOM和创建节点更好的选择? (我已经看过the clasic article by Anthony Holdener但现在已经超过一年了,而且我希望IE已经进化,或者有人有另一个工作周期)

感谢。

3 个答案:

答案 0 :(得分:5)

Internet Explorer 9 DOM API中有一个函数document.importNode()。但是,IE9在调用

时会抛出脚本错误
  

SCRIPT16386:不支持此类接口

还需要定义源节点的命名空间(例如,当我们要导入SVG时 - In IE9, Imported nodes do not seem to be recognized as SVG Elements

Phrogz建议this有用的解决方法。但是,当我们导入具有特殊命名空间的元素(在xmlns属性中声明,例如<svg xmlns="http://www.w3.org/2000/svg" …>…</svg>)时,clone.setAttributeNS(a.namespaceURI,a.nodeName,a.nodeValue)中会出现错误,因为属性xmlns的namespaceURI为空。

有适合​​我的解决方法:

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;
  }
}

答案 1 :(得分:4)

我还没有听说过这种情况已经发生了变化,在John Resig的recent post中,他说:

  

Internet Explorer不支持importNode或adoptNode

另请参阅cross-browser importnode()上的这篇A List Apart文章,因为它包含了针对Internet Explorer的特定解决方法。

引用后代,

  

我所有问题的解决方案是毕竟不使用DOM方法,而是使用我自己的实现。在这里,它的所有荣耀,是我以跨浏览器兼容的方式编码的importNode()问题的最终解决方案:(换行标记为»-Ed。)

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;
}

答案 2 :(得分:-1)

对于更轻量级的解决方案(假设您不介意添加依赖项),您可以始终使用jQuery:

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

这会在dom_to_import的末尾添加'element-to-import-into'