Skip to content

Commit 2c789ec

Browse files
committed
src : add proper callback triggering
for #6 test : add callback test v1.5.0 beta
1 parent 2deee26 commit 2c789ec

File tree

2 files changed

+252
-28
lines changed

2 files changed

+252
-28
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
---
2+
title: Callbacks
3+
layout: default
4+
category: tests
5+
---
6+
7+
<section id="copy">
8+
<p>Tests that callbacks are triggering properly, after animation/transition has completed.</p>
9+
10+
</section>
11+
12+
<section id="options" class="clearfix">
13+
14+
{% include filter-buttons.html %}
15+
16+
{% include sort-buttons.html %}
17+
18+
<h3>Etc</h3>
19+
20+
<ul id="etc" class="clearfix">
21+
<li id="toggle-sizes"><a href="#toggle-sizes">Toggle variable sizes</a></li>
22+
<li id="insert"><a href="#insert">Insert new elements</a></li>
23+
<li id="append"><a href='#append'>Append new elements</a></li>
24+
<li id="shuffle"><a href='#shuffle'>Shuffle</a></li>
25+
</ul>
26+
27+
</section> <!-- #options -->
28+
29+
<div id="container" class="clickable variable-sizes clearfix">
30+
{% for elem_number in site.best_of_order %}
31+
{% assign element = site.elements[elem_number] %}
32+
{% include element-partial.html %}
33+
{% endfor %}
34+
</div> <!-- #container -->
35+
36+
37+
<script src="../{{ site.jquery_js }}"></script>
38+
<script src="../{{ site.isotope_js }}"></script>
39+
<script src="../js/fake-element.js"></script>
40+
<script>
41+
42+
$(function(){
43+
44+
var $container = $('#container');
45+
46+
{% include random-sizes.js %}
47+
48+
var colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'white'],
49+
colorI = 0;
50+
51+
function changeBGColor() {
52+
var color = colors[ colorI % colors.length ];
53+
$container.css({ background: color })
54+
colorI++;
55+
}
56+
57+
$container.isotope({
58+
itemSelector : '.element',
59+
masonry : {
60+
columnWidth : 120
61+
},
62+
masonryHorizontal : {
63+
rowHeight: 120
64+
},
65+
cellsByRow : {
66+
columnWidth : 240,
67+
rowHeight : 240
68+
},
69+
cellsByColumn : {
70+
columnWidth : 240,
71+
rowHeight : 240
72+
},
73+
getSortData : {
74+
symbol : function( $elem ) {
75+
return $elem.attr('data-symbol');
76+
},
77+
category : function( $elem ) {
78+
return $elem.attr('data-category');
79+
},
80+
number : function( $elem ) {
81+
return parseInt( $elem.find('.number').text(), 10 );
82+
},
83+
weight : function( $elem ) {
84+
return parseFloat( $elem.find('.weight').text().replace( /[\(\)]/g, '') );
85+
},
86+
name : function ( $elem ) {
87+
return $elem.find('.name').text();
88+
}
89+
}
90+
}, changeBGColor );
91+
92+
93+
var $optionSets = $('#options .option-set'),
94+
$optionLinks = $optionSets.find('a');
95+
96+
$optionLinks.click(function(){
97+
var $this = $(this);
98+
// don't proceed if already selected
99+
if ( $this.hasClass('selected') ) {
100+
return false;
101+
}
102+
var $optionSet = $this.parents('.option-set');
103+
$optionSet.find('.selected').removeClass('selected');
104+
$this.addClass('selected');
105+
106+
// make option object dynamically, i.e. { filter: '.my-filter-class' }
107+
var options = {},
108+
key = $optionSet.attr('data-option-key'),
109+
value = $this.attr('data-option-value');
110+
// parse 'false' as false boolean
111+
value = value === 'false' ? false : value;
112+
options[ key ] = value;
113+
if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
114+
// changes in layout modes need extra logic
115+
changeLayoutMode( $this, options )
116+
} else {
117+
// otherwise, apply new options
118+
$container.isotope( options, changeBGColor );
119+
}
120+
121+
return false;
122+
});
123+
124+
125+
126+
$('#insert a').click(function(){
127+
var $newEls = $( fakeElement.getGroup() );
128+
$container.isotope( 'insert', $newEls, changeBGColor );
129+
130+
return false;
131+
});
132+
133+
$('#append a').click(function(){
134+
var $newEls = $( fakeElement.getGroup() );
135+
$container.append( $newEls ).isotope( 'appended', $newEls, changeBGColor );
136+
137+
return false;
138+
});
139+
140+
141+
// change size of clicked element
142+
$container.delegate( '.element', 'click', function(){
143+
$(this).toggleClass('large');
144+
$container.isotope('reLayout');
145+
});
146+
147+
// toggle variable sizes of all elements
148+
$('#toggle-sizes').find('a').click(function(){
149+
$container
150+
.toggleClass('variable-sizes')
151+
.isotope('reLayout');
152+
return false;
153+
});
154+
155+
156+
var $sortBy = $('#sort-by');
157+
$('#shuffle a').click(function(){
158+
$container.isotope('shuffle');
159+
$sortBy.find('.selected').removeClass('selected');
160+
$sortBy.find('[data-option-value="random"]').addClass('selected');
161+
return false;
162+
});
163+
164+
});
165+
</script>

