| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740 | /* * TouchSlider * @author qiqiboy * @github https://github.com/qiqiboy/touchslider */;(function(ROOT, struct, undefined){    "use strict";    var VERSION='2.0.1';    var lastTime=0,        nextFrame=ROOT.requestAnimationFrame            ||                ROOT.webkitRequestAnimationFrame        ||                ROOT.mozRequestAnimationFrame           ||                ROOT.msRequestAnimationFrame            ||                function(callback){                    var currTime=+new Date,                        delay=Math.max(1000/60,1000/60-(currTime-lastTime));                    lastTime=currTime+delay;                    return setTimeout(callback,delay);                },        cancelFrame=ROOT.cancelAnimationFrame           ||                ROOT.webkitCancelAnimationFrame         ||                ROOT.webkitCancelRequestAnimationFrame  ||                ROOT.mozCancelRequestAnimationFrame     ||                ROOT.msCancelRequestAnimationFrame      ||                clearTimeout,        DOC=ROOT.document,        divstyle=DOC.createElement('div').style,        cssVendor=function(){            var tests="-webkit- -moz- -o- -ms-".split(" "),                prop;            while(prop=tests.shift()){                if(camelCase(prop+'transform') in divstyle){                    return prop;                }            }            return '';        }(),        transition=cssTest('transition'),        toString=Object.prototype.toString,        slice=[].slice,        class2type={},        event2type={},        event2code={            click:4,            mousewheel:5,            dommousescroll:5,            keydown:6,            resize:7        },        POINTERTYPES={            2:'touch',            3:'pen',            4:'mouse',            pen:'pen'        },        STARTEVENT=[],        MOVEEVENT=[],        EVENT=function(){            var ret={},                states={                    start:1,                    down:1,                    move:2,                    end:3,                    up:3,                    cancel:3                };            each("mouse touch pointer MSPointer-".split(" "),function(prefix){                var _prefix=/pointer/i.test(prefix)?'pointer':prefix;                ret[_prefix]=ret[_prefix]||{};                POINTERTYPES[_prefix]=_prefix;                each(states,function(endfix,code){                    var ev=camelCase(prefix+endfix);                    ret[_prefix][ev]=code;                    event2type[ev.toLowerCase()]=_prefix;                    event2code[ev.toLowerCase()]=code;                    if(code==1){                        STARTEVENT.push(ev);                    }else{                        MOVEEVENT.push(ev);                    }                });            });            each("otransitionend oTransitionEnd webkitTransitionEnd mozTransitionEnd MSTransitionEnd transitionend".split(" "),function(ev){                STARTEVENT.push(ev);                event2code[ev.toLowerCase()]=8;            });            return ret;        }(),        POINTERS={            touch:{},            pointer:{},            mouse:{}        };    each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(name){        class2type["[object "+name+"]"]=name.toLowerCase();    });    function type(obj){        if(obj==null){            return obj+"";        }                return typeof obj=='object'||typeof obj=='function' ? class2type[toString.call(obj)]||"object" :            typeof obj;    }	    function isArrayLike(elem){        var tp=type(elem);        return !!elem && tp!='function' && tp!='string' && (elem.length===0 || elem.length && (elem.nodeType==1 || (elem.length-1) in elem));    }    function camelCase(str){        return (str+'').replace(/^-ms-/, 'ms-').replace(/-([a-z]|[0-9])/ig, function(all, letter){            return (letter+'').toUpperCase();        });    }    function cssTest(name){        var prop=camelCase(name),            _prop=camelCase(cssVendor+prop);        return (prop in divstyle) && prop || (_prop in divstyle) && _prop || '';    }    function isFunction(func){        return type(func)=='function';    }    function pointerLength(obj){        var len=0,key;        if(type(obj.length)=='number'){            len=obj.length;        }else if('keys' in Object){            len=Object.keys(obj).length;        }else{            for(key in obj){                if(obj.hasOwnProperty(key)){                    len++;                }            }        }        return len;    }    function pointerItem(obj,n){        return 'item' in obj?obj.item(n):function(){            var i=0,key;            for(key in this){                if(i++==n){                    return this[key];                }            }        }.call(obj,n);    }        function each(arr, iterate){        if(isArrayLike(arr)){            if(type(arr.forEach)=='function'){                return arr.forEach(iterate);            }            var i=0,len=arr.length,item;            for(;i<len;i++){                item=arr[i];                if(type(item)!='undefined'){                    iterate(item,i,arr);                }            }        }else{            var key;            for(key in arr){                iterate(key,arr[key],arr);            }        }    }    function children(elem){        var ret=[];        each(elem.children||elem.childNodes,function(elem){            if(elem.nodeType==1){                ret.push(elem);            }        });        return ret;    }    function getStyle(elem,prop){        var style=ROOT.getComputedStyle&&ROOT.getComputedStyle(elem,null)||elem.currentStyle||elem.style;        return style[prop];    }    function setStyle(elem,props){        each(props,function(name,value){            var prop;            switch(name){                case 'float':                    prop=cssTest('cssFloat')?'cssFloat':'styleFloat';                    break;                default:                    prop=camelCase(name);            }            try{                elem.style[prop]=value;            }catch(e){}        });    }    function addListener(elem,evstr,handler){        if(type(evstr)=='object'){            return each(evstr,function(evstr,handler){                addListener(elem,evstr,handler);            });        }        each(evstr.split(" "),function(ev){            if(elem.addEventListener){                elem.addEventListener(ev,handler,false);            }else if(elem.attachEvent){                elem.attachEvent('on'+ev,handler);            }else elem['on'+ev]=handler;        });    }    function offListener(elem,evstr,handler){        if(type(evstr)=='object'){            return each(evstr,function(evstr,handler){                offListener(elem,evstr,handler);            });        }        each(evstr.split(" "),function(ev){            if(elem.removeEventListener){                elem.removeEventListener(ev,handler,false);            }else if(elem.detachEvent){                elem.detachEvent('on'+ev,handler);            }else elem['on'+ev]=null;        });    }    function removeRange(){        var range;        if(ROOT.getSelection){            range=getSelection();            if('empty' in range)range.empty();            else if('removeAllRanges' in range)range.removeAllRanges();        }else{            DOC.selection.empty();        }    }    function EASE(t,b,c,d){        return -c * ((t=t/d-1)*t*t*t - 1) + b;    }    function filterEvent(oldEvent){        var ev={},            which=oldEvent.which,            button=oldEvent.button,            pointers,pointer;        each("wheelDelta detail which keyCode".split(" "),function(prop){            ev[prop]=oldEvent[prop];        });        ev.oldEvent=oldEvent;                ev.type=oldEvent.type.toLowerCase();        ev.eventType=event2type[ev.type]||ev.type;        ev.eventCode=event2code[ev.type]||0;        ev.pointerType=POINTERTYPES[oldEvent.pointerType]||oldEvent.pointerType||ev.eventType;        ev.target=oldEvent.target||oldEvent.srcElement||DOC.documentElement;        if(ev.target.nodeType===3){            ev.target=ev.target.parentNode;        }        ev.preventDefault=function(){            oldEvent.preventDefault && oldEvent.preventDefault();            ev.returnValue=oldEvent.returnValue=false;        }        if(pointers=POINTERS[ev.eventType]){            switch(ev.eventType){                case 'mouse':                case 'pointer':                    var id=oldEvent.pointerId||0;                    ev.eventCode==3?delete pointers[id]:pointers[id]=oldEvent;                    break;                case 'touch':                    POINTERS[ev.eventType]=pointers=oldEvent.touches;                    break;            }            if(pointer=pointerItem(pointers,0)){                ev.clientX=pointer.clientX;                ev.clientY=pointer.clientY;            }                        ev.button=which<4?Math.max(0,which-1):button&4&&1||button&2; // left:0 middle:1 right:2            ev.length=pointerLength(pointers);        }        return ev;    }    struct.prototype={        version:VERSION,        constructor:struct,        latestTime:0,        init:function(config){            var self=this,                handler=this.handler=function(ev){                    self.handleEvent(ev);                }            this.events={};            this.duration=isNaN(parseInt(config.duration))?600:parseInt(config.duration);            this.direction=parseInt(config.direction)==0?0:1;            this.current=parseInt(config.start)||0;            this.mouse=config.mouse==null?true:!!config.mouse;            this.mousewheel=!!config.mousewheel;            this.interval=parseInt(config.interval)||5000;            this.playing=config.autoplay==null?true:!!config.autoplay;            this.arrowkey=!!config.arrowkey;            this.fullsize=config.fullsize==null?true:!!config.fullsize;            this.align=config.align||'center';            this.pages=children(this.container);            this.length=this.pages.length;            this.pageData=[];            addListener(this.container,STARTEVENT.join(" ")+" click"+(this.mousewheel?" mousewheel DOMMouseScroll":""),handler);            addListener(DOC,MOVEEVENT.join(" ")+(this.arrowkey?" keydown":""),handler);            addListener(ROOT,'resize',handler);                        each(this.pages,function(page){                self.pageData.push({                    cssText:page.style.cssText||''                });            });            this.pageData.container=this.container.style.cssText||'';            this.on({                before:function(){clearTimeout(this.playTimer);},                dragStart:function(){clearTimeout(this.playTimer);removeRange();},                after:this.firePlay            }).firePlay();            this.comment=document.createComment(' Powered by TouchSlider v'+this.version+'  https://github.com/qiqiboy/touchslider ');            this.container.appendChild(this.comment);            this.resize();        },        resize:function(){            var self=this,                type=this.direction?'height':'width',                pst=getStyle(this.container,'position'),                css;            this.size=this.getSize(this.offsetParent=this.container[pst=='absolute'||pst=='fixed'?'offsetParent':'parentNode']||DOC.body);            css={                float:'left',                display:'inline'            }            each(this.pages,function(page){                if(self.fullsize){                    css[type]=self.size-self.getMarginSize(page)-self.getPaddingSize(page)-self.getBorderSize(page)+'px';                }                if(type=='height'){                    css['clear']='both';                }                setStyle(page,css);            });            this.total=this.getSum(0,this.length);                        css={};            if(pst=='static'){                css={position:'relative'};            }            css[transition]='none';            css[type]=this.total+'px';            css[this.direction?'top':'left']=this.getPos(this.current)+'px';            cancelFrame(this.timer);            setStyle(this.container,css);            clearTimeout(this.playTimer);            return this.firePlay();        },        on:function(ev,callback){            var self=this;            if(type(ev)=='object'){                each(ev,function(ev,callback){                    self.on(ev,callback);                });            }else{                if(!this.events[ev]){                    this.events[ev]=[];                }                this.events[ev].push(callback);            }            return this;        },        fire:function(ev){            var self=this,                args=slice.call(arguments,1);            each(this.events[ev]||[],function(func){                if(isFunction(func)){                    func.apply(self,args);                }            });            return this;        },        isStatic:function(){            return !this.timer && !this.drag;        },        prev:function(){            return this.slide((this.current-1+this.length)%this.length);        },        next:function(){            return this.slide((this.current+1)%this.length);        },        play:function(){            this.playing=true;            return this.firePlay();        },        firePlay:function(){            var self=this;            if(this.playing){                this.playTimer=setTimeout(function(){                    self.next();                },this.interval);            }            return this;        },        pause:function(){            this.playing=false;            clearTimeout(this.playTimer);            return this;        },        slide:function(_index){            var self=this,                dir=this.direction,                stime=+new Date,                duration=this.duration,                current=this.current,                index=Math.min(Math.max(0,_index),this.length-1),                curSize=this.getSum(index,index+1),                curPos=parseFloat(getStyle(this.container,dir?'top':'left'))||0,                type=dir?'top':'left',                css={},tarPos;                    tarPos=this.getPos(index);            duration*=Math.min(1,Math.abs(tarPos-curPos)/curSize)||10;            this.current=index;            this.latestTime=stime+duration;            this.fire('before',current,index);            this.end=function(){                delete self.timer;                self.fire('after',index,current);            }            if(transition){                this.timer=1;                css[transition]=type+' '+duration+'ms ease';                css[type]=tarPos+'px';                setStyle(this.container,css);            }else{                cancelFrame(this.timer);                ani();            }            function ani(){                var offset=Math.min(duration,+new Date-stime),                    s=EASE(offset,0,1,duration)                    cp=(tarPos-curPos)*s+curPos;                self.container.style[type]=cp+'px';                if(offset==duration){                    self.end();                }else{                    self.timer=nextFrame(ani);                }            }        },        handleEvent:function(oldEvent){            var ev=filterEvent(oldEvent),                canDrag=ev.button<1&&ev.length<2&&(!this.pointerType||this.pointerType==ev.eventType)&&(this.mouse||ev.pointerType!='mouse');            switch(ev.eventCode){                case 2:                    if(canDrag&&this.rect){                        var index=this.current,                            dir=this.direction,                            rect=[ev.clientX,ev.clientY],                            _rect=this.rect,                            offset=rect[dir]-_rect[dir];                        if(this.drag==null && _rect.toString()!=rect.toString()){                            this.drag=Math.abs(offset)>=Math.abs(rect[1-dir]-_rect[1-dir]);                            this.drag && this.fire('dragStart',ev);                        }                        if(this.drag){                            if(!this.pages[index+(offset>0?-1:1)]){                                offset/=Math.abs(offset)/this.size+2;                            }                            this.container.style[dir?'top':'left']=this.startPos+offset+'px';                            this.fire('dragMove',ev);                            this._offset=offset;                            ev.preventDefault();                        }                    }                    break;                case 1:                case 3:                    if(canDrag){                        var self=this,                            index=this.current,                            type=this.direction?'top':'left',                            isDrag,offset,tm,nn,sub,curPos,tarPos,myWidth;                        if(ev.length&&(ev.eventCode==1||this.drag)){                            nn=ev.target.nodeName.toLowerCase();                            clearTimeout(this.eventTimer);                            if(!this.pointerType){                                this.pointerType=ev.eventType;                            }                            this.startPos=parseFloat(getStyle(this.container,type))||0;                            if(transition){                                this.container.style[transition]='none';                            }else if(this.timer){                                cancelFrame(this.timer);                                delete this.timer;                            }                            this.rect=[ev.clientX,ev.clientY];                            this.time=+new Date;                            this.container.style[type]=this.startPos+'px';                            if(ev.eventType!='touch' && (nn=='a' || nn=='img')){                                ev.preventDefault();                            }                        }else if(tm=this.time){                            offset=this._offset||0;                            isDrag=this.drag;                            curPos=this.startPos+offset;                            tarPos=this.getPos(index);                            each("rect drag time startPos _offset".split(" "),function(prop){                                delete self[prop];                            });                            if(isDrag){                                sub=offset>0?1:-1;                                while(sub*(curPos-tarPos)>this.getOuterSize(this.pages[index])/2&&this.pages[index-sub]){                                    tarPos=this.getPos(index-=sub);                                }                                if(Math.abs(offset)>20&&+new Date-tm<500){                                    index-=sub;                                }                                                                this.fire('dragEnd',ev);                                ev.preventDefault();                            }                            if(curPos!=tarPos){                                this.slide(index);                            }else if(isDrag){                                this.firePlay();                            }                            this.eventTimer=setTimeout(function(){                                delete self.pointerType;                            },400);                        }                    }                    break;                case 4:                    if(this.timer){                        ev.preventDefault();                    }                    break;                case 5:                    ev.preventDefault();                    if(this.isStatic() && +new Date-this.latestTime>Math.max(1000-this.duration,0)){                        var wd=ev.wheelDelta||-ev.detail;                        Math.abs(wd)>=3 && this[wd>0?'prev':'next']();                    }                    break;                case 6:                    var nn=ev.target.nodeName.toLowerCase();                    if(this.isStatic() && nn!='input' && nn!='textarea' && nn!='select'){                        switch(ev.keyCode||ev.which){                            case 33:                            case 37:                            case 38:                                this.prev();                                break;                            case 32:                            case 34:                            case 39:                            case 40:                                this.next();                                break;                            case 35:                                this.slide(this.length-1);                                break;                            case 36:                                this.slide(0);                                break;                        }                    }                    break;                case 7:                    this.resize();                    break;                case 8:                    if(oldEvent.propertyName==(this.direction?'top':'left')){                        this.container.style[transition]='none';                        this.end();                    }                    break;            }        },        getSum:function(from,to){            var sum=0;            while(from<to){                sum+=this.getOuterSize(this.pages[from++],true);            }            return sum;           },        getPos:function(index){            var type=this.direction?'Top':'Left',                myWidth=this.getOuterSize(this.pages[index],true),                sum=this.getSum(0,index)+this['getMargin'+type+'Size'](this.container)+this['getBorder'+type+'Size'](this.container);            switch(this.align){                case 'top':                case 'left':                    return -sum;                case 'bottom':                case 'right':                    return this.size-myWidth-sum;                default:                    return (this.size-myWidth)/2-sum;            }        },        getOuterSize:function(elem,withMargin){            return elem[this.direction?'offsetHeight':'offsetWidth']+(withMargin?this.getMarginSize(elem):0);        },        getInnerSize:function(elem){            return this.getOuterSize(elem)-this.getBorderSize(elem);        },        getSize:function(elem){            return elem[this.direction?'offsetHeight':'offsetWidth']-this.getPaddingSize(elem)-this.getBorderSize(elem);        },        destroy:function(){            var pageData=this.pageData;            offListener(this.container,STARTEVENT.join(" ")+" click"+(this.mousewheel?" mousewheel DOMMouseScroll":""),this.handler);            offListener(DOC,MOVEEVENT.join(" ")+(this.arrowkey?" keydown":""),this.handler);            offListener(ROOT,'resize',this.handler);            each(this.pages,function(page,index){                page.style.cssText=pageData[index].cssText;            });            this.container.style.cssText=pageData.container;            this.container.removeChild(this.comment);            this.length=0;                        return this.pause();        },        refresh:function(){            this.pages=children(this.container);            this.length=this.pages.length;            this.current=Math.max(Math.min(this.length-1,this.current),0);            return this.resize();        },        append:function(elem,index){            if(null==index){                index=this.pages.length;            }            this.pageData.splice(index,0,{                cssText:elem.style.cssText||''            });            this.container.insertBefore(elem,this.pages[index]||null);            return this.refresh();        },        prepend:function(elem){            return this.append(elem,0);        },        insertBefore:function(elem,index){            return this.append(elem,index-1);        },        insertAfter:function(elem,index){            return this.append(elem,index+1);        },        remove:function(index){            this.container.removeChild(this.pages[index]);            this.pageData.splice(index,1);            return this.refresh();        }    }    each("margin padding border".split(" "),function(type){        each("Top Left Right Bottom".split(" "),function(dir){            var prop=type+dir;            struct.prototype[camelCase('get-'+prop)+'Size']=function(elem){                return parseFloat(getStyle(elem,prop+(type=='border'?'Width':'')))||0;            }        });        struct.prototype[camelCase('get-'+type)+'Size']=function(elem){            return this[camelCase('get-'+type)+(this.direction?'Top':'Left')+'Size'](elem)+this[camelCase('get-'+type)+(this.direction?'Bottom':'Right')+'Size'](elem);        }    });    if(typeof exports === 'object') {        module.exports = struct;    } else if(typeof define=='function' && define.amd){        define('TouchSlider',function(){            return struct;        });    }else ROOT.TouchSlider=struct;})(window, function(wrap,config){    if(!(this instanceof arguments.callee)){        return new arguments.callee(wrap,config);    }    this.container=typeof wrap=='string'?document.getElementById(wrap):wrap;    this.init(config||{});});
 |