很多高分辨率的图像真的能够扮靓一个Web网站。但是它们也可能会降低网站的(响应)速度——图像都是文件,文件就要占用带宽,而带宽与等待时间直接相关。现在是你进行自我学习,了解如何利用一种叫做图像预加载的小技巧给网站提速的时候了。
图像的预加载
浏览器通常的工作方式是:只有当要求加载图像的HTTP请求被发送的时候,图像才会被加载,而不论它是被动地通过<img>标记加载,还是主动地通过方法调用加载。所以,如果你有一段JavaScript,需要在鼠标悬停的时候切换图像,或者在超时之后自动地更换图像,那么你就可能会在从服务器取回图像的时候随时碰到等待,时间会从数秒钟到几分钟不等。当你以较慢的速度连接到Internet上的时候,或者被取回的图像非常巨大的时候,这种状况尤其显著,而这种数据延迟通常都会毁掉你所期望的效果。
有些浏览器会试图转嫁这一问题,比如把图像保存在本地缓冲区里,这样以后对它的调用就能够很快进行了,但是需要第一次调用图像的时候仍然会产生延迟。预加载是一项在需要图像之前就把它下载到缓冲区里的技术。通过这种方式,当真的需要图像的时候,它可以被从缓冲区里取出来,并立即显示出来。
Image()对象
预加载图像最简单的方法用JavaScript将一个新的Image()对象实例化,并把你想要预加载的图像的URL传递给它。假设我们有一个叫做http://www.host01.com/Get/jsp/00040004/heavyimagefile.jpg的图像,我们希望,当用户把鼠标放在一个已经显示过的图像上的时,系统能够显示出这个图像。为了预加载这个图像,以便实现更快的响应时间,我们只用创建一个新的Image()对象,将其命名为heavyImage,并使用onLoad()事件处理程序把它同时加载到页面上。
1 < html >< head >< script language = "JavaScript" > function preloader() {heavyImage = new Image(); heavyImage.src = " http://www.host01.com/Get/jsp/00040004/heavyimagefile.jpg " ;} </ script ></ head >< body onLoad ="javascript:preloader()" >< a href ="#" onMouseOver ="javascript:document.img01.src='http://www.host01.com/Get/jsp/00040004/heavyimagefile.jpg'" >< img name ="img01" src =http://www.host01.com/Get/jsp/00040004/"justanotherfile.jpg" ></ a ></ body ></ html >
2
要注意的是,图像标记自身并不会处理onMouseOver()和onMouseOut()事件,这就是为什么上面例子里的<img>标记被放在一个<a>标记里,后者的确加入了对这些事件类型的支持。
用数组加载多个图像
在实际操作中,你可能需要预加载一幅以上的图像;例如,在包含有多个图像翻滚(rollover)的菜单条里,或者如果你正在尝试创建平滑的动态效果。这并不困难;你所需要做的就是使用JavaScript的数组,就像下面例子里的一样:
1 < script language = " JavaScript " > function preloader() { // counter var i = 0; // create object imageObj = new Image(); // set image list images = new Array(); images[0]="image1.jpg" images[1]="image2.jpg" images[2]="image3.jpg" images[3]="image4.jpg" // start preloading for(i=0; i<=3; i++) { imageObj.src=images[i]; }
2 } </ script >
在上面的例子里,你先定义变量i和叫做imageObj的Image()对象。然后定义一个叫做images[]的新数组,在这个数组里,每个数组元素都保存着需要预加载的图像来源。最后,创建一个for()循环,让它在数组里循环,并将它们中的每一个都指派给Image()对象,这样就能够把它预加载到缓冲区里。
onLoad()事件处理程序
就和JavaScript里的其它很多对象一样,Image()对象也带有多个事件处理程序。这其中最有用的毫无疑问的就是onLoad()处理程序了,它会在完成图像加载的时候被调用。这个处理程序可以与自定义的函数一起使用,以便在完成图像加载之后进行特定的任务。下面的例子通过在图像加载的时候显示“请等待(please wait)”提示信息来说明这个问题,然后在图像完成加载之后就向浏览器发送一个新的URL。
< html >< head >< script language ="JavaScript" > // create an image objectobjImage = new Image(); // set what happens once the image has loaded objImage.onLoad=imagesLoaded(); // preload the image fileobjImage.src='http://www.host01.com/Get/jsp/00040004/images/image1n.gif';// function invoked on image loadfunction imagesLoaded(){ document.location.href='index2.html';}</script></head><body>Please wait, loading images</body></html>
当然,你还可以创建一个图像数组,对它进行循环,预加载每个图像,并在每个阶段对已加载图像的数量保持跟踪。一旦加载了所有的图像,事件处理程序就能够按照设定把浏览器带到下一个页面(或者进行其他的任务)。
预加载与多状态菜单
现在,把你刚刚学到的理论付诸真正的实践怎么样?下面一部分内容就是我碰巧编写的一段代码——一个由多个按钮(图像链接)组成的菜单条——其中每个按钮都可能处于三种状态中的一种:正常(normal)、hover(悬停)和点击(click)。由于所有的按钮都有多个状态,所以就有必要使用图像预加载来确保菜单能够根据其切换到的状态进行快速的响应。列表A里的代码就说了这一点。
列表A里的HTML代码会建立一个由四个按钮组成的菜单条,每个按钮都有三种状态:正常、悬停和点击。其要求如下:
但鼠标移动到处于正常状态的按钮上时,按钮会变为悬停状态。当鼠标移开的时候,按钮又会恢复到正常状态。当鼠标点击按钮的时候,按钮就会变为点击状态。它会一直保持这个状态,直到另外一个按钮被点击。如果有一个按钮被点击,那么其他的按钮就都不能处于点击状态。其他的按钮只能够处于悬停或者正常状态。一次只能有一个按钮可以被点击。一次只能有一个按钮处于悬停状态。
第一项任务是建立保存有菜单每个状态的图像的数组。与这些数组元素相对应的<img>元素也都在HTML文档的主体里被创建,并按顺序命名。要注意的是,对数组值的索引是从0开始的,而相应的<img>元素是从1开始命名的——这就需要在脚本后面的一段里进行某种计算上的调整。
PreloadImages()函数会负责把所有的图像都加载到缓冲区里,这样的话对鼠标移动的响应时间会被减到最小。一个for()循环被用在第一步里创建的图像里进行迭代,并预加载每一个图像。
ResetAll()函数是把所有图像恢复都到它们正常状态的方便方法。这是有必要的,因为当菜单的项目被点击的时候,菜单里其他所有的项目都必须在被点击项目能够切换到点击状态之前恢复到正常状态。
SetNormal()、setHover()和setClick()函数负责把特定图像(图像的编号被作为函数的自变量进行传递)的来源分别改为正常、悬停或者点击状态。由于被点击的图像必须一直保持点击状态,直到另外一个图像被点击(见第二项要求),所以它们暂时不会对鼠标移动作出反应;这样的话,如果按钮还不是处在点击状态,那么setNormal()和setHover()函数所包括的代码就只能用来改变按钮的状态。
上面所提到的预加载只是提高你JavaScript效果响应时间的多种方法之一。就在你的网站上使用上面列出的技巧,并根据你的要求在需要的地方更改它们吧。祝你好运!