变换图像

要真正制作动画和演示就必须精通随心所欲地变换图像的艺术.

本课我将要把 "图像A" 变换为 "图像B":

imageA.gif

imageB.gif

首先要保证两个图像的大小必须完全相同, 否则当你变换它们时, 新图像将以原图像的尺寸放大或缩小. 当你想变换两个大小不同的图像时就需要使用不同的语句 -- 你只需简单地显示和隐藏不同的层即可.

我们先从第一个图像入手 -- 把 "imageA" 放入名为 "imgDiv" 的 DIV 当中:

<DIV ID="imgDiv">
<IMG NAME="myImg" SRC="imageA.gif" WIDTH=75 HEIGHT=75 BORDER=0>
</DIV>

注意我把图像的NAME属性定义为 myImg, 这个名字将在图像变换时被用到. 名字绝对不能有重复, 在 IE4 中图像的名字不能与 DIV 的名字相同, 否则它将无法正常工作. 通常我在想用的名字后面加上 "Img", 就象我在一个层的 ID 后面加上 "Div" 一样, 这样就避免了命名的冲突.

预载图像

变换图像之前你需要把不同的图像预载入浏览器的缓存里. 以下是预载一个图像的基础代码:

imagename = new Image();
imagename.src = "imagefilename.gif";

它的作用是建立一个图像对象. 它并不能显示什么, 只是从此我们就可以在任何时间里读取这个对象中的图像了. 换句话说只要我们需要, 这个图像随时可以被访问到 -- 你毋须等待它的下载, 因为它已被放入缓存. 由于我们需要的是图像A (imageA) 和图像B (imageB) 两个图像, 所以我必须将二者同时预载:

imageA = new Image();
imageA.src = "imageA.gif";
imageB = new Image();
imageB.src = "imageB.gif";

preload( ) 函数

要预载的图像越多, 你就越不愿意每次都重复书写这两行代码. 为了避免重复劳动, 我们把它简化为一个 preload() 函数:

function preload(imgObj,imgSrc) {
	if (document.images) {
		eval(imgObj+' = new Image()')
		eval(imgObj+'.src = "'+imgSrc+'"')
	}
}

在这里:

示例:

preload('imageA','imageA.gif')
preload('imageB','imageB.gif')

最好在页面下载的过程中同时预载图像而不要等到整页传完后再进行这项工作, 所以我总是建议立即运行预载函数.

更换图像

一旦图像预载结束你就可以随时调用和更换页面里的图片了. 在 Netscape 和 IE 中变换层里的图像时会稍有不同, 在这里我先为每个浏览器写一段代码, 然后再给你一个通用的函数.

如果图像并非一个层, 通常是这样来变换图像:

document.images["imageName"].src = imageObject.src

在这里imageName是提供给 IMG 标签的名字, 而imageObject则是要预载的图形对象的名字.

具体到我的示例中就是:

document.images["myImg"].src = imageB.src

但是要记住, 这是指图像不在层中, 一旦图像放在层中情况就会发生变化.

在 Netscape 中, 你必须指明用的是什么 DIV 标签(即层). 在我的例子中图象是放在imgDiv层中, 所以你必须在代码前添加document.imgDiv.document:

if (ns4) document.imgDiv.document.images["myImg"].src = imageB.src

在层名(即imgDiv)和"images"之间的"document"是必须的, 因为 Netscape 将层视为一个完全独立的文件.

但是在 Internet Explorer 中你则不必考虑这一点, 你完全不用理会图像是否在某个层中:

if (ie4) document.images["myImg"].src = imageB.src

好了, 现在你要做的就是将代码放入一个单独的函数中, 当需要更换图片时调用这个函数就可以了:

function changeToA() {
	if (ns4) document.imgDiv.document.images["myImg"].src = imageA.src
	if (ie4) document.images["myImg"].src = imageA.src
}

function changeToB() {
	if (ns4) document.imgDiv.document.images["myImg"].src = imageB.src
	if (ie4) document.images["myImg"].src = imageB.src
}

查看images1.html, 它使用了以上两个函数.

changeImage( ) 函数

changeImage() 函数的作用是每次想更换图片时不再需要单独的函数了. 你只需放入相应的层名, 图片名和预载图片名 -- 注意, 是层名, 图片名图片对象分别放入:

function changeImage(layer,imgName,imgObj) {
	if (document.layers && layer!=null) eval('document.'+layer+'.document.images["'+imgName+'"].src = '+imgObj+'.src');
	else document.images[imgName].src = eval(imgObj+".src");
}

具体到本课, 我只需把 changeToA() 函数简单地替换为:

changeImage('imgDiv','myImg','imageA')

同样, 对于 imageB 则是:

changeImage('imgDiv','myImg','imageB')

查看使用了 changeImage() 函数的示例images2.html.

提示:

changeImage() 函数同样适用于嵌套层, 对于layer变量你可以插入parentLayer.document.childLayer, 类似于动态层对象处理嵌套层的方法.

你甚至可以不在层中对图像使用这个函数, 仅需在层变量中加入保留字null:

changeImage(null,'myImg','imageB')

同样, changeImage()具有向下兼容性. 如果你在 Netscape 3 中浏览一个含有层的页面, 这个函数仍能很好地表现出来. 这个浏览器也支持其他示例. 由于其他浏览器不支持图像更替, 因此如果你想检查一个浏览器是否具有这项功能, 你可以使用这段改变后的 changeImage() 函数:

function changeImage(layer,imgName,imgObj) {
	if (document.images) {
		if (document.layers && layer!=null) eval('document.'+layer+'.document.images["'+imgName+'"].src = '+imgObj+'.src')
		else document.images[imgName].src = eval(imgObj+".src")
	}
}

changeImage()和preload()函数都是DynAPI的一部分, 并包括在 images.js 文件中:

源代码

下载: images.js
看源代码: images.js

鼠标变图

我曾指出过鼠标变图是一种行将消亡的功能, 所以在此之前我并没有提及它. 但是由于有不少人向我问及, 所以我就简单地演示一下如何用 changeImage() 函数来表现这个效果.

鼠标变图的原理非常简单, 当你将鼠标放在一个图像上, 它就改变为另一个不同的图像, 当你移开鼠标时, 它又变回原来的图像. 为了达到这个目的, 你必须为 IMG 标签加上锚点/超链接并在使用 onMouseOver 和 onMouseOut 事件的同时调用 changeImage() 函数. onMouseOver 和 onMouseOut 事件必须从超链接中调用, 因为 Netscape 的 IMG 标签不能建立此类事件.

但是要记住, 你必须把锚点标签链接到某个地方才能使用这个功能. 通常变图功能用于工具栏, 你只要把它链到某个与其关联的页面就可以了. 但如果你并不想把它链接到任何别的地方, 你可以在 HREF 处用javascript:void(null)代替目标. 这个命令不会做任何实际操作. 这样超链接仍然存在 -- 而这个链接执行的是一个什么都不做的 javascript 命令.

<DIV ID="imgDiv">
<A HREF="javascript:void(null)"
onMouseOver="changeImage('imgDiv','myImg','imageB')"
onMouseOut="changeImage('imgDiv','myImg','imageA')">
<IMG NAME="myImg" SRC="imageA.gif" WIDTH=75 HEIGHT=75 BORDER=0></A>
</DIV>

查看鼠标变图示例images3.html.

首页 下一课: 剪切层
copyright 1998 Dan Steinman
Translated by Cartouche YU