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