第七部分:图象对象

web页上的图象

  现在我们来看一看 Javascript1.1中新出现的图象对象(需要Netscape Navigator 3.0以上), 通过使用图象对象,你可以在web页上改变图象,产生动画般的效果。
  请记住使用低版本浏览器的读者(象Netscape Navigator 2.0 或Microsoft Internet Explorer3.0- 它们只支持 Javascript 1.0)无法看到下面的例子,或所有的效果。
  首先我们来看一看怎样通过使用Javascript来使一个图片联接一个URL地址。 所有的图作为一个数组,这个数组被称为images。它是文本对象的一个特性。web页上的 每一个图有一个序号。第一个图的序号是0,第二个图是1,依次类推。由此我们可以利用 document.images[0]来表示第一个图。
  HTML页中的每一个图都是一个图象对象。每一个图象对象的特性都可以利用Javascript来获得。 象可以利用 width和 height来得到一个图的大小。 document.images[0].width 给出了web页上第一个图象的宽度(像素)。
  当你在一个web页上使用很多图时,给每一个图指定一个名字就显得很重要,你可以使用下面的 符号来标记一个图象

<img src="img.gif" name="myImage" width=100 height=100>

你可以使用document.myImage或 document.images["myImage"]来使用它。

载入新图片

  在这里我们不必学习如何知道web页上一个图形的大小,我们来学一学如何改变web 页上的图片,为此我们将要用到 src 特性。在 <img> 符号中的 src 特性表示了显示的图片的地址,通过使用 JavaScript 1.1 你能够对一个web页上已经载入的图片赋予一个新地址,结果就是一个新的图片被载入了。 这个新载入的图片代替了web页上的旧图片,看看这个例子:

<img src="img1.gif" name="myImage" width=100 height=100>

被载入的图片 img1.gif 同时被命名为 myImage。下面的代码显示了如何用新图片 img2.gif 取代了旧图片 img1.gif:

document.myImage.src= "img2.src";

新的图片的尺寸必须和旧的图片一样,你不能改变显示的图片的尺寸,单击下面的按钮,你可以试试这一个例子:

图片的预载入

  一个不利之处在于新的图片会在src特性中指定新地址之后再被载入,因为图片 不是预载入的所以在通过Internet 取回图片时会有一些时间上的延迟,有时这不算什么,但 这样的延迟经常是令人难以忍受的。怎么办呢?预载入是一个解决方法。在这种情况下我们必须 生成一个新的图像对象。看看下面这些代码:

hiddenImg= new Image();
hiddenImg.src= "img3.gif";

  第一行生成了一个图像对象。第二行定义了hiddenImg对象要表现的图像的地址。 我们已经看到给src指定一个新地址会强制浏览器载入这个地址所指定的图片。所以当执行第二行代码时图片img2.gif就被载入了。hiddenImg使图片在浏览器载入后并不马上显示。只是在内存中保留它(或者保存在cache中)。如果想显示它,可以使用下面的这行命令:

document.myImage.src= hiddenImg.src;

现在图片就会马上被显示了。我们尝试了预载入图片。

  当然浏览器为了使载入的图片立即显示,首先必须结束预载入。所以如果你对很多图片使用了预载入技术的话,会使浏览器化一定的时间去下载所有的图片。你必须考虑到Internet的速度--使用预载入技术并不会使下载的速度加快。我们只是使下载图片的时间早一些--用户也会早一些看到它们。(小张:现在大概很少人用14.4以下的猫了吧,上面讨论的这些技术不一定会派上用处了)

在特定事件中作图像转换

  在一些特定的事件中,你可以图像转变的技术作出有趣的效果。例如在光标移到一个特定的位置时,改变一幅图片。试一下下面的例子(在只支持 Javascript 1.0的浏览器中,你会得到一个错误信息,下面我们会学习如何防止这个错误信息的出现):

这个例子的源代码是这样的:

<a href="#" 
  onMouseOver="document.myImage2.src='img2.gif'" 
  onMouseOut="document.myImage2.src='img1.gif'">
<img src="img1.gif" name="myImage2" width=160 height=50 border=0></a>

下面情况下会产生错误:

