IE поддерживает DOM importNode
Я искал в Интернете, и я вполне уверен, что я уже знаю ответ ("нет"), но я хотел бы проверить:
IE поддерживает importNode() еще? Есть ли лучшая альтернатива, чем ходить по DOM и создавать узлы? (Я видел классическую статью Энтони Холденера, но ей уже больше года, и я надеюсь, что либо IE эволюционировал, либо у кого-то есть другой обходной путь)
Благодарю.
3 ответа
Я не слышал, чтобы это изменилось, и в недавнем сообщении Джона Резига он заявляет:
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;
}
В API DOM Internet Explorer 9 есть функция 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 является нулевым.
Есть обходной путь, который работает для меня:
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;
}
}
Для более легкого решения (если вы не возражаете против добавления зависимости) вы всегда можете использовать jQuery:
$(dom_to_import_into).find('element-to-import-into').append($(dom_to_import).clone());
Это добавит dom_to_import
в конце 'element-to-import-into'
,