Shuffle emits an event when a layout happens and when elements are removed. The event names are Shuffle.EventType.LAYOUT and Shuffle.EventType.REMOVED.
+
Shuffle uses the global CustomEvent to create events. A polyfill for IE<=11 is bundled with Shuffle.
// Overrideable options
Shuffle.options = {
- group: ALL_ITEMS, // Initial filter group.
+ group: Shuffle.ALL_ITEMS, // Initial filter group.
speed: 250, // Transition/animation speed (milliseconds).
- easing: 'ease-out', // CSS easing function to use.
- itemSelector: '', // e.g. '.picture-item'.
- sizer: null, // Sizer element. Use an element to determine the size of columns and gutters.
+ easing: 'ease', // CSS easing function to use.
+ itemSelector: '*', // e.g. '.picture-item'.
+ sizer: null, // Element or selector string. Use an element to determine the size of columns and gutters.
gutterWidth: 0, // A static number or function that tells the plugin how wide the gutters between columns are (in pixels).
columnWidth: 0, // A static number or function that returns a number which tells the plugin how wide the columns are (in pixels).
delimeter: null, // If your group is not json, and is comma delimeted, you could set delimeter to ','.
buffer: 0, // Useful for percentage based heights when they might not always be exactly the same (in pixels).
- columnThreshold: HAS_COMPUTED_STYLE ? 0.01 : 0.1, // Reading the width of elements isn't precise enough and can cause columns to jump between values.
+ columnThreshold: 0.01, // Reading the width of elements isn't precise enough and can cause columns to jump between values.
initialSort: null, // Shuffle can be initialized with a sort object. It is the same object given to the sort method.
throttle: throttle, // By default, shuffle will throttle resize events. This can be changed or removed.
throttleTime: 300, // How often shuffle can be called on resize (in milliseconds).
- sequentialFadeDelay: 150, // Delay between each item that fades in when adding items.
- supported: CAN_TRANSITION_TRANSFORMS // Whether to use transforms or absolute positioning.
+ staggerAmount: 15, // Transition delay offset for each item in milliseconds.
+ staggerAmountMax: 250, // Maximum stagger delay in milliseconds.
+ useTransforms: true, // Whether to use transforms or absolute positioning.
};
-
No options need to be specified, but itemSelector should be used. Other common options to change are speed, easing, gutterWidth, and columnWidth (or sizer).
+
No options need to be specified, but itemSelector should be used. Other common options to change are speed and sizer.
The only real important thing here is the data-groups attribute. It has to be a valid JSON array of strings. Optionally, it can be a string delimeted by a value you provide. See delimeter in the options.
-
In this example, shuffle is using the fluid grid from the Twitter Bootstrap v2.3. It's also making use of BEM class naming.
+
This example is using this site's grid. Each item would be 4 columns at the "sm" breakpoint (768px).
+
+
Images
+
To see why the images are wrapped in .aspect elements, check out the images demo.
The columnWidth option is used to calculate the column width. You have several options:
+
There are 4 options for defining the width of the columns:
-
Use a sizer element. This is the easest way to specify column and gutter widths. You can use an element or an element wrapped in jQuery to define the column width and gutter width. Shuffle will measure the width and margin-left of this sizer element each time the grid resizes. This is awesome for responsive or fluid grids where the width of a column is a percentage. The sizer option is an alias for columnWidth.See a demo using a sizer element or look at the js file for the sizer demo.
+
Use a sizer element. This is the easiest way to specify column and gutter widths. Add the sizer element and make it 1 column wide. Shuffle will measure the width and margin-left of this sizer element each time the grid resizes. This is awesome for responsive or fluid grids where the width of a column is a percentage.
Use a function. When a function is used, its first parameter will be the width of the shuffle element. You need to return the column width for shuffle to use (in pixels).
A number. This will explicitly set the column width to your number (in pixels).
By default, shuffle will use the width of the first item to calculate the column width.
@@ -51,14 +49,14 @@
A basic setup example
If you want functional buttons, check out the js file.
+
Shuffle uses a UMD definition so that you can use it with globals, AMD, or CommonJS.
You can encounter problems when shuffle item dimensions depend on images. Like this demo. There are three good solutions to this.
-
-
Set an explicit height on .shuffle-items like the basic demo.
-
Similar to number 1, make the height of the image container a percentage of the width. If you know the aspect ratio of the images you're using, this is the technique you should use. This demo uses this technique.
-
Get notified when images load and call myShuffleInstance.layout(). I recommend using Desandro's images loaded plugin to know when your images have finished loading.
-
+
+
+
Using images with Shuffle
+
You can encounter problems when shuffle item dimensions depend on images. Like this demo. There are three good solutions to this.
+
+
Set an explicit height on .shuffle-items like the basic demo.
+
Similar to number 1, make the height of the image container a percentage of the width. If you know the aspect ratio of the images you're using, this is the technique you should use. This demo uses this technique.
+
Get notified when images load and call myShuffleInstance.layout(). I recommend using Desandro's images loaded plugin to know when your images have finished loading.
In this demo, the height of each item in the grid depends on the image. If Shuffle is initialized before the images load, the heights it calculates will be incorrect. See here for a solution.
-
Resize the window and it'll fix itself.
+
+
+
This probably looks broken.
+
In this demo, the height of each item in the grid depends on the image. If Shuffle is initialized before the images load, the heights it calculates will be incorrect. See here for a solution.
- Shuffle uses a UMD wrapper, so it is compatible with AMD loaders like RequireJS. The UMD wrapper also allows Shuffle to work with CommonJS modules. You can take a peek at the config file used on this page.
-
+
+
+
RequireJS!
+
+ Shuffle uses a UMD wrapper, so it is compatible with AMD loaders like RequireJS. The UMD wrapper also allows Shuffle to work with CommonJS modules. You can take a peek at the config file used on this page.
+
+
+
@@ -34,7 +38,7 @@ pagejs: false
-
+
{% for item in site.items %}
diff --git a/js/demos/animate-in.js b/js/demos/animate-in.js
index 5318937..5e7a0da 100644
--- a/js/demos/animate-in.js
+++ b/js/demos/animate-in.js
@@ -6,7 +6,7 @@ var Viewport = window.Viewport;
var Demo = function () {
this.element = document.getElementById('grid');
this.gridItems = this.element.querySelectorAll('.picture-item');
- var sizer = this.element.querySelector('.shuffle__sizer');
+ var sizer = this.element.querySelector('.my-sizer-element');
this.shuffle = new Shuffle(this.element, {
itemSelector: '.picture-item',
diff --git a/js/demos/homepage.js b/js/demos/homepage.js
index b5624f5..60ae901 100644
--- a/js/demos/homepage.js
+++ b/js/demos/homepage.js
@@ -10,7 +10,7 @@ var Demo = function (element) {
this.shuffle = new Shuffle(element, {
itemSelector: '.picture-item',
- sizer: element.querySelector('.shuffle__sizer'),
+ sizer: element.querySelector('.my-sizer-element'),
});
this._activeFilters = [];
@@ -44,8 +44,6 @@ Demo.prototype.addShuffleEventListeners = function () {
console.log('type: %s', event.type, 'detail:', event.detail);
};
- this.element.addEventListener(Shuffle.EventType.LOADING, handler, false);
- this.element.addEventListener(Shuffle.EventType.DONE, handler, false);
this.element.addEventListener(Shuffle.EventType.LAYOUT, handler, false);
this.element.addEventListener(Shuffle.EventType.REMOVED, handler, false);
};
diff --git a/js/demos/images.js b/js/demos/images.js
index a47f0eb..e318aed 100644
--- a/js/demos/images.js
+++ b/js/demos/images.js
@@ -2,5 +2,5 @@ var Shuffle = window.shuffle;
window.myShuffle = new Shuffle(document.querySelector('.my-grid-with-images'), {
itemSelector: '.js-item',
- sizer: '.shuffle__sizer',
+ sizer: '.my-sizer-element',
});
diff --git a/js/demos/padding-grid.js b/js/demos/padding-grid.js
index 34bdce5..e618169 100644
--- a/js/demos/padding-grid.js
+++ b/js/demos/padding-grid.js
@@ -2,5 +2,5 @@
window.demo = new window.shuffle(document.getElementById('grid'), {
itemSelector: '.grid__brick',
- sizer: document.querySelector('#grid .shuffle__sizer'),
+ sizer: document.querySelector('#grid .my-sizer-element'),
});
diff --git a/src/on-transition-end.js b/src/on-transition-end.js
index 8f9a298..c12829a 100644
--- a/src/on-transition-end.js
+++ b/src/on-transition-end.js
@@ -27,7 +27,7 @@ export function onTransitionEnd(element, callback) {
export function cancelTransitionEnd(id) {
if (transitions[id]) {
transitions[id].element.removeEventListener(eventName, transitions[id].listener);
- delete transitions[id];
+ transitions[id] = null;
return true;
}
diff --git a/src/shuffle.es6.js b/src/shuffle.es6.js
index 755a6e2..24431d0 100644
--- a/src/shuffle.es6.js
+++ b/src/shuffle.es6.js
@@ -24,10 +24,6 @@ function each(obj, iterator, context) {
}
}
-function defer(fn, context, wait) {
- return setTimeout(fn.bind(context), wait);
-}
-
function arrayMax(array) {
return Math.max.apply(Math, array);
}
@@ -68,7 +64,7 @@ class Shuffle {
this.isDestroyed = false;
this.isInitialized = false;
this._transitions = [];
- this._isMovementCanceled = false;
+ this.isTransitioning = false;
this._queue = [];
element = this._getElementOption(element);
@@ -80,15 +76,8 @@ class Shuffle {
this.element = element;
this.id = 'shuffle_' + id++;
- this._dispatch(Shuffle.EventType.LOADING);
this._init();
-
- // Dispatch the done event asynchronously so that people can bind to it after
- // Shuffle has been initialized.
- defer(function () {
- this.isInitialized = true;
- this._dispatch(Shuffle.EventType.DONE);
- }, this, 16);
+ this.isInitialized = true;
}
_init() {
@@ -124,12 +113,13 @@ class Shuffle {
// Kick off!
this.filter(this.options.group, this.options.initialSort);
- // The shuffle items haven't had transitions set on them yet
- // so the user doesn't see the first layout. Set them now that the first layout is done.
- defer(function () {
- this._setTransitions();
- this.element.style.transition = 'height ' + this.options.speed + 'ms ' + this.options.easing;
- }, this);
+ // The shuffle items haven't had transitions set on them yet so the user
+ // doesn't see the first layout. Set them now that the first layout is done.
+ // First, however, a synchronous layout must be caused for the previous
+ // styles to be applied without transitions.
+ this.element.offsetWidth; // jshint ignore: line
+ this._setTransitions();
+ this.element.style.transition = 'height ' + this.options.speed + 'ms ' + this.options.easing;
}
/**
@@ -381,16 +371,16 @@ class Shuffle {
var size;
// If the columnWidth property is a function, then the grid is fluid
- if (typeof this.columnWidth === 'function') {
- size = this.columnWidth(containerWidth);
+ if (typeof this.options.columnWidth === 'function') {
+ size = this.options.columnWidth(containerWidth);
// columnWidth option isn't a function, are they using a sizing element?
} else if (this.useSizer) {
size = Shuffle.getSize(this.options.sizer).width;
// if not, how about the explicitly set option?
- } else if (this.columnWidth) {
- size = this.columnWidth;
+ } else if (this.options.columnWidth) {
+ size = this.options.columnWidth;
// or use the size of the first item
} else if (this.items.length > 0) {
@@ -479,6 +469,10 @@ class Shuffle {
* @return {boolean} Whether the event was prevented or not.
*/
_dispatch(name, details = {}) {
+ if (this.isDestroyed) {
+ return;
+ }
+
details.shuffle = this;
return !this.element.dispatchEvent(new CustomEvent(name, {
bubbles: true,
@@ -747,16 +741,15 @@ class Shuffle {
_transition(opts) {
opts.item.applyCss(this._getStylesForTransition(opts));
- this._whenTransitionDone(opts.item.element, opts.callback);
+ return this._whenTransitionDone(opts.item.element, opts.callback);
}
/**
* Execute the styles gathered in the style queue. This applies styles to elements,
* triggering transitions.
- * @param {boolean} withLayout Whether to trigger a layout event.
* @private
*/
- _processQueue(withLayout = true) {
+ _processQueue() {
if (this.isTransitioning) {
this._cancelMovement();
}
@@ -779,8 +772,8 @@ class Shuffle {
// A call to layout happened, but none of the newly filtered items will
// change position. Asynchronously fire the callback here.
- } else if (withLayout) {
- defer(this._dispatchLayout, this);
+ } else {
+ setTimeout(this._dispatchLayout.bind(this), 0);
}
// Remove everything in the style queue
@@ -1138,8 +1131,6 @@ Shuffle.FILTER_ATTRIBUTE_KEY = 'groups';
* @enum {string}
*/
Shuffle.EventType = {
- LOADING: 'shuffle:loading',
- DONE: 'shuffle:done',
LAYOUT: 'shuffle:layout',
REMOVED: 'shuffle:removed',
};
@@ -1161,7 +1152,8 @@ Shuffle.options = {
// e.g. '.picture-item'.
itemSelector: '*',
- // Sizer element. Use an element to determine the size of columns and gutters.
+ // Element or selector string. Use an element to determine the size of columns
+ // and gutters.
sizer: null,
// A static number or function that tells the plugin how wide the gutters
@@ -1198,7 +1190,7 @@ Shuffle.options = {
// Transition delay offset for each item in milliseconds.
staggerAmount: 15,
- // It can look a little weird when the last element is in the top row
+ // Maximum stagger delay in milliseconds.
staggerAmountMax: 250,
// Whether to use transforms or absolute positioning.
diff --git a/test/test.js b/test/test.js
index a651923..8699026 100644
--- a/test/test.js
+++ b/test/test.js
@@ -49,7 +49,7 @@ describe('shuffle', function () {
}
}
- function cleanup() {
+ function removeFixture() {
if (instance && instance.element) {
instance.destroy();
}
@@ -62,19 +62,6 @@ describe('shuffle', function () {
fixture = null;
}
- function removeFixture(done) {
- if (!instance || instance.isInitialized) {
- cleanup();
- done();
- } else {
- instance.element.addEventListener(Shuffle.EventType.DONE, function onDone() {
- instance.element.removeEventListener(Shuffle.EventType.DONE, onDone);
- cleanup();
- done();
- });
- }
- }
-
function once(element, eventType, fn) {
var handler = function (e) {
element.removeEventListener(eventType, handler);
@@ -103,12 +90,12 @@ describe('shuffle', function () {
appendFixture('regular').then(done);
});
- afterEach(function (done) {
- removeFixture(done);
+ afterEach(function () {
Shuffle.prototype._whenTransitionDone.restore();
+ removeFixture();
});
- it('should have default options', function (done) {
+ it('should have default options', function () {
instance = new Shuffle(fixture);
expect(instance.items.length).to.equal(10);
expect(instance.visibleItems).to.equal(10);
@@ -124,12 +111,7 @@ describe('shuffle', function () {
expect(instance.useSizer).to.equal(false);
expect(instance.id).to.equal('shuffle_0');
- expect(instance.isInitialized).to.be.false;
- instance.element.addEventListener(Shuffle.EventType.DONE, function onDone() {
- instance.element.removeEventListener(Shuffle.EventType.DONE, onDone);
- expect(instance.isInitialized).to.be.true;
- done();
- });
+ expect(instance.isInitialized).to.be.true;
});
it('should add classes and default styles', function () {
@@ -233,11 +215,6 @@ describe('shuffle', function () {
speed: 0,
});
- function first() {
- once(fixture, Shuffle.EventType.LAYOUT, second);
- instance.filter('design');
- }
-
function second() {
expect(instance.visibleItems).to.equal(3);
var concealed = [3, 4, 5, 6, 7, 8, 10].map(function (num) {
@@ -287,7 +264,8 @@ describe('shuffle', function () {
done();
}
- once(fixture, Shuffle.EventType.DONE, first);
+ once(fixture, Shuffle.EventType.LAYOUT, second);
+ instance.filter('design');
});
it('can initialize filtered and the category parameter is optional', function () {
@@ -314,159 +292,146 @@ describe('shuffle', function () {
expect(instance.lastSort).to.deep.equal(sortObj);
});
- describe('after initialized', function () {
- var clock;
-
- beforeEach(function () {
- clock = sinon.useFakeTimers();
- instance = new Shuffle(fixture);
- clock.tick(17);
- expect(instance.isInitialized).to.be.true;
- });
-
- afterEach(function () {
- clock.restore();
- });
+ it('can calculate column spans', function () {
+ instance = new Shuffle(fixture);
+ expect(instance._getColumnSpan(50, 100, 3)).to.equal(1);
+ expect(instance._getColumnSpan(200, 100, 3)).to.equal(2);
+ expect(instance._getColumnSpan(200, 200, 3)).to.equal(1);
+ expect(instance._getColumnSpan(300, 100, 3)).to.equal(3);
- it('can calculate column spans', function () {
- expect(instance._getColumnSpan(50, 100, 3)).to.equal(1);
- expect(instance._getColumnSpan(200, 100, 3)).to.equal(2);
- expect(instance._getColumnSpan(200, 200, 3)).to.equal(1);
- expect(instance._getColumnSpan(300, 100, 3)).to.equal(3);
+ // Column span should not be larger than the number of columns.
+ expect(instance._getColumnSpan(300, 50, 3)).to.equal(3);
- // Column span should not be larger than the number of columns.
- expect(instance._getColumnSpan(300, 50, 3)).to.equal(3);
+ // Fix for percentage values.
+ expect(instance._getColumnSpan(100.02, 100, 4)).to.equal(1);
+ expect(instance._getColumnSpan(99.98, 100, 4)).to.equal(1);
+ });
- // Fix for percentage values.
- expect(instance._getColumnSpan(100.02, 100, 4)).to.equal(1);
- expect(instance._getColumnSpan(99.98, 100, 4)).to.equal(1);
- });
+ it('can calculate column sets', function () {
+ instance = new Shuffle(fixture);
- it('can calculate column sets', function () {
- // _getColumnSet(columnSpan, columns)
- instance.positions = [150, 0, 0, 0];
- expect(instance._getColumnSet(1, 4)).to.deep.equal([150, 0, 0, 0]);
- expect(instance._getColumnSet(2, 4)).to.deep.equal([150, 0, 0]);
- });
+ // _getColumnSet(columnSpan, columns)
+ instance.positions = [150, 0, 0, 0];
+ expect(instance._getColumnSet(1, 4)).to.deep.equal([150, 0, 0, 0]);
+ expect(instance._getColumnSet(2, 4)).to.deep.equal([150, 0, 0]);
+ });
- it('can get an element option', function () {
- var first = fixture.firstElementChild;
-
- expect(instance._getElementOption(first)).to.equal(first);
- expect(instance._getElementOption('#item1')).to.equal(first);
- expect(instance._getElementOption('#hello-world')).to.be.null;
- expect(instance._getElementOption(null)).to.be.null;
- expect(instance._getElementOption(undefined)).to.be.null;
- expect(instance._getElementOption(function () {
- return first;
- })).to.be.null;
- });
+ it('can get an element option', function () {
+ instance = new Shuffle(fixture);
+ var first = fixture.firstElementChild;
+
+ expect(instance._getElementOption(first)).to.equal(first);
+ expect(instance._getElementOption('#item1')).to.equal(first);
+ expect(instance._getElementOption('#hello-world')).to.be.null;
+ expect(instance._getElementOption(null)).to.be.null;
+ expect(instance._getElementOption(undefined)).to.be.null;
+ expect(instance._getElementOption(function () {
+ return first;
+ })).to.be.null;
+ });
- it('can test elements against filters', function () {
+ it('can test elements against filters', function () {
+ instance = new Shuffle(fixture);
- var first = fixture.firstElementChild;
- expect(instance._doesPassFilter('design', first)).to.be.true;
- expect(instance._doesPassFilter('black', first)).to.be.false;
+ var first = fixture.firstElementChild;
+ expect(instance._doesPassFilter('design', first)).to.be.true;
+ expect(instance._doesPassFilter('black', first)).to.be.false;
- expect(instance._doesPassFilter(function (element) {
- expect(element).to.exist;
- return element.getAttribute('data-age') === '21';
- }, first)).to.equal(true);
+ expect(instance._doesPassFilter(function (element) {
+ expect(element).to.exist;
+ return element.getAttribute('data-age') === '21';
+ }, first)).to.equal(true);
- expect(instance._doesPassFilter(function (element) {
- return element.getAttribute('data-age') === '22';
- }, first)).to.equal(false);
- });
+ expect(instance._doesPassFilter(function (element) {
+ return element.getAttribute('data-age') === '22';
+ }, first)).to.equal(false);
+ });
- it('will maintain the last sort object', function () {
- var initialSort = instance.lastSort;
+ it('will maintain the last sort object', function () {
+ instance = new Shuffle(fixture);
+ var initialSort = instance.lastSort;
- instance.sort();
- expect(instance.lastSort).to.deep.equal(initialSort);
+ instance.sort();
+ expect(instance.lastSort).to.deep.equal(initialSort);
- instance.sort({ glen: true });
- expect(instance.lastSort).to.deep.equal({ glen: true });
+ instance.sort({ glen: true });
+ expect(instance.lastSort).to.deep.equal({ glen: true });
- instance.sort();
- expect(instance.lastSort).to.deep.equal({ glen: true });
+ instance.sort();
+ expect(instance.lastSort).to.deep.equal({ glen: true });
- });
+ });
- it('should reset columns', function () {
+ it('should reset columns', function () {
+ instance = new Shuffle(fixture);
- expect(instance.cols).to.be.above(0);
- instance._resetCols();
+ expect(instance.cols).to.be.above(0);
+ instance._resetCols();
- var positions = new Array(instance.cols);
- for (var i = 0; i < instance.cols; i++) {
- positions[i] = 0;
- }
+ var positions = new Array(instance.cols);
+ for (var i = 0; i < instance.cols; i++) {
+ positions[i] = 0;
+ }
- expect(instance.positions).to.deep.equal(positions);
- });
+ expect(instance.positions).to.deep.equal(positions);
+ });
- it('should destroy properly', function () {
- instance.destroy();
+ it('should destroy properly', function () {
+ instance = new Shuffle(fixture);
+ instance.destroy();
- expect(instance.element).to.be.null;
- expect(instance.items).to.be.null;
- expect(instance.options.sizer).to.be.null;
- expect(instance.isDestroyed).to.be.true;
+ expect(instance.element).to.be.null;
+ expect(instance.items).to.be.null;
+ expect(instance.options.sizer).to.be.null;
+ expect(instance.isDestroyed).to.be.true;
- expect(fixture).to.not.have.class('shuffle');
+ expect(fixture).to.not.have.class('shuffle');
- toArray(fixture.children).forEach(function (child) {
- expect(child).to.not.have.class('shuffle-item');
- expect(child).to.not.have.class('filtered');
- expect(child).to.not.have.class('concealed');
- });
+ toArray(fixture.children).forEach(function (child) {
+ expect(child).to.not.have.class('shuffle-item');
+ expect(child).to.not.have.class('filtered');
+ expect(child).to.not.have.class('concealed');
});
+ });
- it('should not update or shuffle when disabled or destroyed', function () {
- var update = sinon.spy(instance, 'update');
- var _filter = sinon.spy(instance, '_filter');
+ it('should not update or shuffle when disabled or destroyed', function () {
+ instance = new Shuffle(fixture);
+ var update = sinon.spy(instance, 'update');
+ var _filter = sinon.spy(instance, '_filter');
- instance.disable();
+ instance.disable();
- instance.filter('design');
+ instance.filter('design');
- expect(_filter.called).to.be.false;
- expect(update.called).to.be.false;
+ expect(_filter.called).to.be.false;
+ expect(update.called).to.be.false;
- instance.enable(false);
+ instance.enable(false);
- instance.destroy();
- instance._onResize();
- expect(update.called).to.be.false;
- });
+ instance.destroy();
+ instance._onResize();
+ expect(update.called).to.be.false;
+ });
- it('should not update when the container is the same size', function () {
- var update = sinon.spy(instance, 'update');
+ it('should not update when the container is the same size', function () {
+ instance = new Shuffle(fixture);
+ var update = sinon.spy(instance, 'update');
- instance._onResize();
+ instance._onResize();
- expect(update.called).to.be.false;
- });
+ expect(update.called).to.be.false;
});
describe('removing elements', function () {
var itemsToRemove;
- var onDone;
- var onRemoved;
beforeEach(function () {
var children = toArray(fixture.children);
itemsToRemove = children.slice(0, 2);
- onDone = function () {
- once(fixture, Shuffle.EventType.REMOVED, onRemoved);
- instance.remove(itemsToRemove);
- };
});
afterEach(function () {
itemsToRemove = null;
- onDone = null;
- onRemoved = null;
});
it('can remove items', function (done) {
@@ -474,17 +439,20 @@ describe('shuffle', function () {
speed: 16,
});
- onRemoved = function (evt) {
+ once(fixture, Shuffle.EventType.REMOVED, function (evt) {
var detail = evt.detail;
expect(detail.shuffle.visibleItems).to.equal(8);
expect(detail.collection[0].id).to.equal('item1');
expect(detail.collection[1].id).to.equal('item2');
expect(detail.shuffle.element.children).to.have.lengthOf(8);
expect(instance.isTransitioning).to.equal(false);
- done();
- };
- once(fixture, Shuffle.EventType.DONE, onDone);
+ once(fixture, Shuffle.EventType.LAYOUT, function () {
+ done();
+ });
+ });
+
+ instance.remove(itemsToRemove);
});
it('can remove items without transforms', function (done) {
@@ -493,17 +461,20 @@ describe('shuffle', function () {
useTransforms: false,
});
- onRemoved = function (evt) {
+ once(fixture, Shuffle.EventType.REMOVED, function (evt) {
var detail = evt.detail;
expect(detail.shuffle.visibleItems).to.equal(8);
expect(detail.collection[0].id).to.equal('item1');
expect(detail.collection[1].id).to.equal('item2');
expect(detail.shuffle.element.children).to.have.lengthOf(8);
expect(detail.shuffle.isTransitioning).to.equal(false);
- done();
- };
- once(fixture, Shuffle.EventType.DONE, onDone);
+ once(fixture, Shuffle.EventType.LAYOUT, function () {
+ done();
+ });
+ });
+
+ instance.remove(itemsToRemove);
});
});
@@ -535,7 +506,6 @@ describe('shuffle', function () {
});
describe('inserting elements', function () {
- var clock;
var items = [];
beforeEach(function () {
@@ -555,18 +525,14 @@ describe('shuffle', function () {
items.push(eleven, twelve);
- clock = sinon.useFakeTimers();
instance = new Shuffle(fixture, {
speed: 100,
group: 'black',
});
- clock.tick(17);
- expect(instance.isInitialized).to.be.true;
});
afterEach(function (done) {
once(fixture, Shuffle.EventType.LAYOUT, function () {
- clock.restore();
items.length = 0;
done();
});
@@ -611,10 +577,10 @@ describe('shuffle', function () {
});
});
- afterEach(function (done) {
+ afterEach(function () {
items.length = 0;
clone.length = 0;
- removeFixture(done);
+ removeFixture();
});
it('will catch empty objects', function () {