jquery.isotope.js

Lines changed: 87 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Isotope v1.4.110906
2+
* Isotope v1.5.0 beta
33
* An exquisite jQuery plugin for magical layouts
44
* http://isotope.metafizzy.co
55
*
@@ -45,7 +45,9 @@
4545
}
4646
}
4747

48-
var transformProp = getStyleProperty('transform');
48+
var transformProp = getStyleProperty('transform'),
49+
transitionProp = getStyleProperty('transitionProperty');
50+
4951

5052
// ========================= miniModernizr ===============================
5153
// <3<3<3 and thanks to Faruk and Paul for doing the heavy lifting
@@ -92,7 +94,7 @@
9294
},
9395

9496
csstransitions: function() {
95-
return !!getStyleProperty('transitionProperty');
97+
return !!transitionProp;
9698
}
9799
};
98100

@@ -247,8 +249,20 @@
247249
};
248250

249251
}
252+
253+
// ========================= get transition-end event ===============================
254+
255+
if ( Modernizr.csstransitions ) {
256+
var transitionEndEvent = {
257+
WebkitTransitionProperty: 'webkitTransitionEnd', // webkit
258+
MozTransitionProperty: 'transitionend',
259+
OTransitionProperty: 'oTransitionEnd',
260+
transitionProperty: 'transitionEnd'
261+
}[ transitionProp ];
262+
var transitionDurProp = getStyleProperty('transitionDuration');
263+
}
250264

251-
265+
// ========================= smartresize ===============================
252266

