(function(){ var sina = { $ : function(objname){if(document.getelementbyid){return eval('document.getelementbyid("'+objname+'")')}else{return eval('document.all.'+objname)}}, //event addevent : function(obj,eventtype,func){if(obj.attachevent){obj.attachevent("on" + eventtype,func);}else{obj.addeventlistener(eventtype,func,false)}}, delevent : function(obj,eventtype,func){ if(obj.detachevent){obj.detachevent("on" + eventtype,func)}else{obj.removeeventlistener(eventtype,func,false)} }, // 获取下一个非空节点 next : function(el){ var next = el.nextsibling; while(next && next.nodetype != 1){ next = next.nextsibling; } return next; }, extend : function(o,t){ for (var p in t){ o[p] = t[p]; } return o; }, /** * 设置元素的css样式 */ css : function(o,s){ var t = o.style; for (var p in s){ t[p] =s[p]; } return o; }, getcurrindex : function(len,curr){ if(curr >= len) curr -= len; if(curr <0) curr += len; return curr; }, // 获取数组的某个元素 getarrel : function(arr,curr){ return arr[this.getcurrindex(arr.length,curr)]; }, supporttransition : (function(){ // 这里只是简单的判断一个是否是webkit内核 return window.navigator.useragent.tolowercase().indexof("webkit")>=0; })(), /* * 动画工具,元素elem从当前状态运行到to样式状态,花费time和时间 * 注:需要使用settimeout 0 是为了以上javascript执行器一直占用ui线程,导致元素的css动画得不到所需要的效果。其中一个例子就是:当设置duration为0时,如果后面的代码再有设置duration不为0的,则执行时css的duration为0不生效。这是由于js执行时长时间占用ui线程,导致页面渲染前webkittransitionduration已经不为0了。 */ transition : function(elem,to,time){ settimeout(function(){ sina.css(elem,{ display : "", webkittransform : "translate3d(0,0,0)", //webkittransitiontimingfunction : "linear", webkittransitionduration : time }); sina.css(elem,to); sina.css(elem.imgobj,{ webkittransform : "translate3d(0,0,0)", //webkittransitiontimingfunction : "linear", webkittransitionduration : time }); sina.css(elem.imgobj,to.imgobj); },0); } }; var d = document,w = this, b = d.body, h = d.documentelement; var scrollpic3d = function(){}; scrollpic3d.prototype = { boxid : '', //容器id width : 500, //容器宽度 height : 100, //容器高度 imgwidth : 90, //图片宽度 imgheight : 120, //图片高度 descheight : 100, descclass : "picdesc", showsnumber : 7, //显示数量 zoom : 0.8, //小图缩放比 data : [], position : [], timelimit : 200, //动画时间,100毫秒 leftindex : 0,//最左边图片的数据下标 autoplay : false, //是否自动播放 autoplaytime : 5, //自动播放时间间隔 version : "1.0", author : "mengjia", init : function(){ this.initdata(); if(this.data.length < this.showsnumber){alert('错误:滚动图片数据小于显示数据');return}; if(this.showsnumber % 2 == 0){this.showsnumber++}; //保证是奇数 var boxel = sina.$(this.boxid); boxel.style.width = this.width + 'px'; boxel.style.height = this.height + 'px'; boxel.style.position = 'relative'; boxel.style.overflow = 'hidden'; boxel.style.zoom = 1; this.setleftindex(0); this.showdesc(this.index);// 显示初始化模块的信息 this.ifdestory(); }, /* * 销毁页面时的数据删除处理,防止内存泄露 */ ifdestory : function(){ var thisobj = this; sina.addevent(w,"unload",function(){ delete thisobj.data; }); }, /* * 初始化数据,把目标窗口this.boxid中的所有image元素做为需要动态显示的图片元素,每一个元素的下一个节点是其描述信息,会添加到新创建的节点中做显示处理。如果这个图片没有描述信息,则添加空节点 * */ initdata : function(){ // 处理所有img元素 var boxel = sina.$(this.boxid); // 添加相应的操作元素和显示描述的元素 var descel = d.createelement("div"); descel.id = this.descid = "descel-"+ (+new date()); descel.classname = "imgdesc_"; descel.style.position = "absolute"; descel.style.height = this.descheight + "px"; descel.style.bottom = 0; descel.style.width = "100%"; boxel.appendchild(descel); var objs = boxel.childnodes,obj,imgobj; var imgobjs = boxel.getelementsbytagname("img"),imgobj,tempthis = this; for (var i = 0,j=0,len = objs.length; i < len; i++){ obj = objs[i]; if(obj.tagname != "div")continue; //obj.num = i; obj.style.position = 'absolute'; imgobj = obj.getelementsbytagname("img")[0]; // 如果没有图片,则跳过 if(!imgobj)continue; obj.imgobj = imgobj; imgobj.num = obj.num = j++; imgobj.style.width = "100%"; imgobj.style.height = "100%"; // sina.addevent(imgobj,"click",function(e){ // e = e || w.event; // var tar = e.target || e.srcelement; // // 如果当前页面正是焦点图,则可弹出页面 // tempthis.go(tar.num); // if(tempthis.index != tar.num){ // if ( e.preventdefault ) { // e.preventdefault(); // } // if ( e.stoppropagation ) { // e.stoppropagation(); // } // return false; // } // }); // 把对图片相应的描述内容放置到descel元素中 var next = this._getdescel(obj); if(!next){ next = d.createelement("div"); } next.style.display = "none"; descel.appendchild(next); this.data.push(obj); } }, /* * 显示前一个图片,有动画 * */ pre : function(){ this.go(this.index - 1); }, /* * 显示下一个图片,有动画 * */ next : function(){ this.go(this.index + 1); }, /* * 自动播放函数,通过this.autoplay属性控制 * */ autoplayfunc : function(){ if(this.autoplay){ clearinterval(this._autoplay); var tempthis = this; this._autoplay = setinterval(function(){tempthis.next();},this.autoplaytime*1000); }; }, /* * css3的移动到下一个的动画实现函数 * @param clockwise {boolean} 是顺时针还是逆时针运动 * @param time {number} 执行这次动画所需要的时间 * */ transnext : function(clockwise,time){ var datas = this.data,leftindex = this.leftindex,posarr = this.position,len = this.showsnumber,pos,elem, //获取需要提前准备的元素 el = sina.getarrel(datas,clockwise?leftindex+len : leftindex-1), // 获取该元素所对应的样式 s = sina.getarrel(posarr,clockwise?posarr.length-1:0); // 立即应用该样式 sina.transition(el,s,"0s"); for (var i = 0; i <= len; i++){ // 获取当前对应的元素 elem = sina.getarrel(datas,clockwise?i+leftindex:i-1+leftindex); //给对应的元素设置对应的位置信息,同时指定css动画的时间 pos = sina.getarrel(posarr,clockwise?i:i+1); sina.transition(elem,pos,time+"ms"); } // 设置leftindex和index值 this.leftindex = sina.getcurrindex(datas.length,clockwise?leftindex+1:leftindex-1); this.index = sina.getcurrindex(datas.length,this.leftindex + math.floor(len / 2)); }, /* * 把中间的图片设置成第下标为index的图片,有动画 * @param index {integer} 目标图片对应的下标值 * @example * 例如:需要显示第2副图的描述信息,则===> go(1),则会产生动画效果 * */ go : function(index){ if(this.index == index){return;}; var start = this.index, end = index, len = this.data.length; cleartimeout(this._timeout); //最短路程 if(math.abs(end - start) > len / 2){ if(end > len / 2){ end = end - len; }else{ end = end + len; }; }; // 根据是否支持css3动画 分别做处理 this[sina.supporttransition?"_css3animate":"_jsanimate"](end); }, /* * css3 transition动画实现函数,传入结束值,开始产生动画 * */ _css3animate : function(end){ var obj = this,start = this.index, length = math.abs(end - start), steptime = this.timelimit / length; this._timeout = settimeout(function(){ if(!length--){//根据路程做多个timeout调用 if(obj.onend){obj.onend(start,obj.index)}; return; } obj.transnext(end > start,steptime); obj._timeout = settimeout(arguments.callee,steptime/2); },0); }, /* * js动画实现函数,传入结束值,开始产生动画 * */ _jsanimate : function(end){ //步数 var step = this.timelimit / 20, obj = this, start = this.index, now = 0; this._timeout = settimeout(function(){ var index = obj.index; if(now >= step){ if(index != math.round(index)) obj.go(math.round(index)); if(obj.onend){obj.onend(start,index)}; return; }; now ++; var t = now; // 设置动画运行特效,三次方函数 var value = ((end - start)*((t=t/step-1)*t*t + 1))+ start; obj.setindex(value); obj._timeout = settimeout(arguments.callee,20); },20); }, /* * 获取当前图片对应的描述元素 * @param {htmldomelement} 图片元素对应的htmldomelement * */ _getdescel : function(obj){ var nodes = obj.childnodes,node; for (var i = 0,len = nodes.length; i < len; i++){ node = nodes[i]; if(node && node.classname && node.classname.indexof(this.descclass) >= 0) return node; } return null; /*var pnode = imgel.parentnode, next = sina.next(pnode.tagname.tolowercase() == "a"?pnode :imgel), tagname = next?next.tagname.tolowercase():""; // 需要显示新图片的描述信息 if(!next || (next && (tagname == "img" || tagname == "a" || next.id == this.descid))){ // 没有描述元素,返回空 return null; } return next; */ }, /* * 只显示当前下标图片对应的描述信息 * @param {integer} 当前图片对应的下标值 * @example * 例如:需要显示第2副图的描述信息,则===> showdesc(1) * */ showdesc : function(currindex){ var children = sina.$(this.descid).childnodes; for (var i = 0,len = children.length; i < len; i++){ children[i].style.display = i == currindex?"":"none"; } }, /* * 图片轮转完成后触发的动作 * @param preindex {integer} 原来图片的下标 * @param currindex {integer} 当前图片的下标 * todo 可以做一些动画效果,例如描述信息的淡入淡出等 * */ onend : function(preindex , currindex){ // todo 可以做动画过渡效果 currindex = math.round(currindex); if(currindex >= this.data.length){ currindex = currindex - this.data.length; } this.showdesc(currindex); }, /* * 设置当前下标的值作为中间图片,无动画 * @param index {integer} 图片的下标 * */ setindex : function(index){ this.setleftindex(index - math.floor(this.showsnumber/2)); }, /* * 设置当前下标的值作为最左边图片,无动画 * @param leftindex {integer} 图片的下标 * */ setleftindex : function(leftindex){ var piclen = this.data.length,half = this.showsnumber/2,getindex = sina.getcurrindex; //避免浮点运算的bug leftindex = math.round(leftindex * 1000) / 1000; leftindex = getindex(piclen,leftindex); this.leftindex = leftindex; var index = getindex(piclen,math.floor(half) + leftindex); this.index = index; for(var i=0;i i? l : this.width - l - objw; obj.style.left = l + "px"; t = math.round((this.height - objh - this.descheight) / 2 ); obj.style.top = t + 'px'; obj.style.zindex = z = math.round(zindex); //settimeout(function(){ obj.style.zoom = 1; imgobj.style.zoom = 1; //},0); // 这里保存初始时所有确定的图片位置大小等信息 if(sina.supporttransition && !this.position[i]){ this.position[i] = { zindex:z*100,// 放大zindex left:l + "px", top:t+"px", width:imgw +"px", height:imgh+"px", imgobj : { width : w + "px", height : h + "px" } } }; } // 保存显示元素前一个和最后一个的位置 if(sina.supporttransition && this.position.length != this.showsnumber+2){ var temp = this.position[0]; this.position.unshift(sina.extend(sina.extend({},temp),{ left : "-"+temp.width, zindex : 0 })); this.position[this.position.length-1] = sina.extend(sina.extend({},temp),{ left : this.width+"px", zindex : 0 }); }; this.autoplayfunc(); } }; w.scrollpic3d = scrollpic3d; })();