I run a blog that features lots of videos and other framed content.
a typical blogpost body i pull from my database looks like this:
<p>some text</p>
<iframe src="http://example.com" width="400" height="300"></iframe>
<p>some text</p>
some posts have 2-3 iframes in them - the starting-page usually features 6-7 iframes.
i'd like to speed up the loading-time of my blog - is there a way i can make all iframes on my starting-page load asynchronously?
I'll suggest you to have all your data with you and identify the iframes to load and use setTimeout to load different set of iframes with some time gap.
As someone said in a comment, iframes load asynchronously. Perhaps what you're experiencing is a slow load of the main page while it is also loading the iframes contents. I would suggest using this technique:
<!DOCTYPE html>
<html>
<head>
<title>speedup page with iframes</title>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
some content
<br>
some other content
<br>
<iframe id="data_a"></iframe>
<br>
some wild content appears
<br>
<iframe id="data_b"></iframe>
<br>
some wild content appears
<br>
<iframe id="data_c"></iframe>
<br>
the end
<script>
$(function(){
//the iframes will only load AFTER your
//main page is fully loaded
$("#data_a").attr("src", "http://domain1.com/some/path/news.html");
$("#data_b").attr("src", "http://domain2.com/gallery/pictures.html");
$("#data_c").attr("src", "http://domain3.com/contact/map.html");
});
</script>
</body>
</html>
I hope this helps!
So, i read a lot about this topic in the last few days. Especially this article was helpful, since it discusses the actual problem I was facing: a belated onload() event that fires after all iframes are loaded.
After all, what I came up with are these lines of jQuery-Code that seems to work for me:
var src = new Array();
$(function(){
// onDomReady() store all iframe sources in array
$('iframe').each(function(){
src.push($(this).attr('src'));
$(this).attr('src', '');
});
});
$(window).load(function() {
// onload() restore all iframe sources from the array
var i = 0;
$('iframe').each(function(){
$(this).attr('src', src[i]);
i++;
});
});
So here's the deal: I tried a couple of times with and without this code and measured DomReady and Load events.
The DomReady event fires around the same time (before: 1.58s, after: 1.60s)
The Load event on the other hand fires waaay earlier (before: 8.19s, after: 1.92s)
In a way, this doesn't actually improve loading-speed, of course - anyway, in my opinion. the user experience is improved. Any comments or suggestions?
Related
This may be a bit of an x y problem, so I'll give a small bit of background to start with. I am attempting to make a simple dashboard which loads a number of different sites and which cycles between them. To do this I have set up a simple local server along with a html page which gets populated with the different sites in distict frames and then cycles between them by hiding/showing each one in turn. In simple terms, the page looks like this:
<html>
<head></head>
<body>
<iframe id="frame1" src="www.example1.com"> </iframe>
<iframe id="frame2" src="www.example2.com"> </iframe>
<iframe id="frame3" src="www.example2.com"> </iframe>
</body>
</html>
Now, what I would like to do is be able to force a reload of each frame so that the data is up to date. For most sites I can do this with:
document.getElementById['iframe.src'] = document.getElementById['iframe.src']
However, for sites where content changes aren't reflected in the URL, this won't work and will instead 'refresh' the page back to the home page. What I want to do is esentially submit an F5 sort of refresh direct to the frame or use:
document.getElementById("iframe_id").contentWindow.location.href
or
document.getElementById('YOUR IFRAME').contentDocument.location.reload(true);
But, due to CORS, I can't do this. Considering the sites are external sites that I am viewing and have no control over I'm struggling to come up with a way to get around this issue. Is there something pretty obvious that I am missing?
You're not missing anything, that's how the web works. You have no control over a page from another domain, except if you use postMessage() but thas implies the target page acknowledges your messages and reacts accordingly.
In other terms, you won't achieve this unless you have control over the pages you are embedding.
Rather than try and tell the page in the iframe to reload, which you will be blocked from doing. You could instead update the URL in the iframe tag, by adding some random crap to the end of the URL
So for example news.bbc.co.uk would become news.bbc.co.uk?qaz=1, then change this each time you want it to refresh.
You can achieve something like time by removing iframe element & creating again at same place,
this will seems like same page is being refreshed.
working example : this will refresh the frame every 5 second.
<html>
<head></head>
<body>
<div id="frameContainer1">
<iframe id="frame1" width="500" height="500" src="http://www.example.com"> </iframe>
</div>
<script type="text/javascript">
window.onload = function() {
setInterval(function(){
let elem = document.getElementById('frameContainer1');
var elemFrame = document.getElementById('frame1');
elem.removeChild(elemFrame);
var newFrame = document.createElement('iframe');
newFrame.id = 'frame1';
newFrame.setAttribute('src', 'http://www.example.com');
newFrame.width = 500;
newFrame.height = 500;
elem.appendChild(newFrame);
},5000)
}
</script>
</body>
</html>
After 3 days of research and trial and error, I am not able to get the iframe nor its contents to trigger a resize event so that my resize function is called. If I use ...trigger("resize"); to manually trigger a resize event, my resize function is called and works. The page that is loaded in the iframe is on the same domain (http://localhost:81/curlExample/) as the page containing the iframe. Eventually, the page in the iframe will be a supplied by the php curl method, but I would like to get it working first.
*******Updated********
How do I get the resize event triggered when I resize the browser window which causes the iframe to adjust its size?
Thank you for your help!
Page with the iframe
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
function setResize()
{
window.alert("Hello");
var iframeRef = document.getElementById('displayframe');
$(iframeRef).on("resize", function(){
var xExp = 0;
window.alert("Resize event fired.");
});
}
$('#displayframe').load(function()
{
alert("Hello from iFrame. Load event fired.");
var myStallTime = setTimeout(setResize, 3000);
});
});
</script>
</head>
<body>
<p id="myP">Hello</p>
<iframe id="displayframe" src="http://localhost:81/curlExample/HelloIframe.xhtml" style="height:250px; width:100%;">
<p>Your browser does not support iframes.</p>
</iframe>
</body>
</html>
Page within the iframe (HelloIframe.xhtml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>TODO supply a title</title>
</head>
<body>
<div id="myContent" style="width:100%; height:200px;">
<h1>TODO write content</h1>
<h2>Extremity sweetness difficult behaviour he of</h2>
<p>Agreed joy vanity regret met may ladies oppose who. Mile fail as left as hard eyes. Meet made call in mean four year it to. Prospect so branched wondered sensible of up. For gay consisted resolving pronounce sportsman saw discovery not. Northward or household as conveying we earnestly believing. No in up contrasted discretion inhabiting excellence. Entreaties we collecting unpleasant at everything conviction.</p>
<p>Yet remarkably appearance get him his projection. Diverted endeavor bed peculiar men the not desirous. Acuteness abilities ask can offending furnished fulfilled sex. Warrant fifteen exposed ye at mistake. Blush since so in noisy still built up an again. As young ye hopes no he place means. Partiality diminution gay yet entreaties admiration. In mr it he mention perhaps attempt pointed suppose. Unknown ye chamber of warrant of norland arrived.</p>
</div>
</body>
</html>
The <iframe> element will never trigger a resize event, like an <img> or a <div>. You must get this event from window. As your iframe document comes from the same origin as the parent document, you can access its contentWindow and any other attribue.
So, try this:
var iframeWin = document.getElementById('displayframe').contentWindow;
$(iframeWin).on('resize', function(){ ... });
I did it using only DOM's addEventListener.
var iframeWin = document.getElementById('displayframe').contentWindow;
iframeWin.addEventListener('resize', function(){ ... });
Running the following code, will the browser ever fetch bar.png from the server (whether you see it or not)?
<html>
<body onLoad=myLoadFunc()>
<script>
function myLoadFunc() { document.getElementById("foo").innerHTML = ""; }
</script>
<div id="foo"> <img src="bar.png"/> </div>
</body>
</html>
The intention, by the way, is to show bar.png on browsers that don't run the script.
The answer is wholly adventitious. The browser is certainly allowed to start loading the image before it runs the script -- and I imagine it often will -- but there's nothing like a guarantee either way.
Consider using the <noscript> tag.
When i keep my javascript/jquery external, my code doesn't work. but when i combine them in my html file everything is fine.
any suggestions as to why this is?
here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script type ="text/javascript" src="jquery.js"></script>
<script type ="text/javascript" src="program.js"></script>
</head>
<body>
<div id="clickme">
Click here
</div>
<img id="book" src="book.png" alt="" width="100" height="123" />
<p>First Paragraph</p>
<p>Second Paragraph</p>
<p>Yet one more Paragraph</p>
</body>
</html>
with external javascript
$('#clickme').click(function() {
$('#book').fadeOut('slow', function() {
// Animation complete.
});
});
$("p").click(function () {
$(this).slideUp();
});
VERSUS
<!DOCTYPE html>
<html>
<head>
<script type ="text/javascript" src="jquery.js"></script>
</head>
<body>
<div id="clickme">
Click here
</div>
<img id="book" src="book.png" alt="" width="100" height="123" />
<p>First Paragraph</p>
<p>Second Paragraph</p>
<p>Yet one more Paragraph</p>
<script>
$('#clickme').click(function() {
$('#book').fadeOut('slow', function() {
// Animation complete.
});
});
$("p").click(function () {
$(this).slideUp();
});
</script>
</body>
</html>
I guess you execute the click event before the DOM finishes loading. Wrap your code inside the dom ready event and it should work, Assuming your path to the external javascript file is correct.
$(function(){
$('#clickme').click(function() {
$('#book').fadeOut('slow', function() {
// Animation complete.
});
});
$("p").click(function () {
$(this).slideUp();
});
});
Always use firebug (console) to see what is wrong with the script, if you run into any script errors.
Your javascript is executed before there are elements on the page. You can get around this by using $(document).ready(function(){...}); or moving your external javascript files to the bottom.
Wrap your js code in external file in
$(document).ready(function(){
//your code goes here
});
Right now you are including external js file in header and it is executed. At this point there is no elements so $('#clickme') and $("p") are empty set. In the second example you run this code after rendering html with that elements.
The reason that there is a difference, is that in the external file your code is executing before the browser has fully parsed the DOM so you are attempting to programatically access elements of the page which the browser is not yet aware of. This is exactly what most people have already said, but let me elaborate a bit further...
Whilst a lot of people have mentioned using jQuery's document ready handler, I would like to point out that a workable solution is simply to move your script tags to the bottom of the page.
Not only will this solve your problem in itself, but it will also improve page load times because of how browsers treat scripts. When the browser encounters a script it stops everything else it is doing (known as a "blocking" operation), and parses and executes the script. This causes the page to just appear to stall from a user's perspective, meaning a bad user experience. Thus, because the scripts are parsed and executed only as they are encountered, by moving your scripts to the bottom you allow the browser to fully render the page so that the JavaScript does not block rendering.
Though rather than just moving scripts to the bottom of the page, I'd also follow what the others recommended and wrap the whole code in the document ready handler just to be extra safe that your code will always be executed at the correct time.
Also, in the debate of inline or external, external scripts are generally preferred as they are easier to maintain and the browser can cache them independently of the page (providing the correct HTTP headers are present).
To sum up here's some example code:
<html>
<head></head>
<body>
<!-- all your markup here -->
<!-- script at bottom, markup already rendered by this point -->
<script type="text/javascript" src="jquery.js"></script>
<!-- inline or external, still wrap in document ready handler -->
<!-- though external is better because the browser can cache it independently of the page -->
<script type="text/javascript">
//wrap in document ready to be extra safe
$(function() { /*code here*/ });
</script>
</html>
Before I continue:
I am aware this has been done before.
I searched SO for this before deciding to post this...
Said that, I noticed that in some browsers that have settings to clear cache on every visit to a page, certain parts of my page show with delay. I would like to have a function that will display some animated image until the page is finished loading 100%.
I would like to place it in my header include file once and have it kick in every time a page loads. I think I need it to be implemented in AJAX. I would like this function to be a stand-alone, i.e. not tied to any other functions. Shall I use jQuery? Since jQuery itself requires loading an external file, should I implement it as a simple JS function?
Any feedback would be highly appreciated. Examples would be priceless.
:)
EDIT:
I found a plug-in that does exactly what I need.
With jquery you can do something like this
html
<div id="loader"></div>
$(window).load(function () {
$("#loader").fadeOut();
});
You can incldue a div with a loader (have it fixed, or absolute, whatever you like) and then with $(window).load( callback ); you can detect when the whole page has finished loading so you can hide the loader.
Or with pure JS you can do the same,
window.onload = function() {
document.getElementById('loader').style.display='none';
}
You can use the onLoad attribute for . Do something similar to:
<body onLoad='showLoadingDiv()'>
and make the showLoadingDiv function show a full-page white div with a loading sign.
Another (probably preferred) option is to have a
<div style='background:white; width:100%; height:100%'>LOADING</div>
and hide it as soon as the page completely loads, i.e. under jQuery's $(function() { });
This page includes some AJAX progress images to use.
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js"></script>
<script type="text/javascript">
//window.onload will wait for images
window.onload = function() {
//find element with id='progress' and hide it
$('progress').hide();
}
</script>
</head>
<body>
<img id="progress" src="https://forums.embarcadero.com/servlet/JiveServlet/download/2-21014-135909-1751/progress2.gif" style="display:show;">
<h1="">This is a solar eclipse</h1>
<img src="http://www.zam.fme.vutbr.cz/~druck/eclipse/Ecl2008m/Tse2008_1250_mo1/Hr/Tse2008_1250_mo1.png" width="50%" style="display:show;">
<p>Pretty and large enough to have to wait for</p>
</body>
</html>
I hope this helps