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。