代码改变世界

javascript动画系列 —— 切换图片(原生)

2013-04-16 16:35  MoltBoy  阅读(497)  评论(0编辑  收藏  举报

  在代码里详细注解了,这里就不再赘诉了。

(function(window){
    var m$ = function(){
        function getId(id){
            return document.getElementById(id);
        }
        function getTag(tag){
            return document.getElementsByTagName(tag);
        }
        function extend(des, src){            
            for(var p in src){        //traverse customized configuration by user
                des[p] = src[p];
            }
            return des;
        }
        function each(arr, callback, thisp){        //traverse array
            if(arr.forEach){            //check Array function 
                arr.forEach(callback, thisp);
            }else{
                for(var i=0, len=arr.length; i < len; ++i){
                    callback.call(thisp, arr[i], i, arr);
                }
            }
        }
        function curStyle(ele, style){        //get style, onlyread
            return ele.currentStyle || window.getComputedStyle(ele, null);
        }

        var tween = {        //return sliding distance/per
            quart: {
                easeOut: function(t, b, c, d){        //t:time(the count of slide), b:begin, c:change(the distance in this slide), d:duration(total times/per)
                    return -c * ((t=t/d-1)*t*t*t - 1) + b;
                }
            },
            back: {            //back effects
                easeOut: function(t, b, c, d, s){
                    s == undefined && (s = 1.70158);
                    return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
                }
            },
            bounce: {            //Rebound effects
                easeOut: function(t, b, c, d){
                    return (t/=d) < (1/2.75) ? c*(7.5625*t*t) + b :
                        (t < (2/2.75)) ? c*(7.5625*(t-=(1.5/2.75))*t + .75) + b : 
                        (t < (2.5/2.75)) ? c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b : c*(7.5625*(t-=(2.25/2.75))*t + .984375) + b;        
                }
            }
        }

        var defaultConfig = {
            trigger: 1,     //the type of trigger
            auto: true,
            tween: tween.quart.easeOut,        //default tween style
            time: 10,        //slide delay
            duration: 50,        //switch time
            pause: 5000,        //auto interval time
            start: function(){},    //switch execute function in the beginning
            end: function(){}        //switch execute function in the end
        };

        function scrollFn(cid, sid, count, config){        //cid: container id, sid: scroller id
            var self = this;
            if(!(self instanceof scrollFn)){
                  return new scrollFn(cid, sid, count, config);    //instantiation
            }
            self.container = getId(cid);
            self.scroller = getId(sid);
            if (!(self.container || self.scroller)) {     //checking to see whether container and scroller exists
                   return;
               } 

            self.config = extend(defaultConfig, config || {});    //replace the part of configs what alter by user
            self.index = 0;
            self.timer = null;        //setTimeout ID
            self.count = count;        //the number of images
            self.step = self.scroller.offsetWidth / count;        //On average, the width of each image
        };

        scrollFn.prototype = {
            constructor: scrollFn,

            transform: function(index){            //transform
                var self = this;
                index == undefined && (index = self.index);  //if the index is undefined, the default for the current index
                index < 0 && (index = self.count - 1) || index >= self.count && (index = 0);
                self.time = 0;
                self.target = -Math.abs(self.step) * (self.index = index);        //slide the target location
                self.begin = parseInt(curStyle(self.scroller)['left']);        //starting position
                self.change = self.target - self.begin;        //slide distance
                self.duration = self.config.duration;    
                self.start();
                self.run();
            },

            run: function(){
                var self = this;
                clearTimeout(self.timer);
                if(self.change && self.time < self.duration){
                    self.moveTo(Math.round(self.config.tween(self.time++, self.begin, self.change, self.duration)));
                    self.timer = setTimeout(function(){self.run()}, self.config.time);
                }else{
                    self.moveTo(self.target);
                    self.config.auto && (self.timer = setTimeout(function(){self.next()}, self.config.pause));    //auto play, call the function: next()
                }
            },

            moveTo: function(i){
                this.scroller.style.left = i + 'px';        //Relative to the containing block
            },

            next: function(){
                this.transform(++this.index);
            }
        };

        return{
            scroll: function(cid, sid, count, config){
                window.onload = function(){
                    var frag = document.createDocumentFragment(),
                        nums = [];
                    for(var i = 0; i < count; i++){        //insert the index of images
                        var li = document.createElement('li');
                        (nums[i] = frag.appendChild(document.createElement('li'))).innerHTML = i + 1;
                    }
                    getId('indexLists').appendChild(frag);        //use fragment, avoid multiple insert

                    var st = scrollFn(cid, sid, count, config);

                    each(nums, function(o, i){        //traverse images and callback   (o: array element, i: the index of array element)
                        o[st.config.trigger == 1 ? 'onclick' : 'onmouseover'] = function(){        //the trigger of mouseover event 
                            o.className = 'on';        //add the className for the target index
                            st.transform(i);
                        }
                        o.onmouseout = function(){
                            o.className = '';        //remove the className
                            st.transform();
                        }
                    });

                    st.start = function(){        //defined start(), handle show the index of selected
                        each(nums, function(o, i){
                            o.className = st.index == i ? 'on' : ''; //add the className for the current index
                        });
                    };
                    st.transform();
                }
            }
        }
    }();

    // Expose jsMolt to the global object
    window.jsMolt = window.m$ = jsMolt = m$;
})(window);

//m$.scroll('c_container' /*外部容器ID*/, 'scroller'/*滑动容器ID*/, 5/*切换图片数目*/, {trigger: 0} /*默认配置*/);

注明:代码原创:BlueDream