<li>
<a href="#"><img src="img/photo01.jpg" alt="description"
onmouseover="javascript:getImageDetails();" /><img src="img/photo01.jpg"
alt="description" class="preview" /></a>
</li>
|
将上述代码添加到这 20 个图像标记并重新加载页面。请您也尝试重新加载您的页面并查看结果。您觉得如何?图 4 显示了该设置的效果:
很麻烦,是不是?部分原因可能是因为使用了警告。每次当鼠标移动到图像之上时,都会弹出一个警告,而且必须要确认后这个警告窗才能消失。更不要提为了添加此处理程序而更改 HTML 中的全部 20 个 img 标记是多么繁琐了。
但更大的问题是可用性。最终,我们的 getImageDetails() 函数需要调用一个服务器端脚本 —— 而且针对每个鼠标移动事件都要这么做!这意味着即使是缩至第二列的第三个图像,只要是鼠标移至其上的每个图像,服务器都会相应动作。这太差劲了 — 太多不必要的处理负荷。
更好的做法是使用大 图像(带 “preview” 类)的 onClick 事件,这样,当单击图片库时,有关细节会被从服务器中拉出。但这意味着要从 20 个图像中删除鼠标移上处理程序并向另多出来的 20 个图像中添加一个新的处理程序;这太过混乱。让我们退一步以修复这个问题,请记住大多数 Ajax 应用程序都是极度动态的并且不依赖大量 HTML 更改。
如下所示的是一个简单的 JavaScript 函数(与所编写的其他的 JavaScript 代码一同放在 hoverbox-ajax.js),它遍历页面上的所有 img 标记,查找具有特定 CSS 类 “preview” 的所有图像。然后,每个图像的 onclick 处理程序再指向 getImageDetails 方法。太完美了!
function addImageHandlers() {
var imagesDiv = document.getElementById("images");
var imageElements = imagesDiv.getElementsByTagName("img");
for (var i=0; i<imageElements.length; i++) {
var class = imageElements[i].className;
if (class == 'preview') {
imageElements[i].onclick = getImageDetails;
}
}
}
|
现在就可以通过将其放入页面 body 元素的 onLoad 处理程序来运行它,如下所示:
<body onLoad="addImageHandlers();"> |
这是一种极标准的 “Ajax 式” 的模式:以编程的方式添加事件处理程序,而不是在 HTML 中手动添加。这种模式最大的好处是可以很方便地进行更改,而不必触及代码中的全部 20(或 40!)个图像元素。
再次运行页面并注意,现在必须要单击每个图像以弹出警告框。更棒了!
接下来,我们需要利用我们的 JavaScript 函数找出所单击的图像的名称并确保该名称符合 PHP 服务器端脚本所要求的格式。最简单的部分是要将整个图像路径传递到此函数,原因是当调用某个 JavaScript 函数时,浏览器都会知道是页面上的哪个 元素调用的该函数。可以利用 this 关键词访问该元素。
要想看看其中的工作原理,可以按照如下所示更改 getImageDetails() 方法:
function getImageDetails() {
createRequest();
alert(this.src);
}
|
this 引用的是调用函数的那个图像元素,src 属性给出的则是图像的源属性。进行这些更改,重新加载页面后,结果应该如图 5 所示:
这是在正确方向上的一大进步!现在,我们的图片库可以调用一个 JavaScript 函数,获得图像的完整路径。
在调用服务器上的 PHP 脚本之前,只剩一个步骤要做。那就是将图像路径转变成只包含单一名称(即照片的名称),不包含任何路径信息或扩展名。所以对于 “file:///Users/bmclaugh/Documents/developerworks/ajax_2-backEnd/hoverbox/img/photo05.jpg”,希望发送给 PHP 脚本的只是 “photo05”。这实际上更像是一种 JavaScript 练习而非一个与 Ajax 相关的任务,代码如下所示:
function getImageName(imagePath) {
var splitPath = imagePath.split('/');
var fileName = splitPath[splitPath.length - 1];
return (fileName.split('.'))[0];
}
|
此函数接受图像路径并只获取名称部分。所以现在可以回过头来,稍许更新 getImageDetails() 函数:
function getImageDetails() {
createRequest();
alert(getImageName(this.src));
}
|
保存、重新加载,终于得到了我们所想要的:一个能获取图像名称并准备将其发给 PHP 服务器端脚本的处理程序。图 6 显示了此阶段的运行效果:
|
向 PHP 脚本发送图像名称非常容易。实现此目的所需要的只是一些 Ajax 101 之类的东西:
function getImageDetails() {
createRequest();
var url = "lookupImage.php?image=" + escape(getImageName(this.src));
request.open("GET", url, true);
request.onreadystatechange = showImageDetails;
request.send(null);
}
|
这与我们一直在使用的那个函数基本相同,不过作了几处更改而已。PHP 脚本的 URL 已经构建,图像名称也已添加完毕(进行了转义以确保传递过程中不会出现编程问题)。之后,请求也设置好了,回调函数也已分配,请求亦发送完毕。没有什么特别的,因为所有工作都已经由在上一节中所编写的 JavaScript 函数完成了。
|