Lazy Web Call for Comments
August, 18th 2010I’ve been working through a particularly tricky jQuery issue this morning and have hit the proverbial brick wall. So, lazy web, I submit to you my question:
Is it possible to return an XHTML snippet through jQuery’s
$.ajaxmethod and have it treated as a DOM node, instead of an array?
What’s happening is the following: I run a fairly standard AJAX command and ask for the data to be returned to me. I’m going to then take that data, insert it into the DOM and animate its opacity into view. Unfortunately, sometimes the data that’s passed back to me (don’t ask…) has HTML comments in it and extraneous script tags. Inserting the extraneous data into the DOM works fine, but animating a comment or script tag seems to throw jQuery for a loop.
In code that would look something like this:
$.ajax({type:'GET', url:p.src, dataType:'html', success:function(data) {
$data = $(data);
$somenode.after($data.css('opacity', 0));
$data.animate({opacity:1}, 'slow', function() {
...
});
});
That accepts each of the following snippets:
<div class="insertme">...</div>
and:
<!-- start insertme -->
<div class="insertme">...</div>
<script type="text/javascript">...</script>
<!-- end insertme -->
The first snippet works fine, the second, not so much. So, the easy fix, in my mind, was to only insert the relevant, .insertme, node, meaning:
$data = $('.insertme', $(data))
That doesn’t work, because the returned data isn’t a DOM node, but an array of elements, so I can’t query against it. I presume I’m getting an array because there’s no html or body tags to tell jQuery this is a DOM tree.
So, seeing as I don’t have access to change the returned data, I’m wondering if there is any way to easily search the returned data and animate only the .insertme node? Currently I’m looping through the array and checking each element, but that seems clunky and gross.
I’ll let you know if I find anything in the meantime, but until then I’m hoping someone out there has run across a similar issue.



Comments
Hey, Mark—have you tried using
.load()?Posted at 05:27 AM on August 18, 2010
Ethan, I love
.loadbut it won’t work in this instance (read: the way I coded my parent Javascript method) because I have to modify the returned data a bit before it’s inserted. Although, if I were starting over (and maybe I will…) I suppose I could.load()the AJAX-ified element into a hiddendivand do my work there, before animating showing anything… hum… hum… yes, I quite like that a lot.Posted at 05:36 AM on August 18, 2010
Oh, right on. (This is what happens when I respond to blog comments before coffee.)
Anyway, yeah: whenever I need to do some pre-processing, I more or less do what you ju st described. (Well, substitute “append
classname that suppresses display” for “hidden div”, but anyway.) Anyway, would love to see whatever you finally end up on!Posted at 05:49 AM on August 18, 2010
Right on Ethan. Thanks for the comment!
I love your idea because then I’m working in the same DOM
document. Also, I sometimes have to get the.width()of an element before it’s inserted and while most of the time it returns what I’d expect I don’t really know how it’s calculating that without putting it in some sort of document. Yes, the suppressed div (see what I did there ;) seems like a very elegant approach.Posted at 06:39 AM on August 18, 2010
I don’t suppose it’s as simple as wrapping data in “”+data+”” to make it valid xhtml (which has to have a single root element)?
Posted at 12:02 PM on August 18, 2010
Thanks Jason, I tried that (but with a
) and while it was better, it still didn’t let me search by doing something like:
Posted at 04:16 PM on August 18, 2010
I’m a big fan of .load() as well. Not sure how much manipulation you need to do (and therefore how long it would take), but what I have done before is do $(this).hide() in the callback and then do your manipulation and then animate it in. Also with .load() you could just grab the .insertme element (you can load remote document fragments, something that blew my mind when I discovered it).
Posted at 05:07 PM on August 18, 2010
Odd, that works for me. I wonder what the difference is.
ed. Updated code styling.
Posted at 05:45 PM on August 18, 2010
Ah, Jason that would work for a string. However, when I pull it back with
$.ajaxI get:Where each of those strings are DOM nodes…
I don’t know if I’m using
$.ajaxwrong or what, but I’d love it to just pull back a string.Posted at 07:24 AM on August 19, 2010
Try specifying
dataType:‘text’, wrapping the response string in a div, *then* passing it in to the jQuery constructor.Posted at 12:51 PM on August 19, 2010
Jason, that may do it. I never thought of using
text. Hum, I’ll let you know what happens!Posted at 02:34 PM on August 19, 2010
Since there is no common container, you can use
filter()to filter the collection of nodes that data gives you.so..
$(data).filter(’.insertme’).appendTo….also you can always do some $(data).wrap(’
‘).parent().find(‘script’).remove().end().children().appendTo(....
kinda sort of thing.
Posted at 09:15 PM on August 19, 2010
And once again Paul proves why he’s Paul and I’m not.
filteris exactly what I was looking for. Thanks Paul!Posted at 12:54 PM on August 23, 2010
Post a Comment