本文使用动态的、分离式的JavaScript来制作自己的图库。每个页面可以包含多个图库,每个图库也可以包含多个图片。当然最重要的是,即时禁止了JavaScript,也要让图片以语义的和可理解的方式显示出来。
用以制作图库的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>
然后,为了更加美观和可导航,需要增加一些样式:
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; }
最后,基本的HTML和CSS的效果如下图:
分离式的加载
这个图库采用分离式脚本编程来制作,这样就不必为需要加入一些诱人的效果而在页面上增加多余的HTML。现在要做的就是在页面完成加载后注入必要的HTML元素。
// 当前图片 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] ); } };
半透明的覆盖层
如同lightbox和ThickBox那样,我们的图库同样需要一个半透明的覆盖层,并且让这个半透明的覆盖层符合当前页面的宽度和高度,最后这个任务可以使用之前写的pageWidth和pageHeight函数来完成。
创建一个简单的div元素并插入到DOM中
// 创建半透明的背景 var overlay = document.createElement("div"); overlay.id = "overlay"; // 点击背景则隐藏它 overlay.onclick = hideOverlay; //将它加入到文档中 document.body.appendChild( overlay );
接下来,开发两个函数来隐藏和显示覆盖层,并使用pageWidth和pageHeight函数使覆盖层与当前页面保持一致的宽度和高度。
隐藏和显示半透明覆盖层的函数:
// 隐藏半透明背景 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 ); }
加上必要的CSS以正确地显示半透明那个覆盖层:
#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; }
到这里和之前的HTML和CSS结合在一起,显示半透明的覆盖层的效果如下图:
图库定位
图库还需要制作一个容器,它会浮动在半透明的覆盖层之上。如果正确支持CSS的话,只需要使用固定定位(fixed position),这样就可以定位在任何元素之上,脱离页面滚动的影响。但由于像IE6这样的浏览器对CSS2的支持不够,导致不能轻易地采用这种方法。在开始之前首先在页面中已经有了如下的DOM结构:
<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>
有了这个基本的HTML结构,还需要一个合适的函数来显示图库的div,并把图片放到这个div中去。显示图库的当前图片的函数:
// 显示当前的图片 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(); }
在showImage函数的最后调用了adjust函数,adjust函数负责把图片定位到用户窗口的绝对中心。
// 重定位图库到页面的中心 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;
最后,还需要一个保证图库能够正确定位的CSS,注意到,这只不过是一个绝对定位的div,且它的z-index比较大,所以能够显示在所有元素之上:
#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; }
CSS、HTML和JavaScript结合之后能够显示图片的效果如下图所示:
在图库中导航
接下来要关注如何让用户方便地导航图库中的图片。在创建图库的容器标签中,已经添加了用以导航的链接,使用这些链接就可以让用户在图库中导航。在图库中执行导航任务的两个函数:
// 查找和显示上一张图片 function prevImage() { showImage( prev( curImage ) ); // 阻止链接的默认行为 return false; } // 查找和显示下一张图片 function nextImage() { showImage( next( curImage ) ); // 阻止链接的默认行为 return false; }
下面是检查何时隐藏或显示下一张和上一张的导航链接:
// 如果是最后一张则隐藏下一张的链接 if ( !next(cur) ) hide( id("gallery_next") ); // 否则,显示下一张的链接 else show( id("gallery_next") ); // 如果是第一张那么隐藏上一张的链接 if ( !prev(cur) ) hide( id("gallery_prev") ); // 否则,显示上一张的链接 else show( id("gallery_prev") );
定位导航链接的CSS:
#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; }
实现了图库中图片的导航之后的效果如下图所示:
幻灯片(Slider)
创建幻灯片的步骤可以分解为两步:
1. 在文档内建立一个额外的链接,点击后开始播放幻灯片
2. 播放幻灯片的过程,控制显示哪张图片和何时切换图片
初始化幻灯片的函数:
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 ); }
现在需要控制幻灯片的播放:
// 开始幻灯片 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(); }
最后还有一些必要的CSS:
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; }
转载请注明:陈童的博客 » 使用JavaScript制作图库(gallery)