欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

图片库改进版

程序员文章站 2022-06-02 23:45:31
...

上一篇博客中已经设计了一个简易的图片库,可以实现把整个图片库的浏览链接集中放在图片库主页里,只在用户点击了这个主页的链接时才把相应的链接发送给他,在点击链接后将网页中的图片替换,而不是网页跳转,点击链接伴随着图片下方文字的替换:
HTML:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Photo Gallery</title>
	<link rel="stylesheet" type="text/css" href="photo gallery.css">
	<script src="photo gallery.js"></script>
</head>
<body>
	<h1>Photo Gallery</h1>
	<ul>
		<li><a href="images/1.png" onclick="showPic(this);return false;" title="基普乔格1">基普乔格1</a></li>
		<li><a href="images/2.png" onclick="showPic(this);return false;" title="基普乔格2">基普乔格2</a></li>
		<li><a href="images/3.png" onclick="showPic(this);return false;" title="基普乔格3">基普乔格3</a></li>
		<li><a href="images/4.png" onclick="showPic(this);return false;" title="贝克勒1">贝克勒1</a></li>
		<li><a href="images/5.png" onclick="showPic(this);return false;" title="贝克勒2">贝克勒2</a></li>
		<li><a href="images/6.png" onclick="showPic(this);return false;" title="贝克勒3">贝克勒3</a></li>
	</ul>
	<div id="box">
		<img id="placeholder" src="images/7.png" height="300" width="400" alt="my image gallery"/>
		<p id="description">Choose a image</p>
	</div>

</body>
</html>

CSS:

body{
	font-family: "Helvetica","Arial",serif;
	color:#C0C0C0  ;
	background-color:#483D8B;
	margin: 1em 10%;
}
#box{
	width: 400px;
	height: 300px;
	border:1px 	solid #8A2BE2;
	margin: 8em 8px;
}
a{
	color: #c60;
	background-color: transparent;
	font-weight: bold;
	text-decoration:none;
}
ul{
	padding: 0;
}
li{
	float: left;
	padding: 1em;
	list-style-type: none;
}
img{
	display: block;
	clear: both;
}
p{
	color:#C0C0C0 ;
}

JS:

function showPic(element){
	var source=element.getAttribute("href");//获取元素节点的src属性值
	var placeholder=document.getElementById("placeholder");//查找placeholder元素及诶8I节点
	placeholder.setAttribute("src",source);//设置placeholder的src属性值为
	var description=document.getElementById("description");//获取元素p
	var text=element.getAttribute("title");
	description.firstChild.nodeValue=text;
}

可以看到我们仍然是使用事件处理函数onclick内嵌在HTML内部,为了提高网页的可访问性和可用性,现在考虑如下问题:平稳退化,向后兼容,分离JavaScript,同时也考虑一些优化,键盘访问属性,结合CSS等等,这对今后的网页优化有十分重要的启发意义.

1.平稳退化

可以看到,当JavaScript被禁用,我们仍然可以沿着链接前进,访问我们想要的图片。但是功能似乎打了点折扣,用户必须点击浏览器中的后退才能回到主页面,这总比没有访问强:
图片库改进版

2.分离JavaScript和HTML

(1)设置挂钩(建立关联)

分离JavaScript方法和前面一样,在HTML内部设置 “挂钩” 将JavaScript代码与HTML关联起来。那么如何设置这样的挂钩呢?可以给每一个超链接设置一个title,通过title找到这条超连接,但是这不是最佳方法,因为给每一个超链接设置title十分繁琐。更可行的是给整个ul无序列表设置一个id:


