图片库改进版

上一篇博客中已经设计了一个简易的图片库,可以实现把整个图片库的浏览链接集中放在图片库主页里,只在用户点击了这个主页的链接时才把相应的链接发送给他,在点击链接后将网页中的图片替换,而不是网页跳转,点击链接伴随着图片下方文字的替换:
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 等等,这对今后的网页优化有十分重要的启发意义.

发布了107 篇原创文章 · 获赞 86 · 访问量 8657

猜你喜欢

转载自blog.csdn.net/weixin_44307065/article/details/104039149