Get the contents of <body> </body> inside a string
I want to do the following.
$("a").click(function (event) { event.preventDefault(); $.get($(this).attr("href"), function(data) { $("html").html(data); }); }); I want all hyperlinks to make ajax calls and retrieve html.
Unfortunately, you cannot just replace the current html with the html that you get in the ajax response.
How can I capture only those that are in the <body> </body> tags of the ajax response so that I can only replace the contents of the body in the existing html.
Edit: the opening <body> tag will not always be just <body> , it can sometimes have a class, for example.
<body class="class1 class2">
If I understand you correctly, grab the content between body tags using a regular expression.
$.get($(this).attr("href"), function(data) { var body=data.replace(/^.*?<body>(.*?)<\/body>.*?$/s,"$1"); $("body").html(body); }); EDIT
As per your comments below, here is an update to match any body tag, regardless of its attributes:
$.get($(this).attr("href"), function(data) { var body=data.replace(/^.*?<body[^>]*>(.*?)<\/body>.*?$/i,"$1"); $("body").html(body); }); Regular expression:
^ 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 uppercase and lowercase.
And please ignore my comment regarding the 's' switch, in JavaScript all RegExp are single-line by default, to match a multi-line pattern, you add 'm'. (Damn you Perl, bothering me when I write about JavaScript! :-)
I did not want to bother with regular expressions. Instead, I created a hidden <iframe> , loaded the contents into it, and extracted <body> from the page in the <iframe> on the onload() page.
I need to be careful with a policy of the same origin for 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 ...
Be sure to bind the events to the document, filtered by class ( $(document).on('click', '.my-class-name', doThings); ). If you replace the html of the body, any event bindings made directly ( $('.my-class-name').on('click', doThings); ) will be destroyed when the DOM is redrawn using the new html, Rebooting will work, but it will also leave a bunch of pointers from old events and nodes that the garbage collector will have to clear - in other words, it can make the page heavier and heavier the longer it takes to open.
I have not tested this on multiple platforms, use with caution.
// create a new html document function createDocument(html) { var doc = document.implementation.createHTMLDocument('') doc.documentElement.innerHTML = html return doc; } $("a").click(function (event) { event.preventDefault(); $.get($(this).attr("href"), function(data) { $("body").html($(createDocument(data)).find('body').html); }); });