JavaScript: Замена для XMLSerializer.serializeToString()?
Я занимаюсь разработкой веб-сайта с использованием инфраструктуры Seam и библиотеки RichFaces AJAX (на самом деле это не так важно для решения проблемы - только некоторый фон).
Я, похоже, обнаружил ошибку в RichFaces, которая в некоторых случаях приведет к сбою обновления на основе AJAX в IE8 (см. здесь для получения дополнительной информации: http://community.jboss.org/message/585737).
Ниже приведен код, в котором происходит исключение:
var anchor = oldnode.parentNode;
if(!window.opera
&& !A4J.AJAX.isWebkitBreakingAmps()
&& oldnode.outerHTML
&& !oldnode.tagName.match( /(tbody|thead|tfoot|tr|th|td)/i ) ) {
LOG.debug("Replace content of node by outerHTML()");
if (!Sarissa._SARISSA_IS_IE || oldnode.tagName.toLowerCase()!="table") {
try {
oldnode.innerHTML = "";
} catch(e){
LOG.error("Error to clear node content by innerHTML "+e.message);
Sarissa.clearChildNodes(oldnode);
}
}
oldnode.outerHTML = new XMLSerializer().serializeToString(newnode);
}
Последняя строка (одна с XMLSerializer) - это то место, где исключение происходит в IE. Мне было интересно, знает ли кто-нибудь о методе замещения/библиотеке/etc, который я мог бы использовать там (только для IE в порядке). Спасибо.
EDIT: после некоторых дальнейших исследований кажется, что исключение не вызвано тем, что XMLSerializer не определяется, скорее это происходит, когда я пытаюсь назначить вывод XMLSerializer свойству outerHTML для старого.
Это странно, потому что он работает чаще всего, но не работает только в нескольких сценариях (этот фрагмент структуры кажется довольно важным).
Может ли кто-нибудь подумать о какой-либо причине, когда вывод XMLSerializer (который, из того, что показывает отладчик, выглядит вполне допустимым HTML), не привязан к свойству outerHTML элемента?
Самое странное, если я должен клонировать элемент (используя cloneNode(true)
), а затем установить outerHTML, он работает.
Ответы
Ответ 1
С тех пор я обнаружил причину (совсем недавно). Оказывается, IE полу-проверяет (он будет игнорировать некоторые ошибки, но игнорировать другие) вставил HTML. Это бросало какую-то "неизвестную ошибку" или что-то подобное, что было совершенно бесполезно, поскольку оно не давало никаких указаний относительно того, что пошло не так - просто что-то пошло не так.
В моем случае это произошло потому, что < li/ > был вставлен с родителем. Если у вас похожие проблемы, вы можете убедиться, что не пытаетесь быть слишком умными с вашим HTML.
Ответ 2
В IE вы можете просто использовать свойство xml
для XML node, если newnode
действительно является XML node, а не HTML node:
function serializeXmlNode(xmlNode) {
if (typeof window.XMLSerializer != "undefined") {
return (new window.XMLSerializer()).serializeToString(xmlNode);
} else if (typeof xmlNode.xml != "undefined") {
return xmlNode.xml;
}
return "";
}
oldnode.outerHTML = serializeXmlNode(newnode);
Обновить следующее обновление вопроса
Я бы не использовал outerHTML
для замены элемента. Он не поддерживается повсеместно. Вместо этого вы можете использовать сочетание innerHTML
и стандартных методов DOM следующим образом:
var tempEl = document.createElement("div");
tempEl.innerHTML = serializeXmlNode(newnode);
oldnode.parentNode.replaceChild(oldnode, tempEl.firstChild);
Ответ 3
Ответ на вопрос о грани (в основном, я могу найти его позже):
Отправка HTML-документа в виде строки в api для создания PDF файлов.
Для тех, кому необходимо преобразовать document.body в String, и они отправляют его через POST в службу для преобразования документа в PDF файл. IE8 не поддерживает XMLSerializer
. При этом вы можете использовать: $(document.body).html();
для IE8.
/**
* Decides the method by which to turn the document.body into a string that we can post to the PDF Api.
* Most browsers support XMLSerializer, for others (ie8) use jquery html method to generate a string.
* @param xmldom - document.body
* @return - string representation of the document body
*/
function serializeXml(xmldom){
if (typeof XMLSerializer != "undefined"){
return (new XMLSerializer()).serializeToString(xmldom);
} else {
return $(xmldom).html();
}
}
Назовите его: var dom = serializeXml(document.body);
Ответ 4
Предлагаемое решение для меня не работает. Вот мое решение этой проблемы.
Я заменил строку:
oldnode.outerHTML = new XMLSerializer().serializeToString(newnode);
:
if(navigator.appName.indexOf('Internet Explorer')>0){
oldnode.outerHTML = newnode.xml
}else{
oldnode.outerHTML = new XMLSerializer().serializeToString(newnode);
}