<body>
	<h1>Photo Gallery</h1>
	<ul titl="photoGallery">
		<li><a href="images/1.png" onclick="showPic(this);return false;" title="基普乔格1">基普乔格1</a></li>
		<li><a href="images/2.png" onclick="showPic(this);return false;" title="基普乔格2">基普乔格2</a></li>
		<li><a href="images/3.png" onclick="showPic(this);return false;" title="基普乔格3">基普乔格3</a></li>
		<li><a href="images/4.png" onclick="showPic(this);return false;" title="贝克勒1">贝克勒1</a></li>
		<li><a href="images/5.png" onclick="showPic(this);return false;" title="贝克勒2">贝克勒2</a></li>
		<li><a href="images/6.png" onclick="showPic(this);return false;" title="贝克勒3">贝克勒3</a></li>
	</ul>
	<div id="box">
		<img id="placeholder" src="images/7.png" height="300" width="400" alt="my image gallery"/>
		<p id="description">Choose a image</p>
	</div>
</body>
</html>

(2)添加事件处理函数:

现在我们需要设置一个函数,将有关操作关联到onclick上,命名为prepareGallery.这个函数配合showPic使用,但是仍然要完成如下功能:

  • 检查当前浏览器是否支持getElementsByTagName
  • 检查当前浏览器是否支持getElementById
  • 检查当前网页是否存在photoGallery的元素节点
  • 历遍photoGallery的子节点
  • 设置onclick事件,让它在有关链接被点击时把这个参数作为参数传递给showPic函数,取消函数的默认行为阻止网页跳转:
function showPic(element){
	var source=element.getAttribute("href");//获取元素节点的src属性值
	var placeholder=document.getElementById("placeholder");//查找placeholder元素节点
	placeholder.setAttribute("src",source);//设置placeholder的src属性值为
	var description=document.getElementById("description");//获取元素p
	var text=element.getAttribute("title");
	description.firstChild.nodeValue=text;
}
function prepareGallery()
{
	if(!document.getElementsByTageName) return false;//检查当前浏览器是否支持getElementsByTagName
	if(!document.getElementById) return false;//检查当前浏览器是否支持getElementById
	if(!document.getElementById("photoGallery")) return false;//检查当前网页是否存在photoGallery的元素节点
	var gallery=document.getElementById("photoGallery");//获取photoGallery元素节点
	var links=gallery.getElementsByTagName("a");//获取元素节点的子节点数组
	for(var i=0;i<links.length;i++)
	{
		links[i].onclick=function()//将onclick绑定在匿名函数上
		{
			showPic(links[i]);//调用showPic函数
			return false;//返回false,阻止网页跳转
		}
	}
}

(3)共享onload事件

设置好onclick事件处理函数后,问题还没有解决,因为无法保证JavaScript加载时HTML的DOM是否完整,这个时候设置onload函数:
当有多个函数在HTML架子啊完毕后需要调用,我们可以如下2种设置方法:

  • 方法1 绑定到匿名函数:
    将onload事件共享到所有要调用的函数中,用一个匿名函数function绑定:
window.onload=function()
{
	firstFunction();
	secondFunction();
	........
}
  • 方法2 addLoadEvent(func)
    我们可以构造一个 addLoadEvent函数 来创建一个队列,将要执行的函数添加在末尾:
function addLoadEvent(func)
{
	var oldonload=window.onload;//存入现有onload函数的值
	if(typeof window.onload!='function')//未绑定任何函数
	{
		window.onload=func;//直接添加
	}
	else//否则用匿名函数添加新的函数
	{
		window.onload=function()//匿名函数添加
		{
			oldonload();
			func();
		}
	}
}
addLoadEvent(firstFunction);//调用函数
addLoadEvent(secondFunction);
........

3. 向后兼容

在前面的分离JavaScript中我们检验了方法document.getElementById和getAttribute是否可用,已经处理了向后兼容问题之一。
(1)同样的,我们给showPic函数设置检验

但是仍然存在一个问题,当placeholder或description被删除,我们showPic函数无法正常工作,这个时候我们仍然在prepareGallery内部返回了false,表示未点超链接。这个时候无论用户如何点击,网页都没有响应,因此,我们要返回

