Javascript IE对DOM importNode的支持

Javascript IE对DOM importNode的支持,javascript,internet-explorer,dom,Javascript,Internet Explorer,Dom,我一直在网上四处寻找,我相当肯定我已经知道答案(“不”),但我想检查一下: IE支持importNode()吗?有没有比遍历DOM和创建节点更好的选择?(我见过,但现在已经一年多了,我希望要么IE已经进化,要么有人有了另一个工作区) 谢谢。我还没听说这种情况已经改变,在约翰·雷西格的一篇文章中,他说: Internet Explorer不支持importNode或adoptNode 另请参阅上的这篇单独列出的文章,因为它包含Internet Explorer的特定解决方案 为了子孙后代 我所有问

我一直在网上四处寻找,我相当肯定我已经知道答案(“不”),但我想检查一下:

IE支持importNode()吗?有没有比遍历DOM和创建节点更好的选择?(我见过,但现在已经一年多了,我希望要么IE已经进化,要么有人有了另一个工作区)


谢谢。

我还没听说这种情况已经改变,在约翰·雷西格的一篇文章中,他说:

Internet Explorer不支持importNode或adoptNode

另请参阅上的这篇单独列出的文章,因为它包含Internet Explorer的特定解决方案

为了子孙后代

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


对于较轻的解决方案(如果您不介意添加依赖项),您可以始终使用jQuery:

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

这将在
'element-to-import-to-into'
的末尾添加
dom\u-to\u-import
,Internet Explorer 9 dom API中有一个函数文档.importNode()。但是,IE9在调用时会抛出一个脚本错误

SCRIPT16386:不支持此类接口

还需要定义源节点的名称空间(例如,当我们想要导入SVG-)

建议的有用解决方法。但是,当我们导入具有特殊名称空间(在xmlns属性中声明,例如,
)的元素时,
clone.setAttributeNS(a.namespaceURI,a.nodeName,a.nodeValue)
中会出现错误,因为属性xmlns的名称空间URI为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;
  }
}
var新节点;
试一试{
newNode=document.importNode(sourceDocumentElement,true);
}
捕获(e){
newNode=importNode(sourceDocumentElement,true);
}
函数导入节点(节点,所有子节点){
开关(node.nodeType){
案例文档.ELEMENT_节点:
var newNode=document.createElements(node.namespaceURI,node.nodeName);
如果(node.attributes&&node.attributes.length>0)
对于(var i=0,il=node.attributes.length;i0)
for(var i=0,il=node.childNodes.length;i
这是一种很好的通用方法,但是您需要
document.createComment
来响应
COMMENT_节点
;将其转换为文本节点可能不是一个好主意。不幸的是,在IE中的HTML元素上使用
getAttribute
/
setAttribute
也存在许多问题;如果要克隆表单,则
名称
可能会有问题,并且
onX
属性和内联
样式
​它们不会以一种有用的方式工作(最好避免它们)。此外,任何
元素在附加到任何父节点时都将重新执行。@bobince:注释节点的要点非常好。get/setAttribute有时在IE6上可能会出现问题,不过,我没有注意到IE7+在这对特定函数上存在重大问题(尽管还有很多问题要抱怨)。要支持命名空间属性,请使用SetAttributes和GetAttributes,而不是setAttribute和getAttribute。下面是一个例子。这对我来说非常有用,但我遇到了一个问题,元素显示为损坏的图像(在IE9中)。你知道为什么会这样吗?我已经验证了图像URL是有效的,所以这绝对不是问题所在。谢谢如果有人感兴趣,我可能不会在IE工作,这取决于你想做什么。我怀疑原始海报使用的是importNode,因为他/她是从外部文档(例如iframe或window.open)复制的。因此,在IE.HierarchyRequestError上使用jQuery的append()仍然会失败。
$(dom_to_import_into).find('element-to-import-into').append($(dom_to_import).clone());
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;
  }
}