JS轮播图效果实现

轮播图可以说是一种最常见的网页效果了,很多大大小小的网站上都有,它可以以动态的方式向用户展示产品或者别的什么东西。

现在尝试自己实现一个,功能点大致如下:

1 - 视窗以一定的时间间隔切换图片
2 - 鼠标指针移至导航条上面,停止自动切换图片
3 - 若鼠标指针移至的导航条索引不是当前的图片索引,视窗切换到导航索引对应的图片
4 - 鼠标移开导航条,恢复图片自动切换
5 - 点击图片可以跳转到对应的页面
 
 
页面制作方式,先定义个div作为包装容器,里面分别定义个包含图片的a元素和一个列表,作为导航条。
class设为active是作为当前轮播点的标识,结构如下。
code1
<div>
            <a href='javascript:void(0);'><img id='img' src='images/1.jpg'/></a>
            <ul id='nav-triggers'>
                <li class='active'>1</li><li>2</li><li>3</li><li>4</li><li>5</li>
            </ul>
        </div>
View Code

轮播的实现需要用到js间歇调用。一般不适用setInterval,因为它存在一些问题,例如两次轮询有可能并不是互斥执行的等等。这里适用setTimeout的方式实现,结构如下:

code2

// 定时循环调用
     var interval = 1500;
     var func = function(){
          console.log('time out');
     };
     setTimeout(function(){
          func();
          setTimeout(arguments.callee, interval);
     }, interval);
View Code

定义一个index变量标识当前轮播索引,然后 func 函数体变换一下,就可以实现最简单的轮播

code3

var func = function(){
          if(++index > 5)
               index = 1;
          // _$,根据id获取dom
          _$('img').setAttribute('src', 'images/' + index + '.jpg');
     };
View Code

加上鼠标移入移出导航条的控制

code4

// 定时循环调用
    var interval = 3000,  // 每隔3秒切换一次
        index = 1; // 当前所轮播的索引
        
    // 'nav-triggers'是导航条ul的id
    var navTriggers = _$('nav-triggers');
    var childLis = getChildNodes(navTriggers, 'LI')
    
    var changePic = function(idx){
        var tween = new Tween();
        tween.setup(0.4,1,400);
        var isImgSeted = false;
        tween.move(function(cur){
            _$('img').style.opacity = cur;
            if(!isImgSeted){
                // _$,根据id获取dom
                _$('img').setAttribute('src', 'images/' + idx + '.jpg');
                isImgSeted = true;
            }
        });
        
        addClassName(childLis[idx - 1], 'active');
    };
    
    var func = function(){
        removeClassName(childLis[index - 1], 'active');
        if(++index > 5)
            index = 1;
        changePic(index);
    };
    
    var timeoutObj = setTimeout(function(){
        func();
        timeoutObj = setTimeout(arguments.callee, interval);
    }, interval);
    
    var isCleared = false;
    navTriggers.addEventListener('mouseover', function(e){
        var target = e.target || e.srcElement;
        if(target.tagName !== 'LI') return;
        for(var i=0, len=childLis.length; i<len; i++){
            if(target === childLis[i])
                break;
        }
        clearTimeout(timeoutObj);
        isCleared = true;
        if(i == index-1) return;
        removeClassName(childLis[index - 1], 'active');
        index = i+1;
        changePic(index);
    });
    
    navTriggers.addEventListener('mouseout', function(e){
        if(!isCleared) return;
        isCleared = false;
        timeoutObj = setTimeout(function(){
            func();
            timeoutObj = setTimeout(arguments.callee, interval);
        }, interval);
    });
View Code

要点1:

图片轮播的控制点用index变量控制。当图片要切换时,先清除掉index(变换前的)对应的列表项(li)的active class。

然后变换index,自增1或者用户选了导航条后,取导航条的当前值。

最后通过index执行图片变换逻辑changePic。

由于这三个逻辑总是要绑在一起操作的,因此封装成函数可能是更好的方式。同时index的变换方式是不确定的,这或许可以通过传入一个返回目标index的函数来解决。当然,现在没有这么做。

要点2:

getChildNodes函数是获取指定元素的指定标签名对应的所有子节点,以数组的形式返回。之所以定义它,是因为在实际测试时发现ul的子节点并不全是li,在开头和最后居然是一个text节点,内容是回车符号(我勒个去,这都可以),这应该是编写html的方式所导致的了。应该可以通过修改html代码解决这个问题,但因为它太充满不确定性了,所以还是写个函数保险点。

function getChildNodes(element, tag){
    var childNodeArr = [];
    for(var i=0, len=element.childNodes.length; i<len; i++){
        if(tag === element.childNodes[i].tagName)
            childNodeArr.push(element.childNodes[i]);
    }
    return childNodeArr;
}
View Code

 要点3:关于一些判断

在ul的鼠标移入事件增加了目标是否为li的判断。这是因为目标有可能是ul本身。isCleared标识由鼠标移入和移出公用。鼠标移入时清空了间歇调用后,isCleared才设为true,鼠标移出时,只有isCleared为true,才重新设置间歇调用。

完整代码请参阅附件

posted on 2013-05-26 11:25  寻找亮光  阅读(1075)  评论(1编辑  收藏  举报