现在我们来看一看能解决所有这些问题的完整的代码。下面两点可以保证代码的可扩展性:

这儿你可以看到效果:


下面是源代码(加入了注解):


<html>
<head>

<script language="JavaScript">
<!-- hide

// ******************************************************
// Script from Stefan Koch - Voodoo's Intro to JavaScript
//     http://rummelplatz.uni-mannheim.de/~skoch/js/ 
//       JS-book: http://www.dpunkt.de/javascript
//    You can use this code if you leave this message
// ******************************************************

  // ok, we have a JavaScript browser
  var browserOK = false;
  var pics;

// -->
</script>

<script language="JavaScript1.1">
<!-- hide

  // JavaScript 1.1 browser - oh yes!
  browserOK = true;
  pics = new Array();

// -->
</script>



<script language="JavaScript">
<!-- hide

var objCount = 0; // number of (changing) images on web-page

function preload(name, first, second) {  

  // preload images and place them in an array

  if (browserOK) {     
    pics[objCount] = new Array(3);
    pics[objCount][0] = new Image();
    pics[objCount][0].src = first;
    pics[objCount][1] = new Image();
    pics[objCount][1].src = second;
    pics[objCount][2] = name;
    objCount++;
  }
}

function on(name){
  if (browserOK) {
     for (i = 0; i < objCount; i++) {
      if (document.images[pics[i][2]] != null)
        if (name != pics[i][2]) { 
          // set back all other pictures
          if (pics[i][0].complete)
            document.images[pics[i][2]].src = pics[i][0].src;
        } else {
            // show the second image because cursor moves across this image
            if (pics[i][1].complete)
              document.images[pics[i][2]].src = pics[i][1].src;
        }
    }
  }
}

function off(){
  if (browserOK) {
     for (i = 0; i < objCount; i++) {
      // set back all pictures
      if (document.images[pics[i][2]] != null) 
        if (pics[i][0].complete)
            document.images[pics[i][2]].src = pics[i][0].src;
    }
  }
}

// preload images - you have to specify which images should be preloaded
// and which Image-object on the wep-page they belong to (this is the first
// argument). Change this part if you want to use different images (of course
// you have to change the body part of the document as well)

preload("img1", "img1f.gif", "img1t.gif");
preload("img2", "img2f.gif", "img2t.gif");
preload("img3", "img3f.gif", "img3t.gif");

// -->
</script>
<head>



<body>
<a href="link1.htm" onMouseOver="on('link1')" 
  onMouseOut="off()">
<img name="link1" src="link1f.gif" 
  width="140" height="50" border="0"></a>

<a href="link2.htm" onMouseOver="on('link2')" 
  onMouseOut="off()">
<img name="link2" src="link2f.gif" 
  width="140" height="50" border="0"></a>

<a href="link3.htm" onMouseOver="on('link3')" 
  onMouseOut="off()">
<img name="link3" src="link3f.gif" 
  width="140" height="50" border="0"></a>
</body>
</html>

这段代码把图片加入了一个pics数组。在开头调用的函数preload()定义了这个数组。我们是这样调用这个数组的:

preload("img1", "img1f.gif", "img1t.gif");

这段代码将载入img1f.gif 和img1t.gif 两幅图片。第一个图片时光标还没移上去时所显示的图片。当用户移动光标到图片上时,第二幅图片就显示出来了。preload()函数中的"img1" 用来指定这两个预载入的图片属于页面上哪一个图像对象。在<body>中你会看到一个使用了img1名字的图片,我们利用了图片的名字(而不是序号),来改变图片的次序 - 不需要改变代码。
on() 和 off()这两个函数在onMouseOver 和 onMouseOut事件处理器中被调用。on()函数会把图片改会成原来的,这是很必要的 - 当你把鼠标直接从图片上移出页面外时,MouseOut是不起作用的。

  利用图片可以大大增强你的页面的视觉效果。图像对象可以制作出极佳的效果。但请记住,不是每一个图片和Javascript程序都是好的。如果你在网上多逛逛,你可以看到滥用图片的很多例子。不是图片的数量使你的页面更好,而是质量。化大时间去下载50kb的图片时令人无法忍受的。请记住适当的使用图像对象,也许会使用户更喜欢你的 web页。