Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get contents of <body> </body> within a string

Tags:

html

jquery

ajax

I want to do the following.

$("a").click(function (event) {

    event.preventDefault();

    $.get($(this).attr("href"), function(data) {

        $("html").html(data);

    });

});

I want the behavior of all hyperlinks to make a ajax calls and retrieve the html.

Unfortunately you cannot simply replace the current html with the html you receive in the ajax response.

How can grab only what is within the <body> </body> tags of the ajax response so that i can replace only the contents of the body in the existing html.

Edit: the <body> opening tag will not always be just <body> it may sometimes have a class e.g.

<body class="class1 class2">

like image 955
aprea Avatar asked Jun 01 '11 02:06

aprea


People also ask

Can you have a body inside a body HTML?

"body inside body" most likely isn't "well-formed", but it is OK to ignore that, because browsers (having to be backwards compatible) are very very robust when it comes to non-"well-formed"ness.

How do I separate a body in HTML?

To create sections inside your body, you can use <div> tags instead (or other new html5 tags like <nav> , <article> , etc.).

What does body mean in Javascript?

The document. body in javascript is a direct reference to the DOM element representing the <body> portion of the page. The $() part depends on how it is used. $ could be a variable name, and () after a variable or property name attempts to call a function stored in that variable or property.


2 Answers

If I understand you correctly, grab the content between the body tags with a regex.

$.get($(this).attr("href"), function(data) {
    var body=data.replace(/^.*?<body>(.*?)<\/body>.*?$/s,"$1");
    $("body").html(body);

});

EDIT

Based on your comments below, here's an update to match any body tag, irrespective of its attributes:

$.get($(this).attr("href"), function(data) {
    var body=data.replace(/^.*?<body[^>]*>(.*?)<\/body>.*?$/i,"$1");
    $("body").html(body);

});

The regex is:

^               match starting at beginning of string

.*?             ignore zero or more characters (non-greedy)

<body[^>]*>     match literal '<body' 
                    followed by zero or more chars other than '>'
                    followed by literal '>'

(               start capture

  .*?           zero or more characters (non-greedy)

)               end capture

<\/body>        match literal '</body>'

.*?             ignore zero or more characters (non-greedy)

$               to end of string

Add the 'i' switch to match upper and lowercase.

And please ignore my comment regarding the 's' switch, in JavaScript all RegExp are already single-line by default, to match a multiline pattern, you add 'm'. (Damn you Perl, interfering with me when I'm writing about JavaScript! :-)

like image 59
Rob Raisch Avatar answered Sep 20 '22 18:09

Rob Raisch


I didn't want to mess with regular expressions. Instead, I created a hidden <iframe>, loaded the contents in it, and extracted the <body> from the page in the <iframe> in the page's onload().

I needed to be careful with Same-origin policy for the the iframe (this article showed the way):

var iframe = document.createElement('iframe');
iframe.style.display = "none";
jQuery('body').append(iframe);
iframe.contentWindow.contents = data;
iframe.onload = function () {
    var bodyHTML = jQuery(iframe).contents()
                        .find('body').html();
    // Use the bodyHTML as you see fit
    jQuery('#error').html(bodyHTML);
}
iframe.src = 'javascript:window["contents"]';

Just remove the <iframe> when you're done...

like image 32
Peter V. Mørch Avatar answered Sep 22 '22 18:09

Peter V. Mørch