纳金网

标题: JS按钮滑动切换内容(二) [打印本页]

作者: 奇    时间: 2011-12-30 18:57
标题: JS按钮滑动切换内容(二)
function getId(id) {

    return "string" == typeof id ? document.getElementById(id) : id;

}

function classCreate() {

    return function() {

        this.init.apply(this, arguments);

    }

}

function extend(defaults, curSettings) {

    for(var k in curSettings) {

        defaults[k] = curSettings[k];

    }

    return defaults;

}

function getElementsByClassName(_className, tag, parent){

    //parent这个参数没有的话,parent就为document

    parent = parent || document;

    tag = tag || '*';

    var allTags = (tag == '*' && parent.all) ? parent.all : parent.getElementsByTagName(tag);

    var matchingElements = new Array();

    //在正则对象中转义,

    _className = _className.replace(/-/g, '-');

    var regex = new RegExp('(^|s)' + _className + '(s|$)');

    var element;

    for(var i = 0; i < allTags.length; i++){

        element = allTags;

        if(regex.test(element.className)){

            matchingElements.push(element);

        }

    }

    return matchingElements;

}
  用new classCreate()可以实例化一个对象,用extend()可扩展参数,用getElementsByClassName()可获取类名。
  获取切换数量
  只需计数出有几个box_content即可
this.everyBoxArr = getElementsByClassName(this.everyBoxClass, '', this.slider);

this._count = this.everyBoxArr.length; //切换数量
  有了切换的数量,就可以采用createElement方法动态的向每个切换按钮(本文中圆点按钮)的容器every_btn_c添加按钮元素。
  设置按钮样式
  按钮的样式是通过类名来获得时,包括每个切换按钮与前后切换按钮。索引为第一个时,每个切换按钮中的第一个与前一个切换按钮是禁用状态,索引为最后一个时类似。
//上一个下一个按钮

this.ptBtnArr[0].className = this.index == 0 ? 'prev_btn_disabled' : 'prev_btn';

this.ptBtnArr[1].className = this.index == (this._count - 1) ? 'next_btn_disabled' : 'next_btn';

//每个切换的按钮

for(var i = 0; i < this._count; i++) {

      this.everyBtnArr.className = this.index == i ? 'current_every_btn' : 'every_btn';

}
  让内容滑动
  所有的按钮在被点击时,都需要设置当前的索引,整个程序都是围绕索引展开的,点击的同时递归调用setTimeout方法,不断的改变滑动对象的left值,直到滑动到目标位置才停止。
  目标位置的获取方法:首选用this.distance = parseInt(this.everyBoxArr[0].offsetWidth)得到每个内容滑动的距离,再用this._target = -1 * this.index * this.distance得到。
  滑动参照一种缓动的方法:
