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()的用法;
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。