2010-7-29 10:01
cloudgamer
SlideView 滑动展示效果
滑动展示效果主要用在图片或信息的滑动展示,也可以设置一下做成简单的口风琴(Accordion)效果。
这个其实就是以前写的[url=http://www.cnblogs.com/cloudgamer/archive/2008/05/13/1194272.html]图片滑动展示效果[/url]的改进版,那是我第一篇比较受关注的文章,是时候整理一下了。
有如下特色:
1,有四种方向模式选择;
2,结合tween算法实现多种滑动效果;
3,能自动根据滑动元素计算展示尺寸;
4,也可自定义展示或收缩尺寸;
5,可扩展自动切换功能;
6,可扩展滑动提示功能。
兼容:ie6/7/8, firefox 3.6.8, opera 10.51, safari 4.0.5, chrome 5.0
[url=http://www.cnblogs.com/cloudgamer/archive/2010/07/29/SlideView.html][b][color=red]详细程序说明和效果预览[/color][/b][/url]
[b][url=http://files.cnblogs.com/cloudgamer/SlideView.rar]完整实例下载[/url][/b]
[code]<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>SlideView 滑动展示效果</title>
<script>
eval(function(p,a,c,k,e,r){e=function(c){return(c<62?'':e(parseInt(c/62)))+((c=c%62)>35?String.fromCharCode(c+29):c.toString(36))};if('0'.replace(0,e)==0){while(c--)r[e(c)]=k[c];k=[function(e){return r[e]||e}];e=function(){return'([3-59f-hj-mp-ru-yCG-NP-RT-Z]|[1-4]\\w)'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('5 $$,$$B,$$A,$$F,$$D,$$E,$$C,$$S;(4(){5 O,B,A,F,D,E,C,S;O=4(id){9"3s"==2T id?1j.getElementById(id):id};O.emptyFunction=4(){};O.1D=4(1e,1E,2m){f(2m===1q)2m=1k;14(5 1l W 1E){f(2m||!(1l W 1e)){1e[1l]=1E[1l]}}9 1e};O.deepextend=4(1e,1E){14(5 1l W 1E){5 1Y=1E[1l];f(1e===1Y)continue;f(2T 1Y==="h"){1e[1l]=Q.callee(1e[1l]||{},1Y)}K{1e[1l]=1Y}}9 1e};O.wrapper=4(me,3u){5 2U=4(){me.1b(3,Q)};5 2V=4(){};2V.N=3u.N;2U.N=3v 2V;9 2U};B=(4(ua){5 b={1F:/1F/.L(ua)&&!/2W/.L(ua),2W:/2W/.L(ua),3w:/webkit/.L(ua)&&!/2X/.L(ua),3x:/3x/.L(ua),2X:/2X/.L(ua)};5 2n="";14(5 i W b){f(b[i]){2n="3w"==i?"1Z":i;2Y}}b.1Z=2n&&1G("(?:"+2n+")[\\\\/: ]([\\\\d.]+)").L(ua)?1G.$1:"0";b.ie=b.1F;b.3y=b.1F&&30(b.1Z,10)==6;b.ie7=b.1F&&30(b.1Z,10)==7;b.3z=b.1F&&30(b.1Z,10)==8;9 b})(31.navigator.userAgent.32());A=4(){5 y={isArray:4(3A){9 Object.N.toString.1n(3A)==="[h 33]"},2o:4(15,1r,q){f(15.2o){9 2p(q)?15.2o(1r):15.2o(1r,q)}K{5 17=15.1s;q=2p(q)?0:q<0?18.3B(q)+17:18.3C(q);14(;q<17;q++){f(15[q]===1r)9 q}9-1}},2q:4(15,1r,q){f(15.2q){9 2p(q)?15.2q(1r):15.2q(1r,q)}K{5 17=15.1s;q=2p(q)||q>=17-1?17-1:q<0?18.3B(q)+17:18.3C(q);14(;q>-1;q--){f(15[q]===1r)9 q}9-1}}};4 1v(h,I){f(1q===h.1s){14(5 p W h){f(J===I(h[p],p,h))2Y}}K{14(5 i=0,17=h.1s;i<17;i++){f(i W h){f(J===I(h[i],i,h))2Y}}}};1v({21:4(h,I,M){1v(h,4(){I.1b(M,Q)})},34:4(h,I,M){5 y=[];1v(h,4(){y.3D(I.1b(M,Q))});9 y},1H:4(h,I,M){5 y=[];1v(h,4(3E){I.1b(M,Q)&&y.3D(3E)});9 y},every:4(h,I,M){5 y=1k;1v(h,4(){f(!I.1b(M,Q)){y=J;9 J}});9 y},some:4(h,I,M){5 y=J;1v(h,4(){f(I.1b(M,Q)){y=1k;9 J}});9 y}},4(1f,p){y[p]=4(h,I,M){f(h[p]){9 h[p](I,M)}K{9 1f(h,I,M)}}});9 y}();F=(4(){5 1I=33.N.1I;9{1w:4(2r,M){5 1J=1I.1n(Q,2);9 4(){9 2r.1b(M,1J.3F(1I.1n(Q)))}},bindAsEventListener:4(2r,M){5 1J=1I.1n(Q,2);9 4(m){9 2r.1b(M,[E.22(m)].3F(1J))}}}})();D={2s:4(k){5 1K=k?k.3G:1j;9 1K.3H.3I||1K.3J.3I},2t:4(k){5 1K=k?k.3G:1j;9 1K.3H.3K||1K.3J.3K},3L:1j.23?4(a,b){9!!(a.3M(b)&16)}:4(a,b){9 a!=b&&a.3L(b)},Y:4(k){5 v=0,1c=0,Z=0,11=0;f(!k.3N||B.3z){5 n=k;while(n){v+=n.offsetLeft,1c+=n.offsetTop;n=n.offsetParent};Z=v+k.3O;11=1c+k.3P}K{5 Y=k.3N();v=Z=D.2t(k);1c=11=D.2s(k);v+=Y.v;Z+=Y.Z;1c+=Y.1c;11+=Y.11};9{"v":v,"1c":1c,"Z":Z,"11":11}},clientRect:4(k){5 Y=D.Y(k),35=D.2t(k),36=D.2s(k);Y.v-=35;Y.Z-=35;Y.1c-=36;Y.11-=36;9 Y},1L:1j.23?4(R){9 1j.23.3Q(R,T)}:4(R){9 R.37},3R:1j.23?4(R,p){5 g=1j.23.3Q(R,T);9 p W g?g[p]:g.getPropertyValue(p)}:4(R,p){5 g=R.g,1L=R.37;f(p=="1x"){f(/38\\(1x=(.*)\\)/i.L(1L.1H)){5 1x=parseFloat(1G.$1);9 1x?1x/2u:0}9 1}K f(p=="3S"){p="3T"}5 y=1L[p]||1L[S.39(p)];f(!/^-?\\d+(?:px)?$/i.L(y)&&/^\\-?\\d/.L(y)){5 v=g.v,2w=R.runtimeStyle,3U=2w.v;2w.v=1L.v;g.v=y||0;y=g.pixelLeft+"px";g.v=v;2w.v=3U}9 y},3V:4(24,g,1M){f(!24.1s){24=[24]}f(2T g=="3s"){5 s=g;g={};g[s]=1M}A.21(24,4(R){14(5 p W g){5 1M=g[p];f(p=="1x"&&B.ie){R.g.1H=(R.37.1H||"").3W(/38\\([^)]*\\)/,"")+"38(1x="+1M*2u+")"}K f(p=="3S"){R.g[B.ie?"3T":"cssFloat"]=1M}K{R.g[S.39(p)]=1M}}})}};E=(4(){5 1g,1t,U=1,3a=4(l,j,r){f(!r.$$U)r.$$U=U++;f(!l.X)l.X={};5 12=l.X[j];f(!12){12=l.X[j]={};f(l["on"+j]){12[0]=l["on"+j]}}};f(31.3c){5 25={"3d":"3X","3e":"3Y"};1g=4(l,j,r){f(j W 25){3a(l,j,r);5 3Z=l.X[j][r.$$U]=4(m){5 2x=m.26;f(!2x||(l!=2x&&!(l.3M(2x)&16))){r.1n(3,m)}};l.3c(25[j],3Z,J)}K{l.3c(j,r,J)}};1t=4(l,j,r){f(j W 25){f(l.X&&l.X[j]){l.40(25[j],l.X[j][r.$$U],J);3f l.X[j][r.$$U]}}K{l.40(j,r,J)}}}K{1g=4(l,j,r){3a(l,j,r);l.X[j][r.$$U]=r;l["on"+j]=2y};1t=4(l,j,r){f(l.X&&l.X[j]){3f l.X[j][r.$$U]}};4 2y(){5 2z=1k,m=22();5 12=3.X[m.j];14(5 i W 12){3.$$2y=12[i];f(3.$$2y(m)===J){2z=J}}9 2z}}4 22(m){f(m)9 m;m=31.m;m.pageX=m.clientX+D.2t(m.3g);m.pageY=m.clientY+D.2s(m.3g);m.1y=m.3g;m.3h=3h;m.3i=3i;5 26={"3Y":m.toElement,"3X":m.fromElement}[m.j];f(26){m.26=26}9 m};4 3h(){3.cancelBubble=1k};4 3i(){3.2z=J};9{"1g":1g,"1t":1t,"22":22}})();C=(4(){5 U=1;9{1g:4(h,j,r){f(!r.$$$U)r.$$$U=U++;f(!h.V)h.V={};f(!h.V[j])h.V[j]={};h.V[j][r.$$$U]=r},1t:4(h,j,r){f(h.V&&h.V[j]){3f h.V[j][r.$$$U]}},19:4(h,j){f(!h.V)9;5 1J=33.N.1I.1n(Q,2),12=h.V[j];14(5 i W 12){12[i].1b(h,1J)}},41:4(h){f(!h.V)9;14(5 j W h.V){5 12=h.V[j];14(5 i W 12){12[i]=T}h.V[j]=T}h.V=T}}})();S={39:4(s){9 s.3W(/-([a-z])/ig,4(all,42){9 42.toUpperCase()})}};f(B.3y){try{1j.execCommand("BackgroundImageCache",J,1k)}catch(e){}};$$=O;$$B=B;$$A=A;$$F=F;$$D=D;$$E=E;$$C=C;$$S=S})();5 1z=4(1h,x){3.1N(1h,x);3.43();3.44();3.1O(3.x.45)};1z.N={1N:4(1h,x){5 1h=3.1P=$$(1h);3.1A=T;3.2A=T;3.1Q=0;3.1R=0;5 P=3.46(x);3.2B=P.2B|0;3.27=P.27|0;3.1S=P.1S|0;3.28=P.28;3.29=!!P.29;3.2a=P.2a;3.2C=P.2C;5 1u=3.2b=/^(11|1c|Z|v)$/.L(P.47.32())?1G.$1:"v";3.48=/Z|v/.L(3.2b);3.2c=/11|Z/.L(3.2b);5 1a=P.1a?$$A.34(P.1a,4(n){9 n}):$$A.1H(1h.childNodes,4(n){9 n.nodeType==1});3.1T=$$A.34(1a,4(k){5 g=k.g;9{"k":k,"g":g[1u],"13":g.13,"1B":g.1B}});3.3j=$$F.1w(3.3k,3);5 49=$$F.1w(3.2d,3);3.2D=$$F.1w(4(){1o(3.1A);$$C.19(3,"4a");f(3.29){3.1A=2E(49,3.27)}},3);$$C.19(3,"1C")},46:4(x){3.x={1a:T,47:"v",G:0,H:0,27:2u,2B:20,1S:20,45:T,29:1k,28:4(t,b,c,d){9-c*((t=t/d-1)*t*t*t-1)+b},2a:4(w){},2C:4(){}};9 $$.1D(3.x,x||{})},43:4(){5 1h=3.1P,g=1h.g,13=$$D.3R(1h,"13");3.4b={"13":g.13,"2F":g.2F};f(13!="4c"&&13!="3l"){g.13="4c"}g.2F="4d";$$E.1g(1h,"3e",3.2D);5 1B=2u,4e=3.2c?-1:1;3.1i(4(o){5 g=o.k.g;g.13="3l";g.1B=1B+=4e});$$C.19(3,"initContainer")},44:4(){5 17=3.1T.1s,1d=17-1,j=3.48?"Width":"Height",2e="2e"+j,1p=3.1P["client"+j],1U=18.3m(1p/17),4f=3.2c?4(i){9 1U*(1d-i)}:4(i){9 1U*i},G=3.x.G,H=3.x.H,2G,2H;f(G>0||H>0){f(G>0){G=18.G(G<=1?G*1p:18.H(G,1p),1U);H=(1p-G)/1d}K{H=18.H(H<1?H*1p:H,1U);G=1p-1d*H}2G=4(){9 G};2H=4(){9 H}}K{2G=4(o){9 18.G(18.H(o.k[2e],1p),1U)};2H=4(o){9(1p-o.G)/1d}}3.1i(4(o,i){5 k=o.k,1V=$$F.1w(3.2f,3,i);o.1V=$$F.1w(4(){1o(3.1A);3.1A=2E(1V,3.27);$$C.19(3,"4g",i)},3);$$E.1g(k,"3d",o.1V);o.2g=o.3n=4f(i);o.G=2G(o);o.H=2H(o)});$$C.19(3,"4h")},2f:4(w){3.2I(w|0);3.2a(3.1R);3.3o()},2d:4(){3.2I();3.2C();3.3o()},1O:4(w){1o(3.1A);f(w==1q){3.4i()}K{3.2I(w);3.2a(3.1R);3.3p()}},2I:4(w){5 setTarget;f(w==1q){2h=4(o){9 o.3n}}K{5 1a=3.1T,1d=1a.1s-1;3.1R=w=w<0||w>1d?0:w|0;5 3q=1a[w],H=3q.H,G=3q.G;2h=4(o,i){9 i<=w?H*i:H*(i-1)+G};f(3.2c){5 4j=2h;w=1d-w;2h=4(o,i){9 4j(o,1d-i)}}}3.1i(4(o,i){o.1y=2h(o,i);o.1W=o.2g;o.2J=o.1y-o.1W});$$C.19(3,"4k",w)},3o:4(){3.1Q=0;3.3k()},3k:4(){f(3.1Q<3.1S){3.4l();3.1Q++;3.2A=2E(3.3j,3.2B)}K{3.3p();$$C.19(3,"4m")}},4l:4(){3.2K(4(o){9 3.28(3.1Q,o.1W,o.2J,3.1S)});$$C.19(3,"4n")},3p:4(){3.2K(4(o){9 o.1y});$$C.19(3,"4o")},4i:4(){3.2K(4(o){9 o.3n});$$C.19(3,"4p")},2K:4(1f){1o(3.2A);5 1u=3.2b;3.1i(4(o,i){o.k.g[1u]=(o.2g=18.3m(1f.1n(3,o)))+"px"})},1i:4(I){$$A.21(3.1T,I,3)},2L:4(){1o(3.1A);1o(3.2A);$$C.19(3,"2L");5 1u=3.2b;3.1i(4(o){5 g=o.k.g;g[1u]=o.g;g.1B=o.1B;g.13=o.13;$$E.1t(o.k,"3d",o.1V);o.1V=o.k=T});$$E.1t(3.1P,"3e",3.2D);$$D.3V(3.1P,3.4b);3.1P=3.1T=3.3j=3.2D=T;$$C.41(3)}};1z.N.1N=(4(){5 1C=1z.N.1N,1O=1z.N.1O,2M={"1C":4(){3.2N=3.x.2N|0;3.2i=T;3.2O=J;3.4q=$$F.1w(4(){3.2f(3.1R+1)},3)},"4a":4(){3.29=3.2O=J;3.2P()},"4g":4(){1o(3.2i);3.2O=1k},"4m":4(){3.2P()},"2L":4(){1o(3.2i)}},N={2P:4(){f(!3.2O){1o(3.2i);3.2i=2E(3.4q,3.2N)}},1O:4(w){1O.1n(3,w==1q?3.1R:w);3.2P()}};9 4(){5 x=Q[1];f(x&&x.auto){$$.1D(x,{2N:2000},J);$$.1D(3,N);$$A.21(2M,4(1f,p){$$C.1g(3,p,1f)},3)}1C.1b(3,Q)}})();1z.N.1N=(4(){5 1C=1z.N.1N,2M={"1C":4(){3.3r=/^(11|1c|Z|v)$/.L(3.x.4r.32())?1G.$1:"11"},"4h":4(){5 P=3.x,2Q=P.2Q,1X=P.1X,re=1X&&3v 1G("(^|\\\\s)"+1X+"(\\\\s|$)"),4t=4(k){5 1a=k.getElementsByTagName(2Q);f(1X){1a=$$A.1H(1a,4(n){9 re.L(n.className)})}9 1a[0]};5 2j=P.2j,2k=P.2k,2e=/Z|v/.L(3.3r)?"3O":"3P";3.1i(4(o){5 k=o.k,2R=4t(k);k.g.2F="4d";2R.g.13="3l";o.u={"k":2R,"2f":2j!=1q?2j:0,"2d":2k!=1q?2k:-2R[2e]}})},"4k":4(w){5 1d=3.1T.1s-1;3.1i(4(o,i){5 u=o.u;f(3.2c){i=1d-i}u.1y=w==1q||w!=i?u.2d:u.2f;u.1W=u.2g;u.2J=u.1y-u.1W})},"4n":4(){3.2S(4(u){9 3.28(3.1Q,u.1W,u.2J,3.1S)})},"4o":4(){3.2S(4(u){9 u.1y})},"4p":4(){3.2S(4(u){9 u.2d})},"2L":4(){3.1i(4(o){o.u=T})}},N={2S:4(1f){5 1u=3.3r;3.1i(4(o,i){5 u=o.u;u.k.g[1u]=(u.2g=18.3m(1f.1n(3,u)))+"px"})}};9 4(){5 x=Q[1];f(x&&x.u==1k){$$.1D(x,{4r:"11",2Q:"*",1X:"",2j:T,2k:T},J);$$.1D(3,N);$$A.21(2M,4(1f,p){$$C.1g(3,p,1f)},3)}1C.1b(3,Q)}})();',[],278,'|||this|function|var||||return||||||if|style|object||type|node|element|event|||name|from|handler|||tip|left|index|options|ret||||CE||||max|min|callback|false|else|test|thisp|prototype||opt|arguments|elem||null|guid|cusevents|in|events|rect|right||bottom|handlers|position|for|array||len|Math|fireEvent|nodes|apply|top|maxIndex|destination|method|addEvent|container|_each|document|true|property||call|clearTimeout|clientSize|undefined|elt|length|removeEvent|pos|each|bind|opacity|target|SlideView|_timerDelay|zIndex|init|extend|source|msie|RegExp|filter|slice|args|doc|curStyle|value|_initialize|reset|_container|_time|_index|duration|_nodes|defaultSize|SHOW|begin|tipClass|copy|version||forEach|fixEvent|defaultView|elems|fix|relatedTarget|delay|tween|autoClose|onShow|_pos|_reverse|close|offset|show|current|getTarget|_autoTimer|tipShow|tipClose||override|vMark|indexOf|isNaN|lastIndexOf|fun|getScrollTop|getScrollLeft|100||rtStyle|related|handleEvent|returnValue|_timerMove|interval|onClose|_LEAVE|setTimeout|overflow|getMax|getMin|_setMove|change|_setPos|dispose|methods|autoDelay|_autoPause|_autoNext|tipTag|tipNode|_setTipPos|typeof|ins|subclass|opera|chrome|break||parseInt|window|toLowerCase|Array|map|sLeft|sTop|currentStyle|alpha|camelize|storage||addEventListener|mouseenter|mouseleave|delete|srcElement|stopPropagation|preventDefault|_MOVE|_move|absolute|round|defaultTarget|_easeMove|_targetMove|nodeShow|_tipPos|string||parent|new|safari|firefox|ie6|ie8|obj|ceil|floor|push|item|concat|ownerDocument|documentElement|scrollTop|body|scrollLeft|contains|compareDocumentPosition|getBoundingClientRect|offsetWidth|offsetHeight|getComputedStyle|getStyle|float|styleFloat|rsLeft|setStyle|replace|mouseover|mouseout|fixhandler|removeEventListener|clearEvent|letter|_initContainer|_initNodes|defaultIndex|_setOptions|mode|_horizontal|CLOSE|leave|_style|relative|hidden|gradient|getDefaultTarget|enter|initNodes|_defaultMove|get|setMove|_tweenMove|finish|tweenMove|targetMove|defaultMove|_NEXT|tipPos||getTipNode'.split('|'),0,{}))
</script>
</head>
<body>
<style type="text/css">
.sv, .sv li {
padding:0;
margin:0;
list-style:none;
}
.sv {
width:500px;
height:100px;
font-size:20px;
color:#fff;
}
.sv li {
width:300px;
height:100px;
}
.sv span {
position:absolute;
padding:5px 10px;
}
.sv span.bottom {
right:0;
bottom:0;
}
</style>
<ul id="idSlideView" class="sv">
<li style="background-color:#D32226;"> <span>0</span> <span class="bottom">0</span> </li>
<li style="background-color:#89C73E;"> <span>1</span> <span class="bottom">1</span> </li>
<li style="background-color:#875FBE;"> <span>2</span> <span class="bottom">2</span> </li>
<li style="background-color:#5C7CDA;"> <span>3</span> <span class="bottom">3</span> </li>
<li style="background-color:#E7AD00;"> <span>4</span> <span class="bottom">4</span> </li>
</ul>
<br>
模式:
<select id="idMode">
<option value="left">左边</option>
<option value="right">右边</option>
</select>
默认索引:
<select id="idIndex">
<option value="">无</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
尺寸:
<select id="idSize">
<option value="[0,0]">按元素尺寸</option>
<option value="[0.5,0]">展示占一半</option>
<option value="[200,0]">展示200px</option>
<option value="[0,0.1]">收缩占十分一</option>
<option value="[0,80]">收缩80px</option>
</select>
<br>
关闭:
<select id="idClose">
<option value="1">自动</option>
<option value="">不自动</option>
</select>
速度:
<select id="idDuration">
<option value="20">默认</option>
<option value="10">快速</option>
<option value="40">慢速</option>
</select>
tween:
<select id="idTween">
<option value="">默认</option>
<option value="1">反弹</option>
</select>
<br>
<input id="idShow" type="button" value="手动展示">
<div id="t"></div>
<script>
(function(){
var container = $$("idSlideView"), show = $$("idShow"),
options = {
onShow: function(){
show.value = "手动关闭";
show.onclick = function(){ sv.close(); }
},
onClose: function(){
show.value = "手动展示";
show.onclick = function(){ sv.show(2); }
}
},
sv = new SlideView( "idSlideView", options );
$$("idClose").onchange = function(){
options.autoClose = sv.autoClose = !!this.value;
}
$$("idDuration").onchange = function(){
options.duration = sv.duration = this.value | 0;
}
$$("idTween").onchange = function(){
options.tween = sv.tween = this.value == ""
? function(t,b,c,d){ return -c * ((t=t/d-1)*t*t*t - 1) + b; }
: function(t,b,c,d){
if ((t/=d) < (1/2.75)) {
return c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
} else {
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
}
};
}
function Create(){
sv.dispose();
sv = new SlideView( "idSlideView", options );
}
$$("idMode").onchange = function(){
options.mode = this.value; Create();
}
$$("idSize").onchange = function(){
options.max = eval(this.value+"[0]");
options.min = eval(this.value+"[1]");
Create();
}
$$("idIndex").onchange = function(){
if( this.value != "" ){
options.defaultIndex = this.value | 0;
} else {
delete options.defaultIndex;
}
Create();
}
})()
</script>
<br>
<br>
<style type="text/css">
.sv2, .sv2 li { padding:0; margin:0; list-style:none; }
.sv2 {
width:500px;
height:300px;
font-size:12px;
line-height:1.5em;
border:1px solid #000;
}
.sv2 li {
width:299px;
height:300px;
background:#FFF;
border-right:1px solid #000;
}
.sv2 li.last { width:300px; border-right:0; }
.sv2 li.last div { width:290px; }
.sv2 li img{
width:299px;
}
.sv2 div {
background-color:#000;
opacity:0.6;
filter:alpha(opacity=60);
color:#FFF;
padding:5px;
width:289px;
}
.sv2 li a:link,
.sv2 li a:visited,
.sv2 li a:hover,
.sv2 li a:active {
color:#F30;
font-weight:bold;
text-decoration:none;
padding-right:10px;
}
</style>
图片滑动展示效果:
<ul id="idSlideView2" class="sv2">
<li>
<div> <a href="http://shop33359573.taobao.com/">内裤蛋糕</a> 神秘浪漫的内裤蛋糕礼盒 </div>
<img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/254820/o_1.jpg"> </li>
<li>
<div> <a href="http://item.taobao.com/item.htm?id=5017267585">内裤蛋糕</a> 送给最亲密的TA~~ </div>
<img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/254820/o_2.jpg"> </li>
<li>
<div> <a href="http://item.taobao.com/item.htm?id=5356744381">内裤蛋糕</a> 超SWEET~~打开漂亮的礼品盒,甜蜜可爱的蛋糕呈现眼前 </div>
<img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/254820/o_3.jpg"> </li>
<li>
<div> <a href="http://item.taobao.com/item.htm?id=5017188447">内裤蛋糕</a> 好Q哦!慢慢解开丝带,竟然是一条条漂亮的内裤 </div>
<img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/254820/o_4.jpg"> </li>
<li class="last">
<div> <a href="http://item.taobao.com/item.htm?id=5012797009">内裤蛋糕</a> 超级SWEET又脸红耶!!! </div>
<img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/254820/o_5.jpg"> </li>
</ul>
<input id="idAuto" type="button" value="取消自动">
<script>
(function(){
var options = { tip: true, auto: true, mode: "right" }, sv = new SlideView( "idSlideView2", options );
$$("idAuto").onclick = function(){
sv.dispose();
if ( options.auto ) {
this.value = "自动展示"; options.auto = false;
} else {
this.value = "取消自动"; options.auto = true;
}
sv = new SlideView( "idSlideView2", options );
}
})()
</script>
<br>
<br>
<style type="text/css">
.sv3 dl, .sv3 dt, .sv3 dd{ padding:0; margin:0; }
.sv3 {
width:200px;
height:250px;
border:1px solid #BFC7D9;
}
.sv3 dl {
width:200px;
height:160px;
background:#EDF5FF;
}
.sv3 dt {
padding:5px 10px;
height:13px;
font-size:13px;
color:#000;
background:#E5ECF9;
border-top:1px solid #fff;
border-bottom:1px solid #BFC7D9;
}
.sv3 dl.on dt {
background:#3366CC;
color:#FFF;
font-weight:bold;
}
.sv3 dd {
padding:10px;
color:#333;
font-size:12px;
line-height:1.5em;
}
.sv3 dd a:link,
.sv3 dd a:visited,
.sv3 dd a:hover,
.sv3 dd a:active { color:#333; display:block; text-align:right;}
</style>
仿口风琴(Accordion)效果:
<div id="idSlideView3" class="sv3">
<dl>
<dt> 图片放大效果 </dt>
<dd> 这个效果也叫放大镜效果,最早好像在ppg出现的,之后就有了很多仿制品出来了。
好处是能在原图附近对图片进行局部放大查看,而且可以通过鼠标控制查看的部位。 <a href="http://www.cnblogs.com/cloudgamer/archive/2010/04/01/ImageZoom.html"> 查看全文 </a> </dd>
</dl>
<dl>
<dt> Lazyload 延迟加载效果 </dt>
<dd> Lazyload是通过延迟加载来实现按需加载,达到节省资源,加快浏览速度的目的。
网上也有不少类似的效果。 <a href="http://www.cnblogs.com/cloudgamer/archive/2010/02/01/LazyLoad.html"> 查看全文 </a> </dd>
</dl>
<dl>
<dt> 图片上传预览效果 </dt>
<dd> 图片上传预览是一种在图片上传之前对图片进行本地预览的技术。
使用户选择图片后能立即查看图片,而不需上传服务器,提高用户体验。 <a href="http://www.cnblogs.com/cloudgamer/archive/2009/12/22/ImagePreview.html"> 查看全文 </a> </dd>
</dl>
<dl>
<dt> Tween算法及缓动效果 </dt>
<dd> Flash做动画时会用到Tween类,利用它可以做很多动画效果,例如缓动、弹簧等等。
我这里要教大家的是怎么利用flash的Tween类的算法,来做js的Tween算法。 <a href="http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html"> 查看全文 </a> </dd>
</dl>
<dl>
<dt> Table行定位效果 </dt>
<dd> 近来有客户要求用table显示一大串数据,由于滚动后就看不到表头,很不方便,所以想到这个效果。 <a href="http://www.cnblogs.com/cloudgamer/archive/2009/05/18/TableFixed.html"> 查看全文 </a> </dd>
</dl>
</div>
<script>
new SlideView( "idSlideView3", { autoClose: false, defaultIndex: 0, min: 25, mode: "top", delay: 200,
onShow: function(index){ this._each(function(o, i){ o.node.className = i == index ? "on" : ""; }) }
});
</script>
</body>
</html>
[/code]
[attach]8944[/attach]
[[I] 本帖最后由 cloudgamer 于 2010-8-4 14:46 编辑 [/I]]
2010-7-29 10:02
cloudgamer
[b]程序说明[/b]
[b]【基本原理】[/b]
通过设置滑动元素的位置坐标(left/right/top/bottom),实现鼠标进入的目标元素滑动展示,其他元素滑动收缩的效果。
难点是如何控制多个滑动元素同时进行不同的滑动,这里关键就在于把整体滑动分解成各个滑动元素进行各自的滑动。
方法是给各个滑动元素设置目标值,然后各自向自己的目标值滑动,当全部都到达目标值就完成了。
[b]【容器设置】[/b]
在_initContainer方法中进行容器设置,由于后面滑动参数的计算要用到容器,所以要先设置容器。
先设置容器样式,要实现滑动需要设置容器相对或绝对定位,并且设置overflow为"hidden"来固定容器大小,而滑动元素也要设置绝对定位。
鼠标移出容器时会触发_LEAVE移出函数:
$$E.addEvent( container, "mouseleave", this._LEAVE );
其中_LEAVE函数是这样的:
var CLOSE = $$F.bind( this.close, this );
this._LEAVE = $$F.bind( function(){
clearTimeout(this._timerDelay);
$$CE.fireEvent( this, "leave" );
if ( this.autoClose ) { this._timerDelay = setTimeout( CLOSE, this.delay ); }
}, this );
当autoClose属性为true时才会延时触发close方法。
[b]【滑动对象】[/b]
程序初始化时会根据滑动元素创建滑动对象集合。
先获取滑动元素:
var nodes = opt.nodes ? $$A.map( opt.nodes, function(n) { return n; } )
: $$A.filter( container.childNodes, function(n) { return n.nodeType == 1; });
如果没有自定义nodes滑动元素,就从容器获取childNodes作为滑动元素。
还要用nodeType筛选一下,因为ie外的浏览器都会把空格作为childNodes的一部分。
接着用获取的滑动元素生成程序需要的_nodes滑动对象集合:
this._nodes = $$A.map( nodes, function(node){ return { "node": node }; });
滑动对象用"node"属性记录滑动元素。
然后在_initNodes方法中初始化滑动对象。
每个滑动对象都有3个用来计算滑动目标值的属性:defaultTarget默认目标值,max展示尺寸,min收缩尺寸。
如果有自定义max尺寸或min尺寸,会根据自定义的尺寸来计算。
程序会优先按max来计算:
max = Math.max( max <= 1 ? max * clientSize : Math.min( max, clientSize ), defaultSize );
min = ( clientSize - max ) / maxIndex;
其中clientSize是容器的可见区域尺寸,defaultSize是平均分配尺寸。
如果max是小数或1就按百分比计算,再把尺寸限制在defaultSize到clientSize的范围内。
再计算减去max后其他收缩元素的平均尺寸,就可以得到min了。
如果没有自定义max再按自定义min来计算:
min = Math.min( min < 1 ? min * clientSize : min, defaultSize );
max = clientSize - maxIndex * min;
同样,如果min是小数就按百分比计算,再做范围限制,然后计算得出max。
最后得到自定义尺寸计算函数:
getMax = function(){ return max; };
getMin = function(){ return min; };
如果没有自定义max或min,就根据元素尺寸来计算:
getMax = function(o){ return Math.max( Math.min( o.node[ offset ], clientSize ), defaultSize ); };
getMin = function(o){ return ( clientSize - o.max ) / maxIndex; };
把元素尺寸作为展示尺寸来计算,同样要做范围限制,然后计算收缩尺寸。
得到尺寸计算函数后,再用_each方法历遍并设置滑动对象:
o.current = o.defaultTarget = getDefaultTarget(i);
o.max = getMax(o); o.min = getMin(o);
其中current是当前坐标值,在移动计算时作为开始值的。
而defaultTarget是默认目标值,即默认状态时移动的目标值,根据defaultSize和索引得到。
还要设置当鼠标进入滑动元素时触发show展示函数:
var node = o.node, SHOW = $$F.bind( this.show, this, i );
o.SHOW = $$F.bind( function(){
clearTimeout(this._timerDelay);
this._timerDelay = setTimeout( SHOW, this.delay );
$$CE.fireEvent( this, "enter", i );
}, this );
$$E.addEvent( node, "mouseenter", o.SHOW );
要在滑动元素的"mouseenter"事件中触发,并传递当前滑动对象的索引,再加上延时设置就可以了。
[b]【滑动展示】[/b]
当鼠标进入其中一个滑动元素,就会触发show方法开始展示。
首先执行_setMove方法设置滑动参数,并以索引作为参数。
在_setMove里面主要是设置计算移动值时需要的目标值、开始值和变化值。
先修正索引,错误的索引值会设置为0:
this._index = index = index < 0 || index > maxIndex ? 0 : index | 0;
再根据索引获取要展示的滑动对象,通过展示对象的min和max得到getTarget目标值函数:
var nodeShow = nodes[ index ], min = nodeShow.min, max = nodeShow.max;
getTarget = function(o, i){ return i <= index ? min * i : min * ( i - 1 ) + max; };
如果滑动对象就是展示对象或者在展示对象前面,目标值就是min * i,因为第i+1个滑动对象的目标值就是i个min的大小。
否则,目标值就是min * ( i - 1 ) + max,其实就是把展示对象的位置换成max。
然后设置每个滑动对象的参数属性:
this._each( function(o, i){
o.target = getTarget(o, i);
o.begin = o.current;
o.change = o.target - o.begin;
});
其中target记录目标值,begin通过current得到开始值,目标值和开始值的差就是change改变值。
设置完成后,就执行_easeMove方法开始滑移,在里面重置_time属性为0,再就执行_move程序就正式开始移动了。
首先判断_time是否到达duration持续时间,没有到达的话,就继续移动。
程序设置了一个_tweenMove移动函数,用来设置缓动:
this._setPos( function(o) {
return Math.round(this.tween( this._time, o.begin, o.change, this.duration ));
});
利用tween算法,结合当前时间,开始值,改变值和持续时间,就能得到当前要移动的坐标值。
ps:关于tween缓动可以参考[url=http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html]tween算法及缓动效果[/url]。
当_time到达duration说明滑动已经完成,再执行一次_targetMove目标值移动函数:
this._setPos( function(o) { return o.target; } );
直接移动到目标值,可以防止可能出现的计算误差导致移位不准确。
[b]【关闭和重置】[/b]
close方法可以关闭展示,即滑动到默认状态,默认在移出容器时就会执行。
默认状态是指全部滑动元素位于defaultTarget默认目标值的状态。
先用_setMove设置移动参数,当_setMove没有索引参数时,就会设置目标值为默认目标值:
getTarget = function(o){ return o.defaultTarget; }
完成参数设置后,再执行_easeMove进行滑动,跟滑动展示类似。
reset方法可以重置展示,重置的意思是不进行滑动而直接移动到目标值。
如果没有索引参数,就会直接执行_defaultMove默认值移动函数:
this._setPos( function(o) { return o.defaultTarget; } );
直接把滑动元素移动到默认状态。
如果有索引参数,就先用_setMove根据索引设置目标值,再执行_targetMove直接移动到目标值。
程序初始化后会执行一次reset,并且以自定义defaultIndex作为参数。
利用defaultIndex可以一开始就展示对应索引的滑动对象。
[b]【方向模式】[/b]
程序可以自定义mode方向模式,有四种方向模式:bottom、top、right、left(默认)。
其中right和left是在水平方向滑动,而bottom和top是在垂直方向滑动。
而right和left的区别是定点方向不同,left以左边为定点在右边滑动,right就相反。
具体参考实例就应该明白了,bottom和top的区别也类似。
程序是通过对不同的方向就修改对应方向的坐标样式来实现的。
例如left模式就用"left"样式来做移动效果,top模式就用"top"样式。
初始化程序中设置的_pos属性就是用来记录当前模式要使用的坐标样式的:
this._pos = /^(bottom|top|right|left)$/.test( opt.mode.toLowerCase() ) ? RegExp.$1 : "left";
然后在_setPos方法中使用_pos指定的坐标样式来设置坐标值:
var pos = this._pos;
this._each( function(o, i) {
o.node.style[ pos ] = (o.current = Math.round(method.call( this, o ))) + "px";
});
而_horizontal属性就记录了是否水平方向滑动,即是否right或left。
在计算尺寸时,通过它来指定使用用水平还是垂直方向的尺寸。
还有一个_reverse属性,判断是否bottom或right模式。
这个属性是为了解决一个问题,例如right模式要实现类似下面的效果:
[img]http://hi.csdn.net/attachment/201007/29/0_1280365961mV7I.gif[/img]
有两种方法,可以调整元素插入顺序:
<div class="container">
<div style="right:0;">2</div>
<div style="right:100px;">1</div>
<div style="right:200px;">0</div>
</div>
但这样需要修改dom结构,或者通过zIndex设置堆叠顺序:
<div class="container">
<div style="right:200px;z-index:3;">0</div>
<div style="right:100px;z-index:2;">1</div>
<div style="right:0;z-index:1;">2</div>
</div>
显然设置zIndex的方法比较好,程序也用了这个方法。
程序就是用_reverse属性来判断是否需要做这些修正。
首先在_initContainer中,根据_reverse重新设置zIndex:
var zIndex = 100, gradient = this._reverse ? -1 : 1;
this._each( function(o){
var style = o.node.style;
style.position = "absolute"; style.zIndex = zIndex += gradient;
});
在_initNodes中,获取默认目标值时也要判断:
getDefaultTarget = this._reverse
? function(i){ return defaultSize * ( maxIndex - i ); }
: function(i){ return defaultSize * i; },
当_reverse为true时,由于定点位置是在索引的反方向,设置元素时也应该倒过来设的,所以要用maxIndex减一下。
在_setMove中,根据索引设置滑动目标值时,也要判断:
if ( this._reverse ) {
var get = getTarget;
index = maxIndex - index;
getTarget = function(o, i){ return get( o, maxIndex - i ); }
}
不但滑动对象集合的索引要修正,展示对象的索引也要修正。
[b]【自动展示扩展】[/b]
这次扩展用的是组合模式,原理参考的[url=http://www.cnblogs.com/cloudgamer/archive/2010/04/14/ImageZoom_ext.html]ImageZoom扩展篇的扩展模式部分[/url]。
不同的是加了一个属性扩展,用来添加扩展方法:
$$.extend( this, prototype );
注意不能添加到SlideView.prototype,这样会影响到SlideView的结构。
“自动展示”要实现的是滑动对象自动轮流展示,并且取消默认状态而实行强制展示,可以用在图片的轮换展示。
原理也很简单,就是每次滑动/移动完成后,用定时器执行下一次滑动就行了。
首先在"init"初始化程序中,增加一个_NEXT程序,用来展示下一个滑动对象:
this._NEXT = $$F.bind( function(){ this.show( this._index + 1 ); }, this );
其实就是把当前索引_index加1之后作为show的参数执行。
再增加一个_autoNext方法:
if ( !this._autoPause ) {
clearTimeout(this._autoTimer);
this._autoTimer = setTimeout( this._NEXT, this.autoDelay );
}
作用是延时执行_NEXT程序,并且有一个_autoPause属性用来锁定执行。
然后设置几个需要执行的地方。
首先在"finish"完成滑动事件中,执行_autoNext方法,这样就实现了基本的自动展示了。
在鼠标进入滑动元素后,应该停止自动切换,所以在"enter"进入滑动元素事件中,会清除定时器并把_autoPause设为true来锁定。
对应地在"leave"鼠标离开容器事件中,要把_autoPause设回false解除锁定,再执行_autoNext方法重新启动自动程序。
并且在"leave"中设置autoClose为false,防止自动恢复默认状态。
最后还要重写reset:
reset.call( this, index == undefined ? this._index : index );
this._autoNext();
重写后的reset会强制设置索引来展示,并执行_autoNext进行下一次滑动。
[b]【提示信息扩展】[/b]
“提示信息”效果是指每个滑动对象对应有一个提示信息(内容)的层(元素)。
这个提示信息会在滑动对象展示时展示,收缩和关闭时关闭。
提示扩展支持四种位置提示:bottom、top、right、left。
在"init"中,根据自定义tipMode获取_tipPos坐标样式:
this._tipPos = /^(bottom|top|right|left)$/.test( this.options.tipPos.toLowerCase() ) ? RegExp.$1 : "bottom";
接着在"initNodes"定义一个能根据滑动元素获取提示元素的函数:
var opt = this.options, tipTag = opt.tipTag, tipClass = opt.tipClass,
re = tipClass && new RegExp("(^|\\s)" + tipClass + "(\\s|$)"),
getTipNode = function(node){
var nodes = node.getElementsByTagName( tipTag );
if ( tipClass ) {
nodes = $$A.filter( nodes, function(n){ return re.test(n.className); } );
}
return nodes[0];
};
如果自定义了tipTag,就会根据标签来获取元素,否则就按默认值"*"获取全部元素。
如果自定义了tipClass,就会再根据className来筛选元素,注意可能包含多个样式,不能直接等于。
得到函数后,再创建提示对象:
this._each( function(o) {
var node = o.node, tipNode = getTipNode(node);
node.style.overflow = "hidden";
tipNode.style.position = "absolute"; tipNode.style.left = 0;
o.tip = {
"node": tipNode,
"show": tipShow != undefined ? tipShow : 0,
"close": tipClose != undefined ? tipClose : -tipNode[offset]
};
});
先获取提示元素,并设置相关样式,再给滑动对象添加一个tip属性,保存对应的提示对象。
其中"node"属性保存提示元素,"show"是展示时的坐标值,"close"是关闭时的坐标值。
如果没有自定义tipShow,默认展示时坐标值是0,即提示元素刚好贴在滑动元素边上的位置;
如果没有自定义tipClose,默认关闭时坐标是提示元素的尺寸,即提示元素刚好隐藏在滑动元素外面的位置。
在"setMove"中设置提示移动目标值:
var maxIndex = this._nodes.length - 1;
this._each( function(o, i) {
var tip = o.tip;
if ( this._reverse ) { i = maxIndex -i; }
tip.target = index == undefined || index != i ? tip.close : tip.show;
tip.begin = tip.current; tip.change = tip.target - tip.begin;
});
这个比滑动对象的设置简单得多,当设置了index参数,并且index等于该滑动对象的索引时才需要展示,其他情况都是隐藏。
要注意,跟滑动对象一样,在_reverse为true的时候需要修正索引。
在"tweenMove"、"targetMove"、"defaultMove"也要设置对应的移动函数。
为了方便样式设置,扩展了一个_setTipPos方法:
var pos = this._tipPos;
this._each( function(o, i) {
var tip = o.tip;
tip.node.style[ pos ] = (tip.current = method.call( this, tip )) + "px";
});
根据_tipPos坐标样式来设置坐标值。
[b]使用技巧[/b]
[b]【展示尺寸】[/b]
要自定义展示尺寸可以通过max和min来设置,可以按像素或百分比来计算。
如果不设置的话,就会按照元素本身的尺寸来展示。
所以滑动元素展示的尺寸并不需要一致的,程序可以自动计算。
[b]【Accordion效果】[/b]
Accordion是可折叠的面板控件,效果类似手风琴,SlideView通过设置也能做到类似的效果。
首先把autoClose设为false取消自动关闭,再设置defaultIndex,使SlideView处于展开状态不会关闭。
一般Accordion都有一个固定尺寸的标题,这个可以用min来设置。
这样就实现了简单的Accordion效果,具体参考第三个实例。
[b]使用说明[/b]
实例化时,必须有容器对象或id作为参数:
new SlideView( "idSlideView" );
可选参数用来设置系统的默认属性,包括:
属性: 默认值//说明
nodes: null,//自定义展示元素集合
mode: "left",//方向
max: 0,//展示尺寸(像素或百分比)
min: 0,//收缩尺寸(像素或百分比)
delay: 100,//触发延时
interval: 20,//滑动间隔
duration: 20,//滑动持续时间
defaultIndex: null,//默认展示索引
autoClose: true,//是否自动恢复
tween: function(t,b,c,d){ return -c * ((t=t/d-1)*t*t*t - 1) + b; },//tween算子
onShow: function(index){},//滑动展示时执行
onClose: function(){}//滑动关闭执行
其中interval、delay、duration、tween、autoClose、onShow、onClose属性可以在程序初始化后动态设置。
还提供了以下方法:
show:根据索引滑动展示;
close:滑动到默认状态;
reset:重置为默认状态或展开索引对应滑动对象;
dispose:销毁程序。
要使用自动展示,只要在SlideView后面加入自动展示扩展程序,并且auto参数设为true即可。
新增如下可选参数:
autoDelay: 2000//展示时间
要使用提示信息,只要加入提示信息扩展程序,并且tip参数设为true即可。
新增如下可选参数:
属性: 默认值//说明
tipPos: "bottom",//提示位置
tipTag: "*",//提示元素标签
tipClass: "",//提示元素样式
tipShow: null,//展示时目标坐标
tipClose: null//关闭时目标坐标
[[I] 本帖最后由 cloudgamer 于 2010-7-30 08:36 编辑 [/I]]