使用JavaScript制作图库(gallery)
本文使用动态的、分离式的JavaScript来制作自己的图库。每个页面可以包含多个图库,每个图库也可以包含多个图片。当然最重要的是,即时禁止了JavaScript,也要让图片以语义的和可理解的方式显示出来。用以制作图库的HTML代码如下:
[code lang="html"]
<html>
<head>
<title>Random Cat Pictures</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="06-gallery.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1>陈童的博客</h1>
<p>try to grasp every inch of web</p>
<ul class="gallery" title="">
<li><a href="images/navi1.jpg"><img src="images/navi1.jpg" alt="contents navigation"/></a></li>
<li><a href="images/navi2.jpg"><img src="images/navi2.jpg" alt="luding labs"/></a></li>
<li><a href="images/navi3.jpg"><img src="images/navi3.jpg" alt="away3d shadow"/></a></li>
<li><a href="images/navi4.jpg"><img src="images/navi4.jpg" alt="particle shape"/></a></li>
<li><a href="images/navi5.jpg"><img src="images/navi5.jpg" alt="webcamera fire"/></a></li>
</ul>
<p>Copyright © 2013. 陈童的博客</p>
</body>
</html>
[/code]
然后,为了更加美观和可导航,需要增加一些样式:
[code lang="html"]
body {
font-family: Arial;
font-siz: 14px;
}
/* 在图库外增加一个外框 */
ul.gallery {
list-style: none;
padding: 5px;
background: #EEE;
overflow: auto;
border: 1px solid #AAA;
margin-top: 0px;
}
/* 在每个图片四周增加一个边框 */
ul.gallery li {
float: left;
margin: 6px;
width: 110px;
height: 110px;
background: #FFF;
border: 2px solid #AAA;
}
/* 横版图像有100像素宽 */
ul.gallery img {
width: 100px;
margin: 5px;
border: 0px;
margin-top: 17px;
}
/* 竖版图像有100像素高 */
ul.gallery li.tall img {
height: 100px;
width: auto;
margin-top: 5px;
margin-left: 17px;
}
[/code]
最后,基本的HTML和CSS的效果如下图:
<img src="http://www.everyinch.net/wp-content/uploads/2013/12/js_gallery1-620x260.jpg" alt="js_gallery1" width="620" height="260" class="alignnone size-medium wp-image-4072" />
分离式的加载
这个图库采用分离式脚本编程来制作,这样就不必为需要加入一些诱人的效果而在页面上增加多余的HTML。现在要做的就是在页面完成加载后注入必要的HTML元素。
[code lang="js"]
// 当前图片
var curImage = null;
// 等待DOM加载完成
window.onload = function() {
/*
* 创建如下的DOM结构:
* <div id="overlay"></div>
* <div id="gallery">
* <div id="gallery_image"></div>
* <div id="gallery_prev"><a href="">« Prev</a></div>
* <div id="gallery_next"><a href="">Next »</a></div>
* <div id="gallery_title"></div>
* </div>
*/
// 创建图库的容器标签
var gallery = document.createElement("div");
gallery.id = "gallery";
gallery.innerHTML = '<div id="gallery_image"></div>' +
'<div id="gallery_prev"><a href="">« Prev</a></div>' +
'<div id="gallery_next"><a href="">Next »</a></div>' +
'<div id="gallery_title"></div>';
// 将DOM结构插入文档
document.body.appendChild( gallery );
// 上一张和下一张的监听事件
id("gallery_next").onclick = nextImage;
id("gallery_prev").onclick = prevImage;
// 定位所有的图库
var g = byClass( "gallery", "ul" );
// 遍历图库
for ( var i = 0; i < g.length; i++ ) {
// 每个图库中的所有链接
var link = tag( "a", g[i] );
// 遍历每个图片链接
for ( var j = 0; j < link.length; j++ ) {
// 点击图片显示图库
link[j].onclick = function(){
// 显示半透明背景
showOverlay();
// 显示图片
showImage( this.parentNode );
// 取消链接的默认行为
return false;
};
}
// 加入幻灯导航
addSlideShow( g[i] );
}
};
[/code]
半透明的覆盖层
如同lightbox和ThickBox那样,我们的图库同样需要一个半透明的覆盖层,并且让这个半透明的覆盖层符合当前页面的宽度和高度,最后这个任务可以使用之前写的pageWidth和pageHeight函数来完成。
创建一个简单的div元素并插入到DOM中
[code lang="js"]
// 创建半透明的背景
var overlay = document.createElement("div");
overlay.id = "overlay";
// 点击背景则隐藏它
overlay.onclick = hideOverlay;
//将它加入到文档中
document.body.appendChild( overlay );
[/code]
接下来,开发两个函数来隐藏和显示覆盖层,并使用pageWidth和pageHeight函数使覆盖层与当前页面保持一致的宽度和高度。
隐藏和显示半透明覆盖层的函数:
[code lang="js"]
// 隐藏半透明背景
function hideOverlay() {
// 重置当前图片的引用
curImage = null;
// 隐藏半透明背景和图库
hide( id("overlay") );
hide( id("gallery") );
}
// 显示半透明背景
function showOverlay() {
// 查找半透明背景
var over = id("overlay");
// 确保它的宽高和页面宽高一致
over.style.height = pageHeight() + "px";
over.style.width = pageWidth() + "px";
// 淡入
fadeIn( over, 50, 10 );
}
[/code]
加上必要的CSS以正确地显示半透明那个覆盖层:
[code lang="html"]
#overlay {
background: #000;
opacity: 0.5;
display: none;
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 100;
cursor: pointer;
cursor: hand;
}
[/code]
到这里和之前的HTML和CSS结合在一起,显示半透明的覆盖层的效果如下图:
<img src="http://www.everyinch.net/wp-content/uploads/2013/12/gallery_overlay-620x202.jpg" alt="gallery_overlay" width="620" height="202" class="alignnone size-medium wp-image-4085" />
图库定位
图库还需要制作一个容器,它会浮动在半透明的覆盖层之上。如果正确支持CSS的话,只需要使用固定定位(fixed position),这样就可以定位在任何元素之上,脱离页面滚动的影响。但由于像IE6这样的浏览器对CSS2的支持不够,导致不能轻易地采用这种方法。在开始之前首先在页面中已经有了如下的DOM结构:
[code lang="html"]
<div id="gallery">
<div id="gallery_image"></div>
<div id="gallery_prev"><a href="">« Prev</a></div>
<div id="gallery_next"><a href="">Next »</a></div>
<div id="gallery_title"></div>
</div>
[/code]
有了这个基本的HTML结构,还需要一个合适的函数来显示图库的div,并把图片放到这个div中去。显示图库的当前图片的函数:
[code lang="js"]
// 显示当前的图片
function showImage(cur) {
// 当前处理的图片
curImage = cur;
// 获取图库图片
var img = id("gallery_image");
// 如果存在则删除当前图片
if ( img.firstChild )
img.removeChild( img.firstChild );
// 加入图片
img.appendChild( cur.firstChild.cloneNode( true ) );
// 使用image标签的alt文本来定义图库中图片的标题
id("gallery_title").innerHTML = cur.firstChild.firstChild.alt;
// 定位图库
var gallery = id("gallery");
// 设置class,以保证正确的尺寸
gallery.className = cur.className;
// 淡入
fadeIn( gallery, 100, 10 );
// 保证图片的位置正确
adjust();
}
[/code]
在showImage函数的最后调用了adjust函数,adjust函数负责把图片定位到用户窗口的绝对中心。
[code lang="js"]
// 重定位图库到页面的中心
function adjust(){
// 图库的引用
var obj = id("gallery");
// 确保图库存在
if ( !obj ) return;
// 获得当前的宽度和高度
var w = getWidth( obj );
var h = getHeight( obj );
// 使它垂直居中
var t = scrollY() + ( windowHeight() / 2 ) - ( h / 2 );
// 确保不超过页面的顶端
if ( t < 0 ) t = 0;
// 使它水平居中
var l = scrollX() + ( windowWidth() / 2 ) - ( w / 2 );
// 确保不超过页面的左端
if ( l < 0 ) l = 0;
// 设置经过调整后的位置
setY( obj, t );
setX( obj, l );
};
// 当用户滚动窗口或者缩放窗口的时候,调整图库的位置
window.onresize = document.onscroll = adjust;
[/code]
最后,还需要一个保证图库能够正确定位的CSS,注意到,这只不过是一个绝对定位的div,且它的z-index比较大,所以能够显示在所有元素之上:
[code lang="js"]
#gallery {
position: absolute;
width: 650px;
height: 510px;
background: #FFF;
z-index: 110;
display: none;
}
#gallery_title {
position: absolute;
bottom: 5px;
left: 5px;
width: 100%;
font-size: 16px;
text-align: center;
}
#gallery img {
position: absolute;
top: 5px;
left: 5px;
width: 640px;
height: 480px;
border: 0px;
z-index: 115;
}
#gallery.tall {
width: 430px;
height: 590px;
}
#gallery.tall img {
width: 420px;
height: 560px;
}
[/code]
CSS、HTML和JavaScript结合之后能够显示图片的效果如下图所示:
<img src="http://www.everyinch.net/wp-content/uploads/2013/12/gallery_showImage-620x386.jpg" alt="gallery_showImage" width="620" height="386" class="alignnone size-medium wp-image-4086" />
在图库中导航
接下来要关注如何让用户方便地导航图库中的图片。在创建图库的容器标签中,已经添加了用以导航的链接,使用这些链接就可以让用户在图库中导航。在图库中执行导航任务的两个函数:
[code lang="js"]
// 查找和显示上一张图片
function prevImage() {
showImage( prev( curImage ) );
// 阻止链接的默认行为
return false;
}
// 查找和显示下一张图片
function nextImage() {
showImage( next( curImage ) );
// 阻止链接的默认行为
return false;
}
[/code]
下面是检查何时隐藏或显示下一张和上一张的导航链接:
[code lang="js"]
// 如果是最后一张则隐藏下一张的链接
if ( !next(cur) )
hide( id("gallery_next") );
// 否则,显示下一张的链接
else
show( id("gallery_next") );
// 如果是第一张那么隐藏上一张的链接
if ( !prev(cur) )
hide( id("gallery_prev") );
// 否则,显示上一张的链接
else
show( id("gallery_prev") );
[/code]
定位导航链接的CSS:
[code lang="html"]
#gallery_prev, #gallery_next {
position: absolute;
bottom: 0px;
right: 0px;
z-index: 120;
width: 60px;
text-align: center;
font-size: 12px;
padding: 4px;
}
#gallery_prev {
left: 0px;
}
#gallery_prev a, #gallery_next a {
color: #000;
text-decoration: none;
}
[/code]
实现了图库中图片的导航之后的效果如下图所示:
<img src="http://www.everyinch.net/wp-content/uploads/2013/12/gallery_navi-620x415.jpg" alt="gallery_navi" width="620" height="415" class="alignnone size-medium wp-image-4087" />
幻灯片(Slider)
创建幻灯片的步骤可以分解为两步:
1. 在文档内建立一个额外的链接,点击后开始播放幻灯片
2. 播放幻灯片的过程,控制显示哪张图片和何时切换图片
初始化幻灯片的函数:
[code lang="js"]
function addSlideshow( elem ) {
// 创建幻灯片的容器
var div = document.createElement("div");
div.className = "slideshow";
// 显示幻灯片的名字,使用的是图库的 title
var span = document.createElement("span");
span.innerHTML = g[i].title;
div.appendChild( span );
// 创建链接
var a = document.createElement("a");
a.href = "";
a.innerHTML = "» View as a Slideshow";
// 点击后开始播放幻灯片
a.onclick = function(){
startShow( this.parentNode.nextSibling );
return false;
};
// 为页面插入新的导航和容器
div.appendChild( a );
elem.parentNode.insertBefore( div, elem );
}
[/code]
现在需要控制幻灯片的播放:
[code lang="js"]
// 开始幻灯片
function startShow(obj) {
// 定位到图库的每一张图片
var elem = tag( "li", obj );
// 图库的引用
var gallery = id("gallery");
// 遍历每一个匹配的图库图片
for ( var i = 0; i < elem.length; i++ ) new function() {
// 记录当前图片
var cur = elem[i];
// 每5秒显示一张图片
setTimeout(function(){
// 显示图片
showImage( cur );
// 在3.5秒后淡出
setTimeout(function(){
fadeOut( gallery, 0, 10 );
}, 3500 );
}, i * 5000 );
};
// 在结束后隐藏全部
setTimeout( hideOverlay, 5000 * elem.length );
// 幻灯片刚开始播放,显示覆盖层
showOverlay();
}
[/code]
最后还有一些必要的CSS:
[code lang="html"]
div.slideshow {
text-align: right;
padding: 4px;
margin-top: 10px;
position: relative;
}
div.slideshow span {
position: absolute;
bottom: 3px;
left: 0px;
font-size: 18px;
font-weight: bold;
}
div.slideshow a {
color: #000;
}
[/code]
这样就完成了幻灯片的制作,幻灯片的效果如下图:
<img src="http://www.everyinch.net/wp-content/uploads/2013/12/gallery_slidershow-620x405.jpg" alt="gallery_slidershow" width="620" height="405" class="alignnone size-medium wp-image-4084" />
查看完整版本: 使用JavaScript制作图库(gallery)
Tags: