views:

238

answers:

1

Hi, I want to create a website which loads a image via XMLHttpRequest(). (XMLHttpRequest because I want to represent the user a % progressbar)

My Code:

var req = new XMLHttpRequest();  

req.addEventListener("progress", onUpdateProgress, false);  
req.addEventListener("load", onTransferComplete, false);  
req.addEventListener("error", onTransferFailed, false);  
req.addEventListener("abort", onTransferFailed, false);  

req.open("GET", "image.png", true);  
req.send();  

function onUpdateProgress(e) {  
 if (e.lengthComputable) {  
 var percent_complete = e.loaded/e.total;  
 if (Math.round(percent_complete*200)>=20) {  
                    $("#progress").animate({  
                    width: Math.round(percent_complete*100)  
            }, 0);  
        }  
      }  
}  

function onTransferFailed(e) {  
    alert("Something went wrong. Please try again.");  
}  

function onTransferComplete(e) {  
   //Problem  
}  

My problem is I don´t know how to show the image which is now loaded. I hope anyone can help me :) Thanks ...

+1  A: 

You can do this using DATA URIs, but it's hard to make that work in all current browsers.

If caching options are set correctly, you can better load it twice: first using your AJAX request, then, after the image has been cached by the browser, another time using the usual image functions. The second time your image will not be retrieved from the server again, but the browser will use the cached file and show the image almost instantly.

Marcel Korpel
This seems to work. But it´s hard to see if the browser really loud the picture only one time. The Safari WebInspector for example shows it two times: electerious.com/share/Web%20Inspector.png
tobiasre
@tobias – Are your server settings correct? Can you show the headers with which the picture is sent?
Marcel Korpel
I think so. Here´s the test site: electerious.com/share/loading.html
tobiasre
@tobias – Hey, I'm looking for laminate flooring; where did you get that? ;)
Marcel Korpel
@tobias – There's another major flaw with your example: you should *preload* your image using an XMLHttpRequest and only after it's fully loaded you can assign the image to your `img` element. Now you're assigning the `src` in your HTML as well and the asynchronous XMLHttpRequest will download the image in parallel with the browser trying to render the image.
Marcel Korpel
@tobias – Whoops, in my previous comment I was looking at the wrong headers. You should add a `Cache-Control: max-age=3155760000` header when serving your image. Also see [Ideal HTTP cache control headers for different types of resources](http://stackoverflow.com/questions/2970938/ideal-http-cache-control-headers-for-different-types-of-resources). Look at http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 for all possible options.
Marcel Korpel
@marcel Dosn´t work. I changed the onTransferComplete(e) function to the following: `$("#image").attr("src", "http://electerious.com/share/Calm_2560_1600.png");` It loads the picture two times now. Also I changed the headers to: `<META HTTP-EQUIV="Cache-Control: max-age=3155760000" CONTENT="NO-CACHE">` Is this right? I updated the test if you want to have a look at it (The wood texture is from http://bit.ly/bT29Ua )
tobiasre
@tobias – No, you don't need that `meta` element in your HTML, I was talking about the HTTP header of *the image*. But I tested this myself, and I see that only when the client explicitly tells to not use a cached version for the image (e.g. using Ctrl-F5 in Firefox), the image is loaded twice. Without that setting (normal reload), I only see an XHR download. BTW, I'm looking for *real* laminate flooring. ;)
Marcel Korpel