I've been searching for a while now, but I can't figure out how to load an entire page via AJAX and still execute all javascript and css.
Mostly I just end up with the plain text without any CSS.
Is there a way to do this? I tried jQuery.get, jQuery.load and jQuery.ajax, but none really work like that.
I have a different solution. You may try it with an iframe. Use jQuery to append an iframe script including all relevant codes into some part of your page (like some div). This may do it for you including CSS, like;
$('<iframe src="your_page.html"/>').appendTo('#your_div');
Or you may try something like;
$('<iframe src="your_page.html"/>').load(function(){
alert('the iframe is done loading');
}).appendTo('#your_div');
I have solved similar problem as following.
Download the webpage over ajax
Iterate it over and find any <script> and </script> tags
Get content from within these tags as text
Create new <script> element and insert there the code
Append the tag to your webpage
Another thing is you will need to somehow call the script..
I have done it this way:
I set standardized function names like initAddedScript callback which I am calling after appending the script to the page. Same as I have deinitScript called when I do not need the code (and its variables,..) anymore.
I must say this is awful solution, which likely means you have bad application architecture so as I have had:)
With css is it the same, but you do not need any handlers. Just append the style tag to your documents head.
If the page you load doesn't have any style data, then the external stylesheets must have relative paths that are not correct relative to the invoking document. Remember, this isn't an iFrame - you aren't framing an external document in your document, you're combining one document into another.
Another problem is that loading your complete page will also load the doctype, html, head, and body tags - which modern browsers will cope with most of the time, but the results are undefined because it's not valid HTML to jam one document into another wholesale. And this brings me to the third reason why it won't work: CSS links outside of the head section aren't valid, and the misplaced head section caused by your haphazard document-in-document collage.
What I'd do for compliance (and correct rendering) is this, which would be implemented in the Success callback:
Copy all link elements to a new jQuery element.
Copy the contents of all script in the head section
Copy the .html() contents from the loaded document's body tag
Append the link elements (copied out in step 1) to your host document's head
Create a new script tag with your copied script contents and stick it in the head too
Done!
Complicated? Kind of, I guess, but if you really want to load an entire page using AJAX it's your only option. It's also going to cause problems with the page's JavaScript no matter what you do, particularly code that's supposed to run during the initial load. There's nothing you can do about this. If it's a problem, you need to either rewrite the source page to be more load-friendly or you could figure out how to make an iFrame suit your needs.
It's also worth considering whether it'd work to just load your external CSS in the host document in the first place.
I suppose you are looking for something like this:
your page div --> load --> www.some-site.com
After a quik search the closest solution seems to be the one by "And": Load website into DIV
You have to run a web server and create a proxy.php page with this content:
Then your JQuery load() function should be like this:
$("#your_div_id").load("proxy.php?url=http://some-site.com");
NB. I have tested this solution and it should not load all the CSS from the target page, probably you'll have to recreate them. For example the image files stored on the remote server will not loaded, I suppose due to authentication policy.
You will be also able to view only the target page without the possibility to browse the target site.
Anyway I hope this could be a step forward to your solution.
Get your entire webpage as text using ajax
document.open();
document.write(this.responseText);
document.close();
OR
document.documentElement.outerHTML = this.responseText;
But you need to change the path of css and js pages in original webpage if the resulting webpage is in another directory.
Related
I am building a Wordpress plugin to display a list of jobs to a user pulled from a recruiting platform API. On click of a job, a cURL request is sent to the API that pulls the job details as a full HTML page (the online job advertisement). I have everything working fine in terms of pulling the HTML, but I cannot figure out how to display it to the user.
How can I either:
Open a new tab to display the HTML pulled from the AJAX request
or
Open the full HTML within a div on the same page (i.e. a modal)
I would prefer to open the HTML in a new page, but don't know how to use jQuery to do this... Opening within the page in a modal is also fine, but as far as I understand iFrames (which I would rather not use anyway), you have to pass a url (and I simply have the full markup). Is there a way to display this within a page, perhaps using canvas? It carries its own links to CSS and Javascript that need to apply only within that sub-page.
EDIT:
As a clarification, I know that I can simply place the HTML within the page. My issue is that it is a full page. This means it has a <head> <body>, and its own CSS links. Just putting it in the page messes with the rest of the CSS and produces invalid HTML.
This is what I already have:
$.post(ajaxurl, data, function(response) {
$('.sg-jobad-full').html(response);
});
It places the response within the page perfectly well... but it messes up the page by introducing a <body> within a <body> and competing CSS.
If you put the response in a <div>, it will mess the markup because css/js/meta definitions may not be put into the <body>.
If there is a way to retrieve the data without the markup already beeing in, you could parse the data and let it print via a javascript, which is the method I'd prefere.
According to your comment, you should really go with iframes, all other methods will alter your markup to have <html> tags inside <html>, which is very bad practice.
Iframes can be styled just like a <div> element, and it is realy not dirty to use iframes for the purpose you mentioned (it does not load from a foreign host, it is not hidden, it does not track).
<iframe class="job-offers-plugin" src=".../wp-content/plugins/yourplugin/getJobs.php">
</iframe>
Put some style into it like width;height;padding;margin;overflow; place it where you like..
This helps you with the databse:
Using WPDB in standalone script?
Add permalinks to your plugin script:
http://teachingyou.net/wordpress/wordpress-how-to-create-custom-permalinks-to-use-in-your-plugins-the-easy-way/
If you get the full HTML in an jQuery.ajax(...) call, you can always just show it in a certain div on your page.
$.ajax({
success: function (resp){
// resp should be your html code
$("#div").html(resp);
}
});
You can use the $(selector).html(htmlCode) everywhere you want. You can insert it into modals, divs, new pages...
If you have to inject a whole HTML page you can:
strip the tags you don't need
or
use an iframe and write the content to that iframe: How to set HTML content into an iframe
iframes aren't my favourite thing... but it's a possibility
I am looking for a way to modify some text inside the HTML before it is being parsed by the browser.
More precisely, I would like to remove some tags from the HTML so the image resources would not be fetched by the browser, only when I am ready I could insert these tag back to have them loaded.
Is it possible to do that via some JS/Jquery or CSS, if so, how?
the motivation here is to be able to block the loading of some resources on a page and have them loaded only when needed according to some logic. this needs to be done by some kind of scripting added to the page
Because you're doing this in JavaScript the HTML is already being processed when it comes to launch your <script> tags.
You could move your <script> tags into the <head> from the <body>, or move it to the very beginning of the body. However the problem here is that you'll have to wait for your elements to actually be created in the DOM before you can work with them.
You could use something like setTimeout() or similar and continually look for them until you find them, but there's still going to be a slight delay between them being created and your script finding them, at which point they might already start to load.
The only surefire way is to process the markup server side long before it gets to the browser.
My answer here possibly could be of use, if you can place noscript tags in key places in your markup prior to parsing/evaluation:
Client-Side Dynamic Removal of <script> Tags in <head>
This method—for javascript-enabled agents—would delay the rendering of the entire page however, or at least the regions that you needed to affect.
basic generalised theory
Wrapper your body or specific region with a noscript tag identified with either a class or id. Place some javascript to execute directly after the close noscript that grabs the tag and reads the html contents as a string. At this point you could modify the html string however you like and then re-inject it back into the DOM replacing the noscript tag.
more specific implementation
If you know before-hand which resources you need to postpone—say all your images—you could wrap each image in-question with a noscript tag. Then trigger off some JavaScript that grabs all noscripts and rewrites the contained image html to use a placeholder or lower quality version of the image. At the same time you could set up event listeners or timeouts that inject the actual images when the time is right.
The Lazy Load Plugin for jQuery is maybe what you are looking for. It delays loading of images in long web pages.
You can use any jQuery event such as click or mouseover. You can also use your own custom events such as foobar. Default is to wait until user scrolls down and image appears on the window.
Beside all the It is also possible to delay loading of images. Following code waits for page to finish loading (not only HTML but also any visible images). Five seconds after page is finished images are loaded automatically.
$(function() {
$("img:below-the-fold").lazyload({
event : "sporty"
});
});
$(window).bind("load", function() {
var timeout = setTimeout(function() {
$("img.lazy").trigger("sporty");
}, 5000);
});
Check the delayed loading demo.
I know that jQuery automatically parses script elements and append them to the head, however I dont have much of a choice. I need to insert an html string exactly into a specified div. so for example <script src='http://.....'></script> into <div id="lb"></div>.
The problem is that the scripts get loaded from a server which I have no control over and is using a document.write() script. So if that gets appended to the header, there will be severe issues. How can I do this with or without jQuery?
Ok. So to rephrase your question:
You want to insert some < script > tags in your page. These tags load javascript files that have document.write() in them.
Now you want the document.write() to happen in some divs, and not in the header.
I think you would then need to render those script tags directly in the source of your page from the very start. Felix noted correctly that when you load thse script tags later, the whole page will be replaced by what is outputted by the document.write() function.
Thus, javascript or JQuery cannot load these script tags. You should render them serverside in the initial version of your page..!
If you don't want your script to alter the content of you page you could insert it in an iframe instead of a div ? document should refer to the iframe then. I don't exactly get what you want though.
Document.write() will put the script at the end of the document (afaik). Then, you would need to look-up these script-tags and put them into the proper DIVs (with a $(elm).append(scriptObj)).
But I might not understand what your problem is...
So I'm working on making a dynamic drop down select form and I need for each menu to propagate possible choices from a prebuilt chunk of html (located at, say, http://example.com/menu/choices) is there an easy way to use javascript to fetch the html of a remote page and then plug that in to the page? I know I can use .write() to insert the code, I just don't know how to fetch it.
Thanks!
Actually, you can't use write to insert the code, not once the initial page rendering is complete.
Loading Code
My first read of your question was that you wanted to load code — e.g., JavaScript. Here's how you do that, but see below.
The easiest way to do this is if your code exists at its source location in a JavaScript file all ready for inclusion in a file in the normal way. In that case, all you need to do is create a script element and add it to the document:
var script = document.createElement('script');
script.type = "text/javascript";
script.src = /* ... the URL of the code ... */;
document.body.appendChild(script);
document.body.removeChild(script);
Note that last line, removing the script node immediately after inserting it in the document. Inserting the node is all you need to do, that immediately triggers the process by which the JavaScript file is fetched and interpreted. You can remove the script element immediately (or not, it's up to you).
In the above, I've added the element to document.body because it's convenient and it doesn't matter where you add it. However, most scripts you see doing this will usually add it to the head instead. That's fine too. More in this article, although it's focussed on the Prototype library.
Speaking of libraries, all of the above notwithstanding, if you use a JavaScript library like jQuery, Closure, Prototype, YUI, or any of several others, it will probably make this (even) easier for you.
Update: Did you add the jQuery tag later? I didn't see it originally. With jQuery, if you're loading the script from the same origin as the document, you can use the getScript function:
jQuery.getScript('ajax/test.js');
// Or $.getScript('ajax/test.js');
However, getScript is not the same as the technique above. getScript will be hampered by the Same Origin Policy, whereas adding a script tag is not.
Loading Markup
If you want to load HTML markup and apply it to part of a page, that's easily done with jQuery.load:
$('#someid').load("yoururl.here");
That will replace the contents of the element with the id "someid" with the HTML returned from the given URL. Here's a live example that loads options into a select and another that loads text (a paragraph) into a div. This is easier with a library (like jQuery) because there are some issues around certain elements that libraries usually handle for you.
The thing you want is called AJAX (Asynchronous JavaScript and XML). If you're using jQuery:
$('#my-select-thingy').load('select-options.cgi');
or whatever flavour of server-side you prefer. You should have something like this in HTML:
<div id="my-select-thingy">
<!-- select will go here -->
</div>
and the url above should return something like this:
<select>
<option>Foo</option>
<option>Bar</option>
</select>
You're way better of using jQuery for that. Just look into the Ajax methods and you'll get the hang of it. http://api.jquery.com/category/ajax/
Suppose you have the following HTML markup
<div id="fakeDiv"></div>
you can execute an ajax request like this
$.ajax({
type: "get",
dataType: "html",
url: "http://example.com/menu/choices",
data: {},
success: function(response) {
$("#fakeDiv").html('').html(response);
},
});
to inject the html code returned by your url inside the DIV element.
This is jQuery code. Hope it helps!
Javascript usually can't access other websites for security reasons. If we could load content from wherever we wanted with a script we'd see some pretty rampant chaos. A simple solution is an iframe with the other document or just a section of it.
Does the website have anyway for you to access that info? If you can find an interface you can just get the info and stick in in the document. Otherwise you'd have to do some scraping.
Appending a script element using jquery rather than putting it in the html by hand seems to lead to very different results. For instance
snaphtml = '<script src="http:\/\/seadragon.com\/embed\/lxe.js?width=auto&height=400px"><\/script>';
$('#content').append(snaphtml);
destroys the layout of my page, but putting the script element in the page directly works fine.
I have posted a test case online:
Working example with script in html.
Broken example with script appended via jquery.
The second div should not be deleted / invisible once the silverlight object is added.
Ideas?
I would recommend you to use $.getScript method for loading external script files programmatically:
$.getScript('path/to/script.js', function() {
alert('Script loaded.');
});
The script load is made asynchronously, and as you see in the above example, you can specify a callback function that will be executed when your external file has been loaded and is ready to use.
Tristan, you will not be able to include the script you reference dynamically onto the page after it has finished loading. The external script is using document.write which will only work correctly when called before the page has finished loading. This is why your static implementation works fine, and your dynamic one tears the page apart.
You might want to put together a dummy HTML file that just has a basic HTML structure and this script in it already. Then dynamically add an iframe to your page that loads the HTML. There are even more dynamic ways to make it work with an iframe, but that would be the easiest.
Try to use $.getScript:
$.getScript("http://seadragon.com/embed/lxe.js?width=auto&height=400px");
Edit:
The provided script is using document.write, which is likely causing your problems: you cannot add it dynamically at the middle of the page. Try loading SeaDragon as shown here:
http://www.seadragon.com/developer/ajax/getting-started/
try to break script tag like
snaphtml = '</sc'+'ript>'