使用JavaScript制作图库(gallery)

前端技术 everyinch 1934℃ 0评论

本文使用动态的、分离式的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的效果如下图:
js_gallery1
分离式的加载
这个图库采用分离式脚本编程来制作,这样就不必为需要加入一些诱人的效果而在页面上增加多余的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="">&laquo; Prev</a></div>
     *     <div id="gallery_next"><a href="">Next &raquo;</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="">&laquo; Prev</a></div>' +
        '<div id="gallery_next"><a href="">Next &raquo;</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结合在一起,显示半透明的覆盖层的效果如下图:
gallery_overlay
图库定位
图库还需要制作一个容器,它会浮动在半透明的覆盖层之上。如果正确支持CSS的话,只需要使用固定定位(fixed position),这样就可以定位在任何元素之上,脱离页面滚动的影响。但由于像IE6这样的浏览器对CSS2的支持不够,导致不能轻易地采用这种方法。在开始之前首先在页面中已经有了如下的DOM结构:

<div id="gallery">
     <div id="gallery_image"></div>
     <div id="gallery_prev"><a href="">&laquo; Prev</a></div>
     <div id="gallery_next"><a href="">Next &raquo;</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结合之后能够显示图片的效果如下图所示:
gallery_showImage
在图库中导航
接下来要关注如何让用户方便地导航图库中的图片。在创建图库的容器标签中,已经添加了用以导航的链接,使用这些链接就可以让用户在图库中导航。在图库中执行导航任务的两个函数:

// 查找和显示上一张图片
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;
}

实现了图库中图片的导航之后的效果如下图所示:
gallery_navi
幻灯片(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 = "&raquo; 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;
}

这样就完成了幻灯片的制作,幻灯片的效果如下图:
gallery_slidershow



转载请注明:陈童的博客 » 使用JavaScript制作图库(gallery)

喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

无觅相关文章插件,快速提升流量