JS achieves image pre-loading without waiting

Source: Internet
Author: User
Tags image flip

During website development, you often need to browse a large number of images on a certain page. If you consider traffic, you can display only one image on each page like pconline, each time you see an image, you need to download the entire page again. However, in the web era, more people are willing to use javascript to implement an image browser, allowing users to see other images without waiting too long.

After knowing the address of an image, you need to display it in a fixed html container (such as div, the most important thing is to know the width and height of the image to be displayed. Then, combine the width and height of the container to display the image according to a certain scaling ratio. Therefore, image pre-loading becomes the core function of the image browser.

Anyone who has done image flip knows that it is best to first download the image to a local place and cache it for the browser to avoid waiting during image rotation. In this case, the Image object in js is usually used. The general method is nothing more than this:
Copy codeThe Code is as follows:
Function preLoadImg (url ){
Var img = new Image ();
Img. src = url;
}

By calling the preLoadImg function and passing in the image url, you can download the image in advance. In fact, the pre-download function used here is basically the same as this. After the image is pre-downloaded, you can know the width and height of the image through the width and height attributes of img. However, when using the image browser, images are displayed in real time. For example, if you click the displayed button, the above Code will be called to load the image. Therefore, if you use img. width Directly, the image has not been completely downloaded. Therefore, some asynchronous methods are required to call the width and height of the img only after the image is downloaded.

In fact, it is not difficult to implement such an asynchronous method. The download event is also very simple, that is, a simple onload event. Therefore, we can write the following code:
Copy codeThe Code is as follows:
Function loadImage (url, callback ){
Var img = new Image ();
Img. src = url;
Img. onload = function () {// call the callback function asynchronously when the image is downloaded.
Callback. call (img); // switch the callback function this pointer to img.
};
}

Now, write a test case.
Copy codeThe Code is as follows:
Function imgLoaded (){
Alert (this. width );
}
<Input type = "button" value = "loadImage" onclick = "loadImage('aaa.jpg ', imgLoaded)"/>

Test it in firefox and find it is good. It is indeed the same as expected. After the image is downloaded, the image width will pop up. The results are the same no matter how many clicks or refreshes.

However, to do this, don't be too happy-you still need to consider the compatibility of the browser, so hurry to test it in ie. That's right. The image width is also displayed. However, when you click load again, the situation is different and no response is returned. Refresh the page.

After tests on multiple browser versions, we found that ie6 and opera both work like this, while firefox and safari work normally. In fact, the reason is quite simple, that is, the browser cache. After an image is loaded once, if a request is sent to the image again, the browser will not initiate a new request because the image has been cached, instead, it is directly loaded from the cache. For firefox and safari, their views make the two loading methods transparent to users, and will also cause image onload events, while ie and opera ignore this identity, it does not cause the onload event of images, so the above Code cannot achieve the effect in them.

What should we do? The best case is that the Image may have a status value indicating whether it has been loaded successfully. When loading from the cache, because you do not need to wait, this status value directly indicates that it has been downloaded. When loading from an http request, this value is not displayed because you need to wait for download. In this way, you can do it.

After some analysis, we finally found a property of the Image compatible with various browsers-complete. Therefore, make a judgment on this value before the image onload event. Finally, the Code becomes as follows:
Copy codeThe Code is as follows:
Function loadImage (url, callback ){
Var img = new Image (); // create an Image object to implement pre-download of the Image
Img. src = url;
If (img. complete) {// if the image already exists in the browser cache, call the callback function directly.
Callback. call (img );
Return; // return directly without handling the onload event
}
Img. onload = function () {// call the callback function asynchronously when the image is downloaded.
Callback. call (img); // replace this of the callback function with the Image object.
};
};

After so much effort, we finally made every browser meet our goal. Although the Code is very simple, it solves the most core problem in the image browser. Next you have to do the following:
Copy codeThe Code is as follows:
<! DOCTYPE html PUBLIC "-// W3C // dtd xhtml 1.0 Transitional // EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<Html xmlns = "http://www.w3.org/1999/xhtml">
<Head>
<Meta http-equiv = "Content-Type" content = "text/html; charset = gb2312"/>
<Title> js implements the action after image pre-loading is completed </title>
</Head>
<Style type = "text/css">
<! --
* Html {
Margin: 0;
Padding: 0;
Border: 0;
}
Body {border: 1px solid # f3f3f3; background: # fefefefe}
Div # loading {
Width: 950px;
Height: 265px;
Line-height: 265px;
Overflow: hidden;
Position: relative;
Text-align: center;
}
Div # loading p {
Position: static;
+ Position: absolute;
Top: 50%;
Vertical-align: middle;
}
Div # loading p img {
Position: static;
+ Position: relative;
Top:-50%; left:-50%;
Vertical-align: middle
}
-->
</Style>
<Div id = "loading">
<P> </p>
</Div>
<Script>
Var I = 0;
Var c = 3;
Var imgarr = new Array
Imgarr [0] = "http://www.bkjia.com/uploads/allimg/131017/06251135D-0.gif ";
Imgarr [1] = "http://img.baidu.com/img/logo-img.gif ";
Imgarr [2] = "http://img.baidu.com/img/logo-zhidao.gif ";
Var Browser = new Object ();
Browser. userAgent = window. navigator. userAgent. toLowerCase ();
Browser. ie =/msie/. test (Browser. userAgent );
Browser. Moz =/gecko/. test (Browser. userAgent );
Function SImage (url, callback)
{
Var img = new Image ();
If (Browser. ie ){
Img. onreadystatechange = function (){
If (img. readyState = "complete" | img. readyState = "loaded "){
Ii = I + 1;
Callback (I );
}
}
} Else if (Browser. Moz ){
Img. onload = function (){
If (img. complete = true ){
Ii = I + 1;
Callback (I );
}
}
}
Img. src = url;
}
Function icall (v)
{
If (v <c ){
SImage ("" + imgarr [v] + "", icall );
}
Else if (v> = c ){
I = 0;
// Location.replace('banner.html '); // write your own actions here,
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.