Download (binary) image using Ajax - html

I would like to dynamically insert an image in a webpage using javascript. The easiest way of course is just to update the 'src' tag of an element. However, the image is actually a dynamically generated PNG, and it takes about 15sec to generate it every time. If I just update the 'img' tag, I am afraid impatient users will think the url is dead and leave the page before it displays, therefore I would like to display a loader.
In order to be able to display a loader I have to download the image through Ajax, and then insert in in the document. Is this possible? I tried to first do an Ajax request, and then when it succeeds update the img src tag hoping that browsers would be smart enough not to re-downoad the image, but apparently this is not the case.
Is there any workaround to have control over the http request of the img without introducing new server code?

When the page is loaded you could show some dummy image which will represent the loading progress:
<img src="loader.gif" id="myimg" />
and then replace it with the actual dynamic image:
$(function() {
$('#myimg').load(function() {
$(this).unbind('load');
this.src = '/script/dynamicimage';
});
});

You could show the loader, and then download the slow image in a hidden tag with an Ajax request, and then when it's loaded hide the loader and display the img.
EDIT: as pointed out by Pekka, load() is unreliable, so that's a no-go. This post deals with the same problem and provides 2 possible solutions:
Use $(window).load to detect when ALL elements in the page (including images) have been loaded. This may or not be suitable, depending on your needs.
There's a link to a snippet in github with a $().imagesLoaded function that is mostly a hack for working around this problem.

It's not very clear what you are trying to do, however...
1.First, attach a load event handler to your image tag, the one you're going to set its src to the newly created image. Make this img tag load the loader animation for example, or just use another tag for that one.
2.Then do an AJAX request to the server script that generates your dynamic image.
3.On the success callback of the AJAX call set the src of the previous mentioned img tag to the image the server has just created. Bare in mind that the fact that the image took time to generate on the server doesn't mean the browser won't take it's own time to load it.
That's why we have attached the load event handler to it before.
Also, hide the loader if you've used a separate DOM element for it.
This should also cover issues with browsers not firing the load event for cached images.

Send an ajax request to download the image and show the loading animation.
On server side, when request is received, create the image and save it in a temporary place.
Send back ajax response to browser the path of image.
Change the src attribute of image one got through ajax.
I hope it will work.

Related

If I create and Image object but doesn't add it into DOM, does it downloaded image src into user's page?

I have typed in below code in my page:
var img = new Image();
img.src="abc.jpg"
abc.jpg is a pagecounter which helps me to count the pageview once it is loaded. For this case, I only create the img element, but doesn't add it into DOM.
Is the image downloaded into user's page? Or I must needed to add it into DOM?
Thanks a lot.
================================================================
In order to make the things more clear, here provides a demo page: http://ad3.guruonline.com.hk/mobmax/testing/stackoverflow.html
This page is referencing a JS file "stackoverflow.js":
And for stackoverflow.js, it creates a variable "img" which points to "stackoverflow.jpg"
So, I go back to stackoverflow.html, and view the "network" tab : the most surprising is, stackoverflow.jpg is actually downloaded!
Accoridng to KK's answer, stackoverflow.jpg shouldn't be downloaded, right? Because I never add it to DOM. Can someone provide a explanation on this scenrio?
Thanks!
Update
After going through the revised post ,it appears that the image loads irrespective of whether it is added into the DOM or not. Maybe this is how the Image object works. Another interesting thing is that if you define a normal Javascript Object and add the src url in that object as key value pair i.e.:
img["src"]="http://www.example.com/image/sameple.jpg";
Then in this case there is no loading of image which can be verified by looking at the network tabs. So yes, Image() does loads the src even if the image is added into the DOM or not.
This technique has been used to preload images, which can be found in this link for more details: http://www.techrepublic.com/article/preloading-and-the-javascript-image-object/
Good question though!
Without being added to the DOM, it's just a variable and it will be treated like a variable. You will need to add it to the DOM for image to be loaded. If you want to preload the images, you can use a hidden image tag which loads the image. You may refer to this solution for preloading the images: How to Preload Images without Javascript?
You need to add it by creating a Dom node as without it, the element won't be added yo the DOM

How can I make an iframe capture ONLY one element of a web page?

I'm trying to capture div#map-canvas from my site, www.RichBlocksPoorBlocks.com, to make an iframe that people can embed anywhere.
Here's my iframe
<iframe src="http://www.richblockspoorblocks.com#map-canvas" style="width:600px; height:400px;"></iframe>
It goes to div#map-canvas, but it also loads the rest of the page as well. I'd like that div to be the only thing in the iframe.
Is this possible with an iframe?
To achieve this, it would be easier to create a separate .php or .html document which contains only the parts that you want to show in the iframe and exclude everything else.
So, instead of the iframe pointing to "http://www.richblockspoorblocks.com#map-canvas", it would point to something like : "http://www.richblockspoorblocks.com/map-canvas.php".
This would be a very quick and efficient way of doing what you want, and doesn't require any outside libraries or javascript.
When you call http://www.richblockspoorblocks.com#map-canvas the hash will probably cause the browser to look for a corresponding <a name="foo">bar</a> so this won't work using an iFrame.
What I would recommend doing is writing a script which you call from your iFrame which accepts the name of the page fragment to load. I know using jQuery's $.load() you can call an element ID to load a page fragment, and I think it's also possible in PHP too...
You cannot use hash links in iframes.
You can and should use, few lines of you'r favorite server side language to create the specific content you want to render and then link to it. in that way, you'r server will send out to the end user only the desired data and also it saves bandwith and loading time.