253267
/*
254268
* smartresize: debounced resize event for jQuery
@@ -295,11 +309,11 @@
295309

296310

297311
// our "Widget" object constructor
298-
$.Isotope = function( options, element ){
312+
$.Isotope = function( options, element, callback ){
299313
this.element = $( element );
300314

301315
this._create( options );
302-
this._init();
316+
this._init( callback );
303317
};
304318

305319
// styles of container element we want to keep track of
@@ -423,7 +437,6 @@
423437

424438
this.$filteredAtoms = this._filter( this.$allAtoms );
425439
this._sort();
426-
427440
this.reLayout( callback );
428441

429442
},
@@ -588,31 +601,80 @@
588601
this.styleQueue.push({ $el: this.element, style: containerStyle });
589602
}
590603

591-
this._processStyleQueue();
592-
593-
// provide $elems as context for the callback
594-
if ( callback ) {
595-
callback.call( $elems );
596-
}
604+
this._processStyleQueue( $elems, callback );
597605

598606
this.isLaidOut = true;
599607
},
600608

601-
_processStyleQueue : function() {
609+
_processStyleQueue : function( $elems, callback ) {
602610
// are we animating the layout arrangement?
603611
// use plugin-ish syntax for css or animate
604612
var styleFn = !this.isLaidOut ? 'css' : (
605613
this.isUsingJQueryAnimation ? 'animate' : 'css'
606614
),
607615
animOpts = this.options.animationOptions,
608616
_isInsertingAnimated = this._isInserting && this.isUsingJQueryAnimation,
609-
objStyleFn;
610-
617+
objStyleFn, processor,
618+
triggerCallbackNow, callbackFn;
619+
620+
// default styleQueue processor, may be overwritten down below
621+
processor = function( i, obj ) {
622+
obj.$el[ styleFn ]( obj.style, animOpts );
623+
};
624+
625+
if ( this._isInserting || !callback ) {
626+
// process styleQueue
627+
processor = function( i, obj ) {
628+
// only animate if it not being inserted
629+
objStyleFn = _isInsertingAnimated && obj.$el.hasClass('no-transition') ? 'css' : styleFn;
630+
obj.$el[ objStyleFn ]( obj.style, animOpts );
631+
};
632+
633+
} else {
634+
var isCallbackTriggered = false;
635+
callbackFn = function() {
636+
// trigger callback only once
637+
if ( isCallbackTriggered ) {
638+
return;
639+
}
640+
callback( $elems );
641+
isCallbackTriggered = true;
642+
};
643+
644+
if ( this.isUsingJQueryAnimation ) {
645+
// add callback to animation options
646+
animOpts.complete = callbackFn;
647+
} else if ( Modernizr.csstransitions ) {
648+
// detect if first item has transition
649+
var i = 0,
650+
testElem = this.styleQueue[0].$el;
651+
// get first non-empty jQ object
652+
// console.log( this.styleQueue )
653+
if ( !testElem.length ) {
654+
return;
655+
}
656+
// get transition duration of the first element in that object
657+
// yeah, this is inexact
658+
var duration = parseFloat( getComputedStyle( testElem[0] )[ transitionDurProp ] );
659+
if ( duration > 0 ) {
660+
processor = function( i, obj ) {
661+
obj.$el[ styleFn ]( obj.style, animOpts )
662+
// trigger callback at transition end
663+
.one( transitionEndEvent, callbackFn );
664+
}
665+
} else {
666+
// no transition? hit it now, son
667+
triggerCallbackNow = true;
668+
}
669+
}
670+
}
671+
611672
// process styleQueue
612-
$.each( this.styleQueue, function( i, obj ) {
613-
objStyleFn = _isInsertingAnimated && obj.$el.hasClass('no-transition') ? 'css' : styleFn;
614-
obj.$el[ objStyleFn ]( obj.style, animOpts );
615-
});
673+
$.each( this.styleQueue, processor );
674+
675+
if ( triggerCallbackNow ) {
676+
callbackFn()
677+
}
616678

617679
// clear out queue for next time
618680
this.styleQueue = [];
@@ -695,11 +757,8 @@
695757
$newAtoms.removeClass('no-transition');
696758
// reveal newly inserted filtered elements
697759
instance.styleQueue.push({ $el: $newAtoms, style: instance.options.visibleStyle });
698-
instance._processStyleQueue();
699-
delete instance._isInserting;
700-
if ( callback ) {
701-
callback( $newAtoms );
702-
}
760+
instance._isInserting = false;
761+
instance._processStyleQueue( $newAtoms, callback );
703762
}, 10 );
704763
},
705764

@@ -1246,7 +1305,7 @@
12461305
// A bit from jcarousel
12471306
// https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js
12481307

1249-
$.fn.isotope = function( options ) {
1308+
$.fn.isotope = function( options, callback ) {
12501309
if ( typeof options === 'string' ) {
12511310
// call method
12521311
var args = Array.prototype.slice.call( arguments, 1 );
@@ -1271,10 +1330,10 @@
12711330
if ( instance ) {
12721331
// apply options & init
12731332
instance.option( options );
1274-
instance._init();
1333+
instance._init( callback );
12751334
} else {
12761335
// initialize new instance
1277-
$.data( this, 'isotope', new $.Isotope( options, this ) );
1336+
$.data( this, 'isotope', new $.Isotope( options, this, callback ) );
12781337
}
12791338
});
12801339
}

0 commit comments

Comments
 (0)