|
1 | 1 | /*
|
2 |
| - * Moving Boxes v2.2.2 |
| 2 | + * Moving Boxes v2.2.3 |
3 | 3 | * by Chris Coyier
|
4 | 4 | * http://css-tricks.com/moving-boxes/
|
5 | 5 | */
|
|
35 | 35 |
|
36 | 36 | base.initialized = false;
|
37 | 37 | base.currentlyMoving = false;
|
38 |
| - base.curPanel = 1; |
| 38 | + base.curPanel = (o.initAnimation) ? 1 : (o.hashTags) ? base.getHash() || o.startPanel : o.startPanel; |
39 | 39 |
|
40 |
| - // make backwards compatible - width & panelWidth deprecated in 2.2.2 |
41 |
| - if (!o.width) { o.width = base.$el.width(); } |
42 |
| - if (!o.panelWidth) { |
43 |
| - o.panelWidth = base.$panels.eq(0).width(); |
44 |
| - } else { |
45 |
| - o.panelWidth = o.width * o.panelWidth; // change panelWidth (deprecation option) fraction into a px width |
46 |
| - } |
| 40 | + // save original slider width |
| 41 | + base.width = (o.width) ? parseInt(o.width,10) : base.$el.width(); |
| 42 | + // save panel width, o.panelWidth originally a fraction (0.5 of o.width) if defined, or get first panel width |
| 43 | + // now can be set after initialization to resize using fraction (value <= 2) or px (all values > 2) |
| 44 | + base.pWidth = (o.panelWidth) ? (o.panelWidth <=2 ? o.panelWidth * base.width : o.panelWidth) : base.$panels.eq(0).width(); |
47 | 45 |
|
48 | 46 | // Set up click on left/right arrows
|
49 | 47 | base.$left = base.$wrap.find('.mb-left').click(function(){
|
|
56 | 54 | });
|
57 | 55 |
|
58 | 56 | // code to run to update MovingBoxes when the number of panels change
|
59 |
| - base.update(); |
60 |
| - $(window).load(function(){ base.update(false); }); // animate height after all images load |
| 57 | + base.update(false); |
| 58 | + $(window).load(function(){ // animate height after all images load |
| 59 | + base.update(false); |
| 60 | + |
| 61 | + // Set up "Current" panel |
| 62 | + var startPanel = (o.hashTags) ? base.getHash() || o.startPanel : o.startPanel; |
| 63 | + // animate to chosen start panel - starting from the first panel makes it look better |
| 64 | + setTimeout(function(){ |
| 65 | + base.change(startPanel, function(){ |
| 66 | + base.initialized = true; |
| 67 | + base.$el.trigger( 'initialized.movingBoxes', [ base, startPanel ] ); |
| 68 | + }, false); |
| 69 | + }, o.speed * 2 ); |
| 70 | + |
| 71 | + }); |
61 | 72 |
|
62 | 73 | // go to clicked panel
|
63 |
| - base.$el.delegate('.mb-panel', 'click', function(){ |
64 |
| - base.change( base.$panels.index($(this)) + base.adj ); |
| 74 | + base.$el.delegate('.mb-panel', 'click', function(e){ |
| 75 | + if (!$(this).hasClass(o.currentPanel)) { |
| 76 | + e.preventDefault(); // prevent non-current panel links from working |
| 77 | + base.change( base.$panels.index($(this)) + base.adj ); |
| 78 | + } |
65 | 79 | });
|
66 | 80 |
|
67 | 81 | // Activate moving box on click or when an internal link obtains focus
|
|
70 | 84 | });
|
71 | 85 | base.$panels.delegate('a', 'focus' ,function(){
|
72 | 86 | // focused link centered in moving box
|
73 |
| - var loc = base.$panels.index($(this).closest('.mb-panel')) + 1; |
74 |
| - if (loc !== base.curPanel){ base.change( base.$panels.index($(this).closest('.mb-panel')) + 1, {}, false ); } |
| 87 | + var loc = base.$panels.index($(this).closest('.mb-panel')) + base.adj; |
| 88 | + if (loc !== base.curPanel){ |
| 89 | + base.change( base.$panels.index($(this).closest('.mb-panel')) + base.adj, {}, false ); |
| 90 | + } |
75 | 91 | });
|
76 | 92 |
|
77 | 93 | // Add keyboard navigation
|
|
92 | 108 | }
|
93 | 109 | });
|
94 | 110 |
|
95 |
| - // Set up "Current" panel |
96 |
| - var startPanel = (o.hashTags) ? base.getHash() || o.startPanel : o.startPanel; |
97 |
| - |
98 | 111 | // Bind Events
|
99 | 112 | $.each('initialized initChange beforeAnimation completed'.split(' '), function(i,evt){
|
100 | 113 | if ($.isFunction(o[evt])){
|
101 | 114 | base.$el.bind(evt + '.movingBoxes', o[evt]);
|
102 | 115 | }
|
103 | 116 | });
|
104 | 117 |
|
105 |
| - // animate to chosen start panel - starting from the first panel makes it look better |
106 |
| - setTimeout(function(){ |
107 |
| - base.change(startPanel, function(){ |
108 |
| - base.initialized = true; |
109 |
| - base.$el.trigger( 'initialized.movingBoxes', [ base, startPanel ] ); |
110 |
| - }, false); |
111 |
| - }, o.speed * 2 ); |
112 |
| - |
113 | 118 | };
|
114 | 119 |
|
115 | 120 | // update the panel, flag is used to prevent events from firing
|
116 |
| - base.update = function(flag){ |
117 |
| - var t; |
| 121 | + base.update = function(flag, callback){ |
118 | 122 |
|
119 | 123 | // Infinite loop
|
120 | 124 | base.$el.children('.cloned').remove();
|
121 | 125 | base.$panels = base.$el.children();
|
122 | 126 | base.adj = (o.wrap && base.$panels.length > 1) ? 0 : 1; // count adjustment for infinite panels
|
123 | 127 |
|
124 |
| - base.$wrap.css('width', o.width); // set wrapper width |
| 128 | + base.width = (o.width) ? parseInt(o.width,10) : base.width; |
| 129 | + base.$wrap.css('width', base.width); // set wrapper width |
125 | 130 |
|
126 | 131 | if (o.wrap && base.$panels.length > 1) {
|
127 | 132 | base.$el.prepend( base.$panels.filter(':last').clone().addClass('cloned') );
|
|
137 | 142 | // defined $panels again to include cloned panels
|
138 | 143 | base.$panels = base.$el.children()
|
139 | 144 | .addClass('mb-panel')
|
140 |
| - .css({ width : o.panelWidth, margin: 0 }) |
| 145 | + .css('margin',0) |
141 | 146 | // inner wrap of each panel
|
142 | 147 | .each(function(){
|
143 | 148 | if ($(this).find('.mb-inside').length === 0) {
|
|
147 | 152 | base.totalPanels = base.$panels.filter(':not(.cloned)').length; // don't include cloned panels in total
|
148 | 153 |
|
149 | 154 | // save 'cur' numbers (current larger panel size), use stored sizes if they exist
|
150 |
| - t = base.$panels.eq(base.curPanel - base.adj); |
151 |
| - base.curWidth = t.width(); |
152 |
| - if (!o.panelWidth) { o.panelWidth = base.curWidth; } |
| 155 | + base.curWidth = (o.panelWidth) ? (o.panelWidth <=2 ? o.panelWidth * base.width : o.panelWidth) : base.pWidth; |
153 | 156 |
|
154 | 157 | // save 'reg' (reduced size) numbers
|
155 | 158 | base.regWidth = base.curWidth * o.reducedSize;
|
|
170 | 173 | base.$el.css({
|
171 | 174 | position : 'absolute',
|
172 | 175 | // add a bit more width to each box (100px should cover margin/padding, etc; then add 1/2 overall width in case only one panel exists
|
173 |
| - width : (base.curWidth + 100) * base.$panels.length + (o.width - base.curWidth) / 2, |
| 176 | + width : (base.curWidth + 100) * base.$panels.length + (base.width - base.curWidth) / 2, |
174 | 177 | height : Math.max.apply( this, base.heights ) + 10
|
175 | 178 | });
|
176 | 179 | base.$window.css({ height : (o.fixedHeight) ? Math.max.apply( this, base.heights ) : base.heights[base.curPanel - base.adj] });
|
177 | 180 | // add padding so scrollLeft = 0 centers the left-most panel (needed because scrollLeft cannot be < 0)
|
178 |
| - base.$panels.eq(0).css({ 'margin-left' : (o.width - base.curWidth) / 2 }); |
| 181 | + base.$panels.eq(0).css({ 'margin-left' : (base.width - base.curWidth) / 2 }); |
179 | 182 |
|
180 | 183 | base.buildNav();
|
181 | 184 |
|
182 |
| - base.change(base.curPanel, null, true); // initialize from first panel... then scroll to start panel |
| 185 | + base.change(base.curPanel, callback, (flag === false) ? false : true); // initialize from first panel... then scroll to start panel |
183 | 186 |
|
184 | 187 | };
|
185 | 188 |
|
|
229 | 232 | var panels = base.$panels.eq(num - base.adj);
|
230 | 233 | if (o.reducedSize === 1) {
|
231 | 234 | panels.css({ width: base.curWidth }); // excluding fontsize change to prevent video flicker
|
232 |
| - if (base.initialized) { base.completed(num, flag); } |
| 235 | + base.completed(num, flag); |
233 | 236 | } else {
|
234 | 237 | panels.animate({ width: base.curWidth, fontSize: '1em' }, (time === 0) ? 0 : o.speed, function(){
|
235 | 238 | // completed event trigger
|
236 | 239 | // even though animation is not queued, trigger is here because it is the last animation to complete
|
237 |
| - if (base.initialized) { base.completed(num, flag); } |
| 240 | + base.completed(num, flag); |
238 | 241 | });
|
239 | 242 | }
|
240 | 243 | };
|
|
265 | 268 | return;
|
266 | 269 | }
|
267 | 270 | var ani, leftValue, wrapped = false;
|
| 271 | + flag = flag !== false; |
268 | 272 |
|
269 | 273 | // make sure it's a number and not a string
|
270 | 274 | curPanel = parseInt(curPanel, 10);
|
271 | 275 |
|
272 |
| - if (base.initialized) { |
| 276 | + if (base.initialized && flag) { |
273 | 277 | // make this moving box active
|
274 | 278 | base.active();
|
275 | 279 | // initChange event - has extra parameter with targeted panel (not cleaned)
|
|
283 | 287 | curPanel = 1;
|
284 | 288 | base.returnToNormal(0, 0);
|
285 | 289 | base.growBigger(0, 0, false);
|
286 |
| - leftValue = base.$panels.eq(0).position().left - (o.width - base.curWidth) / 2; // - ( base.curWidth - base.regWidth ); |
| 290 | + leftValue = base.$panels.eq(0).position().left - (base.width - base.curWidth) / 2; // - ( base.curWidth - base.regWidth ); |
287 | 291 | base.$window.scrollLeft(leftValue);
|
288 | 292 | } else if (curPanel === 0) {
|
289 | 293 | wrapped = false;
|
290 | 294 | curPanel = base.totalPanels;
|
| 295 | + base.returnToNormal(curPanel + 1, 0); |
291 | 296 | base.growBigger(curPanel + 1, 0, false);
|
292 |
| - leftValue = base.$panels.eq(curPanel + 1).position().left - (o.width - base.curWidth) / 2; // - ( base.curWidth - base.regWidth ); |
| 297 | + leftValue = base.$panels.eq(curPanel + 1).position().left - (base.width - base.curWidth) / 2; // - ( base.curWidth - base.regWidth ); |
293 | 298 | base.$window.scrollLeft(leftValue);
|
294 | 299 | }
|
295 | 300 | }
|
296 | 301 |
|
297 | 302 | if ( curPanel < base.adj ) { curPanel = (o.wrap) ? base.totalPanels : 1; }
|
298 | 303 | if ( curPanel > base.totalPanels - base.adj ) { curPanel = (o.wrap) ? 1 : base.totalPanels; }
|
299 | 304 |
|
300 |
| - // don't do anything if it's the same panel |
301 |
| - if (base.initialized && base.curPanel === curPanel && !flag) { return false; } |
302 |
| - |
303 | 305 | // abort if panel is already animating
|
304 | 306 | // animation callback to clear this flag is not called when the slider doesn't move, so include base.initialized
|
305 | 307 | if (!base.currentlyMoving || !base.initialized) {
|
306 | 308 | base.currentlyMoving = true;
|
307 | 309 |
|
308 | 310 | // center panel in scroll window
|
309 | 311 | base.$curPanel = base.$panels.eq(curPanel - base.adj);
|
310 |
| - leftValue = base.$curPanel.position().left - (o.width - base.curWidth) / 2; |
| 312 | + leftValue = base.$curPanel.position().left - (base.width - base.curWidth) / 2; |
311 | 313 |
|
312 | 314 | // when scrolling right, add the difference of the larger current panel width
|
313 | 315 | if (curPanel > base.curPanel || wrapped) { leftValue -= ( base.curWidth - base.regWidth ); }
|
314 | 316 | ani = (o.fixedHeight) ? { scrollLeft : leftValue } : { scrollLeft: leftValue, height: base.heights[curPanel - base.adj] };
|
315 | 317 |
|
316 | 318 | base.curPanel = curPanel;
|
317 |
| - |
318 | 319 | // before animation trigger
|
319 |
| - if (base.initialized) { base.$el.trigger( 'beforeAnimation.movingBoxes', [ base, curPanel ] ); } |
| 320 | + if (base.initialized && flag) { base.$el.trigger( 'beforeAnimation.movingBoxes', [ base, curPanel ] ); } |
320 | 321 | // animate the panels
|
321 | 322 | base.$window.animate( ani,
|
322 | 323 | {
|
|
341 | 342 | }
|
342 | 343 |
|
343 | 344 | // Update navigation links
|
344 |
| - if (o.buildNav && base.$nav) { |
| 345 | + if (o.buildNav && base.$nav.length) { |
345 | 346 | base.$nav.find('a')
|
346 | 347 | .removeClass(o.currentPanel)
|
347 | 348 | .eq(curPanel - 1).addClass(o.currentPanel);
|
|
398 | 399 |
|
399 | 400 | // Behaviour
|
400 | 401 | speed : 500, // animation time in milliseconds
|
| 402 | + initAnimation: true, // if true, movingBoxes will initialize, then animate into the starting slide (if not the first slide) |
401 | 403 | hashTags : true, // if true, hash tags are enabled
|
402 | 404 | wrap : false, // if true, the panel will "wrap" (it really rewinds/fast forwards) at the ends
|
403 | 405 | buildNav : false, // if true, navigation links will be added
|
|
0 commit comments