<img> downloading order - possible to set?

I understand the answer to this is most likely No... but I wanted to ask.
Is it possible to have one img start downloading first?
Basically I have a place holder GIF (that shows in the place of images as they download and I want to get that GIF downloaded as quickly as possible.
Am I able to somehow fast track the downloading of one img (the GIF)?
thx
Try putting an <img> tag with the gif as src before all other <img> tags and hide it with visibility:hidden
You could include that image as a data URI (if it's not too large), so that there's no separate network request made to fetch that image. It will, of course, increase the size of the actual HTML content served.
You could also preload the image using JavaScript by making a new image object and setting the src attribute.
You can have placeholder gifs, eg (in css)
img{background-image:url(default_image.png)}
However, there is no good way to force one image to load before another. Browsers can load in whatever order they want.
You can make it more likely that the placeholder is downloaded first:
If the placeholder is the same on all pages, it can get cached, so that on the next page, it is already loaded
Make sure that the placeholder image is early in the page (makes the browser start loading earlier, a browser will probably load images in the order they appear in the html). If image shouldn't be displayed there, just do something like width="0" or visibility: hidden;
Put the placeholder somewhere that the server serves quickly (avoid dynamically controlled folders - serve it in a static directory, eg. in the public/ folder for Apache)
Make the placeholder image small
Encourage caching by setting the cache headers so that the image expires in the far future (eg. 1 year), and so that the browser doesn't need to check back with the server. Also make sure private caching is off for the image (allow public server caching).
Data URIs are not that great. From Wikipedia:
Data URIs are not separately cached from their containing documents
(e.g. CSS or HTML files) so data are downloaded every time the
containing documents are redownloaded.
Referencing the same resource (such as an embedded small image) more
than once from the same document results in multiple copies of the
embedded resource. In comparison, an external resource can be
referenced arbitrarily many times, yet downloaded and decoded only
once.
If you use the placeholder image in 10 places on your page, you are going to have a much larger page.
You could try to dynamically load everything you don't want loaded before that gif (and is somewhat significant in size). Then, you could load that gif, and after it's done - load the rest of the content.
This could be done using Javascript. I'm not sure if there's already a library that helps you do this easily, but it shouldn't be too hard to do.
I'd start off using something along the lines of "on document.ready, load that important gif, then when that finishes, load the rest":
$(document).ready( function() {
var myImportantImg = $('<img />');
$(myImportantImg).on('load', function() {
// attach myImportantImg somewhere
// load rest
});
$(myImportantImg).attr('src', 'http://url.to/myImg.gif');
});
From what I read using Data URI Scheme in conjunction with css would be a good option:
img.placeholder {
background: white url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC') no-repeat scroll left top;
}
Include the above code in a <style>-tag in the documents <head>-section to make sure it's loaded with the page, and tag the appropriate images with the placeholder-class:
<img src="..." class="placeholder">

Is there any way to request a page without displaying it?

If you link to something downloadable with a simple <a href, the user will download the file while staying on the current page. You can get this behavior with files that the browser has no plugin for (like .bin), or by sending a content-disposition header to force downloading.
Is there any method or header which keeps the user on the current page while still requesting the page? The idea is that the user clicks a link, the request is made, but the page doesn't change—like when downloading a file.
This could be done with an iframe I guess, which is not really pretty and makes another request when loading the page. Javascript is another obvious answer, but that's actually the reason for asking this question: compatibility with JS-less clients.
A form with the method set to HEAD is another ugly solution, but doesn't work anyway. Chromium ignores the method and simply performs a GET request...
Anymore ideas?
You could place an iframe on your page that is hidden. Then, give that iframe and id.
Use this id as the target of a link to the file you want to pull down.
I've created a demo at http://jsfiddle.net/dancrumb/N87nL/ to show you how this would work. Just style the iframe as being invisible and you're good to go
The page will load in the iframe, you'll stay on your page, it doesn't require JS. Oh boy!
Note that the iFrame doesn't have an initial value for src, so no request is made on page load.

HTML frame tag URL of browser not changing

How do I change the URL of the browser with a website using a structure of <frame>. I know the whole point of <frame> is to use embedded frames so that you can't tell where the site is going. In particular, when you click a link, the frame changes, but the URL at the top of the browser says the same thing.
I'm trying to make it so that the browser CHANGES the URL, so the real URL of the main inner frame is shown at all times. How can I do this?
You can't; best bet is to change the fragment with JavaScript, e.g. window.location.hash = 'whatever'.
You will need to use JavaScript to then detect this and modify the frame's src attribute.
Try to use a javascript to change window.location.hash, see this article : http://bytes.com/topic/javascript/answers/170365-change-browser-url-without-navigating-away
or this question How do I, with JavaScript, change the URL in the browser without loading the new page?