kwicks插件学习

  1 /*
  2     Kwicks for jQuery (version 1.5.1)
  3     Copyright (c) 2008 Jeremy Martin
  4     http://www.jeremymartin.name/projects.php?project=kwicks
  5     
  6     Licensed under the MIT license:
  7         http://www.opensource.org/licenses/mit-license.php
  8 
  9     Any and all use of this script must be accompanied by this copyright/license notice in its present form.
 10 */
 11 
 12 (function($){
 13     $.fn.kwicks = function(options) {
 14         var defaults = {
 15             isVertical: false,
 16             sticky: false,
 17             defaultKwick: 0,
 18             event: 'mouseover',
 19             spacing: 0,
 20             duration: 500
 21         };
 22         var o = $.extend(defaults, options);
 23         var WoH = (o.isVertical ? 'height' : 'width'); // WoH = Width or Height
 24         var LoT = (o.isVertical ? 'top' : 'left'); // LoT = Left or Top
 25         
 26         return this.each(function() {
 27             container = $(this);
 28             var kwicks = container.children('li');
 29             var normWoH = kwicks.eq(0).css(WoH).replace(/px/,''); // normWoH = Normal Width or Height
 30             if(!o.max) {
 31                 o.max = (normWoH * kwicks.size()) - (o.min * (kwicks.size() - 1));
 32             } else {
 33                 o.min = ((normWoH * kwicks.size()) - o.max) / (kwicks.size() - 1);
 34             }
 35             // set width of container ul
 36             if(o.isVertical) {
 37                 container.css({
 38                     width : kwicks.eq(0).css('width'),
 39                     height : (normWoH * kwicks.size()) + (o.spacing * (kwicks.size() - 1)) + 'px'
 40                 });                
 41             } else {
 42                 container.css({
 43                     width : (normWoH * kwicks.size()) + (o.spacing * (kwicks.size() - 1)) + 'px',
 44                     height : kwicks.eq(0).css('height')
 45                 });                
 46             }
 47 
 48             // pre calculate left or top values for all kwicks but the first and last
 49             // i = index of currently hovered kwick, j = index of kwick we're calculating
 50             var preCalcLoTs = []; // preCalcLoTs = pre-calculated Left or Top's
 51             for(i = 0; i < kwicks.size(); i++) {
 52                 preCalcLoTs[i] = [];
 53                 // don't need to calculate values for first or last kwick
 54                 for(j = 1; j < kwicks.size() - 1; j++) {
 55                     if(i == j) {
 56                         preCalcLoTs[i][j] = o.isVertical ? j * o.min + (j * o.spacing) : j * o.min + (j * o.spacing);
 57                     } else {
 58                         preCalcLoTs[i][j] = (j <= i ? (j * o.min) : (j-1) * o.min + o.max) + (j * o.spacing);
 59                     }
 60                 }
 61             }
 62             
 63             // loop through all kwick elements
 64             kwicks.each(function(i) {
 65                 var kwick = $(this);
 66                 // set initial width or height and left or top values
 67                 // set first kwick
 68                 if(i === 0) {
 69                     kwick.css(LoT, '0px');
 70                 } 
 71                 // set last kwick
 72                 else if(i == kwicks.size() - 1) {
 73                     kwick.css(o.isVertical ? 'bottom' : 'right', '0px');
 74                 }
 75                 // set all other kwicks
 76                 else {
 77                     if(o.sticky) {
 78                         kwick.css(LoT, preCalcLoTs[o.defaultKwick][i]);
 79                     } else {
 80                         kwick.css(LoT, (i * normWoH) + (i * o.spacing));
 81                     }
 82                 }
 83                 // correct size in sticky mode
 84                 if(o.sticky) {
 85                     if(o.defaultKwick == i) {
 86                         kwick.css(WoH, o.max + 'px');
 87                         kwick.addClass('active');
 88                     } else {
 89                         kwick.css(WoH, o.min + 'px');
 90                     }
 91                 }
 92                 kwick.css({
 93                     margin: 0,
 94                     position: 'absolute'
 95                 });
 96                 
 97                 kwick.bind(o.event, function() {
 98                     // calculate previous width or heights and left or top values
 99                     var prevWoHs = []; // prevWoHs = previous Widths or Heights
100                     var prevLoTs = []; // prevLoTs = previous Left or Tops
101                     kwicks.stop().removeClass('active');
102                     for(j = 0; j < kwicks.size(); j++) {
103                         prevWoHs[j] = kwicks.eq(j).css(WoH).replace(/px/, '');
104                         prevLoTs[j] = kwicks.eq(j).css(LoT).replace(/px/, '');
105                     }
106                     var aniObj = {};
107                     aniObj[WoH] = o.max;
108                     var maxDif = o.max - prevWoHs[i];
109                     var prevWoHsMaxDifRatio = prevWoHs[i]/maxDif;
110                     kwick.addClass('active').animate(aniObj, {
111                         step: function(now) {
112                             // calculate animation completeness as percentage
113                             var percentage = maxDif != 0 ? now/maxDif - prevWoHsMaxDifRatio : 1;
114                             // adjsut other elements based on percentage
115                             kwicks.each(function(j) {
116                                 if(j != i) {
117                                     kwicks.eq(j).css(WoH, prevWoHs[j] - ((prevWoHs[j] - o.min) * percentage) + 'px');
118                                 }
119                                 if(j > 0 && j < kwicks.size() - 1) { // if not the first or last kwick
120                                     kwicks.eq(j).css(LoT, prevLoTs[j] - ((prevLoTs[j] - preCalcLoTs[i][j]) * percentage) + 'px');
121                                 }
122                             });
123                         },
124                         duration: o.duration,
125                         easing: o.easing
126                     });
127                 });
128             });
129             if(!o.sticky) {
130                 container.bind("mouseleave", function() {
131                     var prevWoHs = [];
132                     var prevLoTs = [];
133                     kwicks.removeClass('active').stop();
134                     for(i = 0; i < kwicks.size(); i++) {
135                         prevWoHs[i] = kwicks.eq(i).css(WoH).replace(/px/, '');
136                         prevLoTs[i] = kwicks.eq(i).css(LoT).replace(/px/, '');
137                     }
138                     var aniObj = {};
139                     aniObj[WoH] = normWoH;
140                     var normDif = normWoH - prevWoHs[0];
141                     kwicks.eq(0).animate(aniObj, {
142                         step: function(now) {
143                             var percentage = normDif != 0 ? (now - prevWoHs[0])/normDif : 1;
144                             for(i = 1; i < kwicks.size(); i++) {
145                                 kwicks.eq(i).css(WoH, prevWoHs[i] - ((prevWoHs[i] - normWoH) * percentage) + 'px');
146                                 if(i < kwicks.size() - 1) {
147                                     kwicks.eq(i).css(LoT, prevLoTs[i] - ((prevLoTs[i] - ((i * normWoH) + (i * o.spacing))) * percentage) + 'px');
148                                 }
149                             }
150                         },
151                         duration: o.duration,
152                         easing: o.easing
153                     });
154                 });
155             }
156         });
157     };
158 })(jQuery);

 学习心得:1,jQuery(funtion(){});用于存放DOM对象的代码,执行其中代码时DOM对象已经存在。 不可用于存放开发插件代码。因为jQuery对象没有得到传递,外部通过jQuery.methodye 调用不来其中方法。 (funtion(){ }(jQuery);用于存放开发插件的代码,执行其中代码DOM不一定存在,直接自动执行DOM操作代码请小心使用;

2:$.fx是指jquery的特效。 如果使用显示、滑动、淡入淡出、动画等。 $.fx.off可以关闭动画,其实是直接显示结果.jQuery为开发插件提拱了两个方法,分别是:jQuery.fn.extend(object);jQuery.extend(object);jQuery.extend(object); 为扩展jQuery类本身.为类添加新的方法。jQuery.fn.extend(object);给jQuery对象添加方法。

3:$.extend()的用法;http://www.cnblogs.com/RascallySnake/archive/2010/05/07/1729563.html

4:其实这个效果Css用浮动也能实现,但是那样 元素的晃动太强,所以改成了全部绝对定位实现,第一个设置LEFT 最后一个设置right,虽然最后一个元素会有瑕疵 但比一个效果好,.replace(/px/,'')可以去掉PX;

5 设置每个元素的大小,计算出总长度,然后根据最大值 设置最小值 或者相反;

6声明一个数组 来存放每点击一个元素时其余的兄弟元素的LEFT, 分为两种情况一是兄弟元素在他前面 (包括他自己)二是在他后面 ,前面的话left就是个数乘以最小值,后面就是 个数减一乘以最小值加一个最大值,

7给每个元素添加一个事件,当事件开始时,用for记录它的所有兄弟元素的当前宽和left,用animate 把元素移动到最大值 ,用SETP属性规定动画的每一步完成之后要执行的函数(

.animate({},{setp:duration: o.duration,easing: o.easing})) SETP函数里设置一个循环,来为每一个兄弟元素设置样式,一个设置宽 排除掉当然元素if(j != i);一个设置left 排除 第一个和最后一个if(j > 0 && j < kwicks.size() - 1),

8:重点是所有动画都同步 所以要计算出 频率,先计算出当前元素到最大元素的距离,

 o.max - prevWoHs[i];,然后计算出动画进行时的滑动量 now-prevWoHs[i]; 然后用前者除以后者就是频率 ,每一个同辈元素要移动的量乘以频率就是实时的移动量  用原先的量减去这个就是 同辈元素实时的宽度, left类似,

9:最后设置离开时的事件,第一个元素用animate,其他用step同频率改变宽高,这是的目标宽度 是元素的初始宽度width ,left也是。i*weidht。

 

posted @ 2013-08-27 09:37  鲤鱼在睡觉  阅读(536)  评论(0编辑  收藏  举报