function showPic(element){
	if(!document.getElementById("placeholder")) return false;
	var source=element.getAttribute("href");//获取元素节点的src属性值
	var placeholder=document.getElementById("placeholder");//查找placeholder元素节点
	if(placeholder.nodeName!="IMG") return false;//nodeName总是返回大写字母
	placeholder.setAttribute("src",source);//设置placeholder的src属性值为
	if(document.getElementById("description"))
	{
		var description=document.getElementById("description");//获取元素
		var text=element.getAttribute("title")?element.getAttribute("title"):"";
		//查找成功则获取title,否则获取空串,这样不会因为无法访问title而导致图片也无法加载
		if (description.firstChild.nodeType==3) description.firstChild.nodeValue=text;//当节点类型为3的时候,添加
	}
	return true;
}

由于在prepareGallery()函数中已经检验过document.getElementById和getAttribute是否可用,在showPic函数内部无需检验。

(2)这样处理之后,showPic函数即使文档中没有placeholder,description元素都不会翻身任何JavaScript错误,但是却出现一个 新的问题:如果把HTML中的placeholder删除,这个时候网页中无论如何点击链接都没有任何响应。 问题出在prepareGallery函数上,,它认为showPic函数一定会执行成功返回true,仍然而当执行失败的时候,仍然返回false取消onclick的默认行为,这时点击超链接不会访问图片,这意味着网页无法平稳退化
图片库改进版
解决这个问题很简单,我们只需要根据showPic的发那会值设置prepareGallery的返回值就能实现:

links[i].onclick=function()
{
	return !showPic(this);//调用showPic函数
}

这个时候即使如果把HTML中的placeholder删除,网页也能平稳退化了.
图片库改进版

4. 键盘访问

为了达到不用鼠标也能访问的目的,我们考虑用 onkeypress事件处理函数 ,在按下键盘的任意一个键都会触发这个函数.

为了让onkeypress函数和onclick有同样的行为,我们可以简单地给onkeypress设置相同的函数代码:

links[i].onclick=function()
{
	return !showPic(this);//调用showPic函数
}
links[i].onkeypress=function()
{
	return !showPic(this);//调用showPic函数
}

更理性地确保onkeypress模仿onclick的做法:

links[i].onkeypress=links[i].onclick;

但是这里打算不使用onkeypress事件处理函数,为什么?因为onkeypress函数意味着只要按下键盘就会触发,在某些浏览器里甚至包括tab键,这意味着如果绑定在onkeypress的事件处理函数返回的是false,用户永远也无法离开当前链接页面!所以最好哦不使用onkeypress事件处理函数,因为onclick函数已经十分完美!onclick函数也支持对键盘的访问!
所以我们的源码不打算变化:


function addLoadEvent(func)
{
	var oldonload=window.onload;
	if(typeof window.onload!='function')//未被绑定
	{
		window.onload=func;
	}
	else
	{
		window.onload=function()//匿名函数添加
		{
			oldonload();
			func();
		}
	}
}
addLoadEvent(prepareGallery);
function prepareGallery()
{
	if(!document.getElementsByTagName) return false;
	if(!document.getElementById) return false;
	if(!document.getElementById("photoGallery")) return false;
	var gallery=document.getElementById("photoGallery");
	var links=gallery.getElementsByTagName("a");
	for(var i=0;i<links.length;i++)
	{
		links[i].onclick=function()
		{
			return !showPic(this);//调用showPic函数
		}
		links[i].onkeypress=links[i].onclick;
	}                                                         
}
function showPic(element){
	if(!document.getElementById("placeholder")) return false;
	var source=element.getAttribute("href");//获取元素节点的src属性值
	var placeholder=document.getElementById("placeholder");//查找placeholder元素节点
	if(placeholder.nodeName!="IMG") return false;//nodeName总是返回大写字母
	placeholder.setAttribute("src",source);//设置placeholder的src属性值为
	if(document.getElementById("description"))
	{
		var description=document.getElementById("description");//获取元素
		var text=element.getAttribute("title")?element.getAttribute("title"):"";
		//查找成功则获取title,否则获取空串,这样不会因为无法访问title而导致图片也无法加载
		if (description.firstChild.nodeType==3) description.firstChild.nodeValue=text;//当节点类型为3的时候,添加
	}
	return true;
}

