When developing a website, you often need to browse a large number of images on a certain page. If you consider traffic, you can only display one image per page like pconline, so that users need to download the entire page again every time they see an image. However, in the era of web2.0, more people are willing to use javascript to implement an image browser, so that users can see other images without waiting too long.
If you know the address of a picture, you need to display it in a fixed-size html container (can be a div, etc.). The most important thing is of course you need to know the width and height of the picture to be displayed, and then combine the width and height of the container to display the picture at a certain scale. Therefore, realizing image preloading has become the core function of the image browser.
Friends who have done image flips actually know that to prevent waiting during image rotation, it is best to download the image locally and cache the browser. At this time, the Image object in js is usually used. The general method is nothing more than this:
function preLoadImg(url) {
var img = new Image();
= url;
}
By calling the preLoadImg function and passing in the url of the image, the image can be downloaded 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, it should be considered that when using the image browser function, the pictures are displayed in real time. For example, if you click the displayed button, then you will call the above code to load the picture. Therefore, if you use it directly, the image has not been fully downloaded. Therefore, some asynchronous methods are needed to wait until the image is downloaded, and then the width and height of img will be called again.
It is actually not difficult to implement such an asynchronous method. The image download event is also very simple, which is a simple onload event. Therefore, we can write the following code:
function loadImage(url, callback) {
var img = new Image();
= url;
= function(){ //Callback function asynchronously when the image is downloaded.
(img); // Switch the callback function this pointer to img.
};
}
OK, let's write another test case.
function imgLoaded(){
alert();
}
<input type="button" value="loadImage" onclick="loadImage('',imgLoaded)"/>
After testing it in firefox, I found it is good. As expected, the width of the picture will pop up after the image is downloaded. No matter how many times you click or refresh the result, it will be the same.
However, don't be too happy to do this first - you still need to consider the compatibility of your browser, so hurry up and test it in ie. That's right, the width of the picture also pops up. However, when you click on load again, the situation is different and there is no reaction. Refresh, the same is true.
After testing multiple browser versions, it was found that ie6 and opera will be like this, while firefox and safari perform normally. In fact, the reason is quite simple, because of the browser's cache. When the image has been loaded once, if there is another request for the image, since the browser has cached the image, it will not initiate a new request, but will be loaded directly from the cache. For firefox and safari, their views make these two loading methods transparent to the user, which will also cause the image onload event, while ie and opera ignore this identity and will not cause the image onload event. Therefore, the above code cannot achieve the effect in them.
What to do? The best case is that Image can have a status value indicating whether it has been loaded successfully. When loading from the cache, this status value directly indicates that it has been downloaded because it does not need to wait. When loading from http request, this value is displayed as unfinished because it needs to wait for download. In this way, it can be done.
After some analysis, we finally found an attribute of an Image that is compatible with each browser - complete. Therefore, make a judgment on this value before the image onload event. Finally, the code becomes like this:
function loadImage(url, callback) {
var img = new Image(); //Create an Image object to implement pre-download of images
= url;
if () { // If the image already exists in the browser cache, call the callback function directly
(img);
return; // Return directly, no need to process the onload event
}
= function () { //Callback function asynchronously when the image is downloaded.
(img);//Replace this in the callback function with an Image object
};
};
After all this trouble, all browsers can finally meet our goals. Although the code is simple, it solves the most core problem in the image browser. What you have to do next is just the problem of how to present the image. Let’s take a look at another method:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:///TR/xhtml1/DTD/">
<html xmlns="http:///1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>js implements preloading of images and executes actions after loading</title>
</head>
<style type="text/css">
<!--
*html{
margin:0;
padding:0;
border:0;
}
body{border:1px solid #f3f3f3; background:#fefefe}
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 >
<p><img src="/img/baidu_logo.gif" /></p>
</div>
<script>
var i=0;
var c=3;
var imgarr=new Array
imgarr[0]="/img/baidu_logo.gif";
imgarr[1]="/img/";
imgarr[2]="/img/";
var Browser=new Object();
=();
=/msie/.test();
=/gecko/.test();
function SImage(url,callback)
{
var img = new Image();
if(){
=function(){
if(=="complete"||=="loaded"){
ii=i+1;
callback(i);
}
}
}else if(){
=function(){
if(==true){
ii=i+1;
callback(i);
}
}
}
=url;
}
function icall(v)
{
if(v<c){
SImage(""+imgarr[v]+"",icall);
}
else if(v>=c){
i=0;
//('');// Write your own actions here.
}
}