2009-11-28 77 views
5

我一直在寻找角落找寻的网页,我相当肯定我已经知道答案(“无”),但我想检查:对DOM importNode IE支持

是否支持IE importNode ()呢?有没有比步行DOM和创建节点更好的选择? (我见过the clasic article by Anthony Holdener,但它现在已经超过一年了,我希望无论IE有进化还是有人有另一个工作周期)

谢谢。

+0

这里有一个[关联一个实现的问题(http://stackoverflow.com/a/6075604/405017)。 – Phrogz 2012-03-26 11:38:04

回答

4

我没有听说过这种情况已经改变着呢,在recent post由John Resig的,他说:

Internet Explorer不支持importNode或adoptNode

也看到这方面的一个List Apart文章cross-browser importnode(),因为它包含了针对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; 
} 
+1

这是一个很好的通用方法,但是您会希望'document.createComment'响应'COMMENT_NODE';把它变成一个文本节点可能不是一个好主意。不幸的是,在IE的HTML元素中使用'getAttribute' /'setAttribute'还有很多问题。如果你在克隆表单,'name'可能是一个问题,'onX'属性和内联'样式不会以有用的方式工作(最好避免它们)。当附加到任何父节点时,任何'

-1

对于一个轻量级的解决方案(只要你不介意增加的依赖),你总是可以使用jQuery:

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

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

+0

不错的提示!谢谢 – 2011-03-28 18:39:00

+0

可能无法在IE中运行。取决于你想要做什么。我怀疑原始海报正在使用importNode,因为他/她正在从外部文档(例如iframe或window.open)进行复制。因此,使用jQuery的append()在IE上仍然会失败。 HierarchyRequestError。 – joedotnot 2016-12-12 07:47:05

5

Internet Explorer 9 DOM API中有一个函数document.importNode()。不过,IE9抛出的时候,它被称为

SCRIPT16386一个脚本错误:不支持此接口

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

建议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; 
    } 
} 
+0

这对我很好,但我遇到了一个问题,其中元素显示为破损的图像(在IE9中)。任何想法为什么会发生?我已验证图片网址是有效的,所以这绝对不是问题。谢谢! – lakenen 2013-01-29 21:21:48

+0

如果有人有兴趣,我[解决了问题](http://stackoverflow.com/questions/14593520/ie9-importing-inline-svg-image-elements-broken)。 – lakenen 2013-01-29 23:07:00