5. 优化CSS界面:

在超链接的innerHTMl部分插入图片,这样一来就能通过点击图片链接来访问了,而不是枯燥的文字:

body{
	font-family: "Helvetica","Arial",serif;
	color:#C0C0C0  ;
	background-color:#483D8B;
	margin: 1em 10%;
}
#box{
	width: 400px;
	height: 300px;
	border:1px 	solid #8A2BE2;
	margin: 8em 8px;
}
a{
	color: #c60;
	background-color: transparent;
	font-weight: bold;
	text-decoration:none;
}
ul{
	padding: 0;
}
li{
	float: left;
	padding: 1em;
	list-style-type: none;
	display: inline;
}
img{
	display: block;
	clear: both;
}
p{
	color:#C0C0C0 ;
}

图片库改进版
图片库改进版
最后在这里统一展示我们的代码:
HTML:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Photo Gallery</title>
	<link rel="stylesheet" type="text/css" href="photo gallery.css">
	<script src="photo gallery.js"></script>
</head>
<body>
	<h1>Photo Gallery</h1>
	<ul id="photoGallery">
		<li><a href="images/1.png" title="基普乔格1"><img src="images/1.png" width="55" height="45"></a></li>
		<li><a href="images/2.png" title="基普乔格2"><img src="images/2.png" width="55" height="45"></a></li>
		<li><a href="images/3.png" title="基普乔格3"><img src="images/3.png" width="55" height="45"></a></li>
		<li><a href="images/4.png" title="贝克勒1"><img src="images/4.png" width="55" height="45"></a></li>
		<li><a href="images/5.png" title="贝克勒2"><img src="images/5.png" width="55" height="45"></a></li>
		<li><a href="images/6.png" title="贝克勒3"><img src="images/6.png" width="55" height="45"></a></li>
	</ul>
	<div id="box">
		<img id="placeholder" src="images/7.png" height="300" width="400" alt="my image gallery"/>
		<p id="description">Choose a image</p>
	</div>

</body>
</html>

CSS:

body{
	font-family: "Helvetica","Arial",serif;
	color:#C0C0C0  ;
	background-color:#483D8B;
	margin: 1em 10%;
}
#box{
	width: 400px;
	height: 300px;
	border:1px 	solid #8A2BE2;
	margin: 8em 8px;
}
a{
	color: #c60;
	background-color: transparent;
	font-weight: bold;
	text-decoration:none;
}
ul{
	padding: 0;
}
li{
	float: left;
	padding: 1em;
	list-style-type: none;
	display: inline;
}
img{
	display: block;
	clear: both;
}
p{
	color:#C0C0C0 ;
}

JavaScript:

body{
	font-family: "Helvetica","Arial",serif;
	color:#C0C0C0  ;
	background-color:#483D8B;
	margin: 1em 10%;
}
#box{
	width: 400px;
	height: 300px;
	border:1px 	solid #8A2BE2;
	margin: 8em 8px;
}
a{
	color: #c60;
	background-color: transparent;
	font-weight: bold;
	text-decoration:none;
}
ul{
	padding: 0;
}
li{
	float: left;
	padding: 1em;
	list-style-type: none;
	display: inline;
}
img{
	display: block;
	clear: both;
}
p{
	color:#C0C0C0 ;
}

整个图片库优化完毕,注意优化要注意的几点:
平稳退化,向后兼容,分离JavaScript键盘访问属性,结合CSS 等等,这对今后的网页优化有十分重要的启发意义.

相关标签: Web前端开发框架