Kevin Wilson
Kevin Wilson

Reputation: 8053

How do I parse specific parts of a page using JQuery's AJAX method?

I'm trying to work out how to parse specific parts of a page using JQuery's AJAX method. What I'd like to do is something like this:

$.ajax({
    url: "page-to-load.htm",
    dataType: "html",
    success: function (response) {
            var html= $(response);
            var content = html.find("#main");
            var title = html.find("title");
            var nav = html.find("ul.nav");
    }
});

I know that I can load specific page parts using [container].load() but this will (as far as I understand it) create a request for each page part I want to load.

In my sample code, the html object seems to be an array of HTML elements but each of the objects returned by find() are null. The elements searched for do exist in the target page.

Am I missing something obvious or is this just not something that JQuery can handle?

Upvotes: 8

Views: 2851

Answers (5)

Brandon Joyce
Brandon Joyce

Reputation: 3110

This works. Use .load with the special url syntax to get the part of the page you want into a temporary div. Use the inner html from that for whatever you want.

$(function(){      
  var tempDiv = $("<div />");
  tempDiv.load('index.html #target-element', function(){    
    alert(tempDiv.html());
  });
});

Here is an example without the url syntax so you can work with the entire page. You can pull the title out like you are trying to do in your question...

$(function(){
  var tempDiv = $("<div />");
  tempDiv.load("page-to-load.htm", function() {
        var content = tempDiv.find("#main");
        var title = tempDiv.find("title");
        var nav = tempDiv.find("ul.nav");
  });
});

Upvotes: 2

Eivind
Eivind

Reputation: 841

You could do a split, and then some string replaces before you add it to a jquery object.

$.ajax({
url: "file.html",
dataType: "html",
success: function (response) {            
    var resp = response.split('<body>');
    resp = resp[1].split('</body>');
    resp = resp[0].toString();
    var html = $('<div>'+resp+'</div>');
    var div = html.find('div');
    var ul = html.find('ul');
    var foot = html.find('footer');
    console.log(resp, html, div, ul, foot);
    ul.appendTo('body');
 }});

Works with given HTML:

<!DOCTYPE html>
 <html>
<head>
    <title></title>
</head>
<body>
<div>Something that we're gonna get</div>
<ul>

  <li>List item</li>
</ul>
<footer>Good foot</footer>
</body>
</html>

Upvotes: 0

Jon
Jon

Reputation: 437854

I certainly would not call it impossible.

The very first solution that comes to mind is to do something like this:

1) Insert HTML comments in your output just after opening and just before closing the <body> tag. These comments should contain a unique string so that you can search for it; a guid generated for this purpose would be a good choice. For example:

<!DOCTYPE
blah blah
...
<body>
<!-- BODY: 3F2504E0-4F89-11D3-9A0C-0305E82C3301 -->
...
<!-- BODY: 3F2504E0-4F89-11D3-9A0C-0305E82C3301 -->
</body>

2) After receiving the response, search it for the two instances of <!-- BODY: 3F2504E0-4F89-11D3-9A0C-0305E82C3301 -->. Trim the string so that everything before the first and after the second instance is deleted.

3) You now have a string that contains only elements legal inside a <div>.

The drawback to this method is that you lose access to elements outside <body>, for example <title> (since you mention it). You will have to find another way of passing this information; there are really too many ways to go about this, so pick your poison.

Update (notes):

  • This solution requires that you can modify the HTML produced by page-to-load.html (in other words, it has to be code you own). If this is not the case, then a possibility would be to search for <body> and </body> yourself, but that would start being bug-prone (parsing HTML with regular expressions).
  • Obviously, the unique string (e.g. guid above) will be chosen once and used forever without modification. The whole point is that you need to know what to search for.

Upvotes: 0

jwheron
jwheron

Reputation: 2572

In addition to what you said, the comments on the .find() documentation indicate that you can only perform this action if the HTML is a part of the DOM on your current page. This suggests to me that if you stick all this data into a hidden div and then try to call find, you'll get the results you want.

Upvotes: 0

Kevin Wilson
Kevin Wilson

Reputation: 8053

Actually, found a problem within the answer to another question on here: Why does this jQuery fail to load/parse my HTML string?

From the documentation:

The HTML string cannot contain elements that are invalid within a div, such as html, head, body, or title elements.

If you are fetching a complete HTML document, then you will have lots of elements that may not appear in a div.

answered Sep 18 '09 at 11:53 David Dorward

Looks like it may be impossible then. Dang.

Upvotes: 0

Related Questions