getStep: function(now, target) {

    var curStep = (target - now) / this.step;

    if(0 == curStep) { return curStep; }

    if(Math.abs(curStep) < 1) { return (curStep > 0 ? 1 : -1); } //有可能减不到0,是零点几的小数

    return curStep;

  }
  用目标值减去现在值除以一个大于1的数值,不断调用会变得越来越慢,以实现一个简单的缓动。curStep绝对值小于1时,要定义 curStep为1或-1,不然this.getStep(now, this._target)最后一直是一个大于0而小于1的数,无法停止setTimeout,造成资源的占用(当然是在 parseInt((this.slider.style['left'])的前提下,left要保持整数),这是一个值得注意的地方。
  整个滑动程序代码:
var slideContent = new classCreate();



slideContent.prototype = {

    init: function(container, slider, options) {

        var o = extend(this.defaults, options || {});

        this.container = getId(container);

        this.slider = getId(slider);

        this.index = o.index;

        this.delayTime = o.delayTime;

        this.step = o.step;

        this.everyBoxClass = o.everyBoxClass;

        this.everyBoxArr = getElementsByClassName(this.everyBoxClass, '', this.slider);

        this._count = this.everyBoxArr.length; //切换数量

        this.distance = parseInt(this.everyBoxArr[0].offsetWidth); //滑动距离

        this._target = 0; //到达目标

        this._timer = null;//定时器

        

        var ptBtnC = getElementsByClassName(o.ptBtnConClass, 'div', this.container)[0];

        this.ptBtnArr = ptBtnC.getElementsByTagName('span'); //上一个下一个按钮

        var $this = this;

        //上一个按钮按下时

        this.ptBtnArr[0].onclick = function() {

            $this.index--;

            if($this.index < 0) {

                 $this.index = 0;

            } else {

                $this.start();

            }

        }

        //下一个按钮按下时

        this.ptBtnArr[1].onclick = function() {

            $this.index++;

            if($this.index >= $this._count) {

                $this.index = $this._count - 1;

            } else {

                $this.start();

            }

        }

        

        var everyBtnC = getElementsByClassName(o.everyBtnConClass, 'div', this.container)[0];

        this.everyBtnArr = everyBtnC.getElementsByTagName('span'); //每一个按钮

        everyBtnC.innerHTML = ''; //清空所有切换钮

        var btn = '';

        for(var i = 0; i < this._count; i++) {

            btn = document.createElement('span');

            btn.className = this.index == i ? 'current_every_btn' : 'every_btn';

            btn.innerHTML = i;

            everyBtnC.appendChild(btn);

            this.everyBtnClick(btn, i); //绑定事件

        }

        

        this.setBtnStyle(); //设置初始时的按钮样式

        if(0 != this.index) { this.slider.style['left'] = -1 * this.index * this.distance + 'px'; } //索引不为0时设置滑动内容位置

        this.start();

    },

    defaults: {

        index: 0, //当前索引

        delayTime: 10, //滑动延时,

        step: 5, //滑动变化率

        ptBtnConClass: 'pn_btn_c', //上一个,下一个按钮容器

        everyBtnConClass: 'every_btn_c', //每个切换按钮容器

        everyBoxClass: 'box_content' //每一个内容容器

    },

    //设置按钮样式

    setBtnStyle: function() {

        //上一个下一个按钮

        this.ptBtnArr[0].className = this.index == 0 ? 'prev_btn_disabled' : 'prev_btn';

        this.ptBtnArr[1].className = this.index == (this._count - 1) ? 'next_btn_disabled' : 'next_btn';

        //每个切换的按钮

        for(var i = 0; i < this._count; i++) {

            this.everyBtnArr.className = this.index == i ? 'current_every_btn' : 'every_btn';

        }

    },

    //每个切换按钮单击时

    everyBtnClick: function(elem, i) {

        var $this = this;

        elem.onclick = function() {

            $this.index = i;

            $this.start();

        }

    },

    //开始切换

    start: function() {

        if(this.index >= this._count) { this.index = 0; }

        if(this.index < 0) { this.index =  this._count - 1; }

        this._target = -1 * this.index * this.distance;

        this.setBtnStyle();

        this.move();

    },

    //移动

    move: function() {

        clearTimeout(this._timer);

        var $this = this;

        var now = parseInt(this.slider.style['left']) || 0;

        var curStep = this.getStep(now, this._target);

        if(0 != curStep) {

            this.slider.style['left'] = (now + curStep) + 'px';

            this._timer = setTimeout(function() { $this.move(); }, this.delayTime);

        }

    },

    //获取步长,缓动时每次移动的距离

    getStep: function(now, target) {

        var curStep = (target - now) / this.step;

        if(0 == curStep) { return curStep; }

        if(Math.abs(curStep) < 1) { return (curStep > 0 ? 1 : -1); } //有可能减不到0,是零点几的小数

        return curStep;

    }

}
  defaults里定义了一些可选参数,调用方法:new slideContent('zone1', 'slider1');
  此时用IE6(IETester)打开时,我惊讶的发现,按钮被点击时,所有按钮背景都会消失片刻,然后再出现:查看示例。
  这使我想起了以前碰到的一个问题,给a标签一个CSS背景,a:hover换一个背景时IE6下出现了闪烁:查看示例。这两者都是类似的,由于IE6本身是不会缓存CSS背景图片的,触发某些事件时改变了该标签本身的背景图时,IE6会再次请求该图片。知道了原因,只要让IE6缓存背景图片便可以解决这个问题了,我在这里找到了答案:【IE6的疯狂之八】链接伪类(:hover)CSS背景图片有闪动BUG。
<!--[if IE 6]>

<script type="text/javascript">  

document***cCommand('BackgroundImageCache', false, ***e);

</script>

<![endif]-->
  点此查看:最终演示效果。
  点此下载:完整示例文件。
作者: 奇    时间: 2012-1-6 22:17

作者: 晃晃    时间: 2012-4-8 23:27
俺是新人,这厢有礼了!

作者: tc    时间: 2012-5-21 23:24
俺是新人,这厢有礼了!

作者: 菜刀吻电线    时间: 2012-7-22 23:18
先顶上去,偶要高亮加精鸟!

作者: 奇    时间: 2012-8-15 23:45
百度的叫度娘,网易的叫易娘,新浪内部还在为是叫新娘还是浪娘而争论不休!……不管你们是企鹅的额娘,豆瓣的伴娘,还是华为的伪娘,都要记得,淘宝才是你们的亲娘啊!亲!!

作者: C.R.CAN    时间: 2012-10-22 23:33
发了那么多,我都不知道该用哪个给你回帖了,呵呵

作者: 菜刀吻电线    时间: 2012-11-2 23:27
好铁多多发,感激分享

作者: C.R.CAN    时间: 2013-2-26 23:30
有意思!学习了!

作者: 小鱼    时间: 2013-2-28 21:22
路过、路过、快到鸟,列位请继续...ing




欢迎光临 纳金网 (http://rs.narkii.com/club/) Powered by Discuz! X2.5