jayhendren
jayhendren

Reputation: 4520

using JQuery to fetch an html document and parse it into a DOM tree

So essentially I'm trying to build my own version of GitHub's tree slider. The relevant Javascript/JQuery code is:

// handles clicking a link to move through the tree
$('#slider a').click(function() {
    history.pushState({ path: this.path }, '', this.href) // change the URL in the browser using HTML5 history module
    $.get(this.href, function(data) {
        $('#slider').slideTo(data) // handle the page transition, preventing full page reloads
    })
    return false
})

// binds hitting the back button in the browser to prevent full page reloads
$(window).bind('popstate', function() {
    $('#slider').slideTo(location.pathname)
}

Ok, hopefully that's understandable. Now here's my interpretation of what's going on here, followed by my problem/issue:

The callback function for the GET request when navigating through the tree is the slideTo method, and an HTML string is passed in as an argument to that function. I'm assuming that slideTo is a function defined elsewhere in the script or in a custom library, as I can't find it in the JQuery documentation. So, for my purposes, I'm trying to build my own version of this function. But the argument passed into this function, "data", is just the string of HTML returned from the GET request. However, this isn't just a snippet of HTML that I can append to a div in the document, because if I perform the same GET request (e.g. by typing the url into a web browser) I would expect to see a whole webpage and not just a piece of one.

So, within this callback function that I am defining, I would need to parse the "data" argument into a DOM so that I can extract the relevant nodes and then perform the animated transition. However, this doesn't make sense to me. It generally seems like a Bad Idea. It doesn't make sense that the client would have to parse a whole string of HTML just to access part of the DOM. GitHub claims this method is faster than a full page reload. But if my interpretation is correct, the client still has to parse a full string of HTML whether navigating through the tree by clicking (and running the callback function) or by doing full page loads such as by typing the new URL in the browser. So I'm stuck with either parsing the returned HTML string into a DOM, or ideally only fetching part of an HTML document.

Is there a way to simply load the fetched document into a Javascript or JQuery DOM object so I can easily manipulate it? or even better, is there a way to fetch only an element with an arbitrary id without doing some crazy server-side stuff (which I already tried but ended up being too spaghetti code and difficult to maintain)?

I've also already tried simply parsing the data argument into a JQuery object, but that involved a roundabout solution that only seems to work half the time, using javascript methods to strip the HTML of unwanted things, like doctype declarations and head tags:

var d = document.createElement('html');
d.innerHTML = data;
body = div.getElementsByTagName("body")[0].innerHTML;

var newDOM = $(body);
// finally I have a JQuery DOM context that I can use,
// but for some reason it doesn't always seem to work quite right

How would you approach this problem? When I write this code myself and try to make it work on my own, I feel like no matter what I do, I'm doing something horribly inefficient and hacky.

Is there a way to easily return a JQuery DOM object with a GET request? or better, just return part of a document fetched with a GET request?

Upvotes: 1

Views: 2302

Answers (2)

albertoblaz
albertoblaz

Reputation: 590

Imagine you want to parse a <p> tag in your normal HTML web page. You probably would use something like:

var p = $('<p>');

Right? So you have to use the same approach to parse an entire HTML document and then, navigate through the DOM tree to get the specific elements you want. Therefore, you just need to say:

$.get(this.href, function(data) {
    var html = $(data);

    // (...) Navigating through the DOM tree

    $('#slider').slideTo( HTMLportion );
});

Notice that it also works for XML documents, so if you need to download via AJAX a XML document from the server, parse the inner information and display it on the client-side, the method is exactly the same, ok?

I hope it helps you :)

P.S: Don't ever forget to put semicolons at the end of each JavaScript sentence. Probably, if you don't put them, the engine would work but it is better to be safe and write them always!

Upvotes: 1

Evan Davis
Evan Davis

Reputation: 36592

Just wrap it; jQuery will parse it.

$(data) // in your callback

Upvotes: 2

Related Questions