views:

163

answers:

2

The Problem is:

I get the following structure (generated in PHP) sent via JSON as a string.

<article>

<header>  
    <h2><a href="#">url</a></h2>
    <p><time datetime="2009-11-05">05 Nov 2009</time></p>
</header>

<div class="entry"> 
    <p>something</p>
    ... 
</div>

<footer>something</footer>

</article>

I have a list of articles on the site and I need to replace an existing article with the received one. Using jQuery, I would do something like this:

var $victim = $slider.find('article.loading:first'); 
    $fresh = $(basket.shift());

basket.shift() is the received article in the above string form and $victim is the existing one.


Now, normally I would do

$victim.replaceWith($fresh);

It works in good browsers (gecko, webkit) but jQuery has a known bug on using .innerHTML with HTML5 elements, documented here. .replaceWith uses that method internally in the end.


A solution would be to use native Javascript and methods except .innerHTML. Something like this should work:

$victim.parent().get(0).insertBefore($fresh.get(0), $victim.get(0));

And it does, but only in good browsers, again. Something is not ok with the .get(0) approach on the $fresh var.

I've simulated an insertion of a node created locally in the js code and it works in IE:

var dummy = document.createElement('article');
    var dummyChild = document.createElement('header');
        txt = document.createTextNode("crap");
        dummyChild.appendChild(txt);
dummy.appendChild(dummyChild);

$victim.parent().get(0).insertBefore(dummy, $victim.get(0));

So, is there any other way of transforming the string into a DOM subtree? Or any other way to get by the replaceWith problem?

Note: I'm no javascript guru/ninja :)


Ok, after some more reading I think I've found why the .insertBefore doesn't work.

As the jQuery API states (http://api.jquery.com/jQuery/#creating-new-elements), when I pass the <article> as a string, the DOM element is created also via .innerHTML because of its complexity.

Is there a way to force $() in using the native createElement instead? I know it sucks performance-wise, but at least it will get IE working.

A: 

IE causes errors when working with HTML5 elements so try to donwload the script from this page and include it before any other in the head of the document: http://html5doctor.com/how-to-get-html5-working-in-ie-and-firefox-2/

This should prevent errors caused by HTML5 elements in IE

mck89
THe html5 shiv doesn't cover this. It just creates elements in order to enable styling. I use it by the way.
GreenDude
+1  A: 

You error might actually be occurring earlier than you think. When you wrap the basket.shift() in $() it is actually being added to a hidden div at that point. Have you tried this:

var $victim = $slider.find('article.loading:first'); 
    fresh = basket.shift();

$victim.replaceWith(fresh);
Doug Neiner
Yes, the error occurs at the `$()` function call like I said in the last edit :) Same thing happens if I give a string to `replaceWith`, it will first process the string and then replace.
GreenDude