diff --git a/lib/index.js b/lib/index.js index b1ad8c7..dc5f367 100644 --- a/lib/index.js +++ b/lib/index.js @@ -18,7 +18,8 @@ var propTypes = { imagesLoadedOptions: PropTypes.object, elementType: PropTypes.string, onLayoutComplete: PropTypes.func, - onRemoveComplete: PropTypes.func + onRemoveComplete: PropTypes.func, + updateOnEachComponentUpdate: PropTypes.bool }; var MasonryComponent = createReactClass({ @@ -41,7 +42,8 @@ var MasonryComponent = createReactClass({ onLayoutComplete: function() { }, onRemoveComplete: function() { - } + }, + updateOnEachComponentUpdate: true }; }, @@ -214,7 +216,9 @@ var MasonryComponent = createReactClass({ this.masonry.reloadItems(); } - this.masonry.layout(); + if (this.props.updateOnEachComponentUpdate || reloadItems) { + this.reloadLayout(); + } }, derefImagesLoaded: function() { @@ -237,7 +241,7 @@ var MasonryComponent = createReactClass({ if (this.props.onImagesLoaded) { this.props.onImagesLoaded(instance); } - this.masonry.layout(); + this.reloadLayout(); }.bind(this), 100); var imgLoad = imagesloaded(this.masonryContainer, this.props.imagesLoadedOptions).on(event, handler); @@ -248,6 +252,14 @@ var MasonryComponent = createReactClass({ }; }, + reloadLayout: debounce( + function() { + this.masonry.layout(); + }, 100, { + leading: true + } + ), + initializeResizableChildren: function() { if (!this.props.enableResizableChildren) { return; @@ -261,9 +273,7 @@ var MasonryComponent = createReactClass({ }, listenToElementResize: function(el) { - this.erd.listenTo(el, function() { - this.masonry.layout() - }.bind(this)) + this.erd.listenTo(el, this.reloadLayout); }, destroyErd: function() { @@ -300,7 +310,7 @@ var MasonryComponent = createReactClass({ } this.masonry.destroy(); }, - + setRef: function(n) { this.masonryContainer = n; }, diff --git a/spec/react-masonry-component-test.js b/spec/react-masonry-component-test.js index 4a77281..f2e30f3 100644 --- a/spec/react-masonry-component-test.js +++ b/spec/react-masonry-component-test.js @@ -27,7 +27,8 @@ describe('React Masonry Component', function() { onLayoutComplete: function() { }, onRemoveComplete: function() { - } + }, + updateOnEachComponentUpdate: true }); }); @@ -442,7 +443,7 @@ describe('React Masonry Component', function() { failureMessage(index, 'top', expectedPosition.top + 'px', element.style.top, phase)) } - it('should correctly layout remaining elements when first element is removed [columnWidth empty]', function() { + it('should correctly layout remaining elements when first element is removed [columnWidth empty]', function(done) { let wrapperContext; class Wrapper extends React.Component { constructor() { @@ -479,11 +480,15 @@ describe('React Masonry Component', function() { } wrapperContext.setState({items: localChildrenElements.slice(1)}); - const secondElements = div.querySelectorAll('.item'); - for (let i = 0; i < secondElements.length; i++) { - expectElementPositionToMatch(secondElements[i], secondPositions[i], i, 'after removal'); - } + setTimeout(function(){ + const secondElements = div.querySelectorAll('.item'); + + for (let i = 0; i < secondElements.length; i++) { + expectElementPositionToMatch(secondElements[i], secondPositions[i], i, 'after removal'); + } + done(); + }, 500); }); it('should correctly layout remaining elements when first element is removed [columnWidth fixed]', function() { diff --git a/typings.d.ts b/typings.d.ts index 65cb551..4a83842 100644 --- a/typings.d.ts +++ b/typings.d.ts @@ -27,6 +27,7 @@ export interface MasonryPropTypes { style?: Object; onLayoutComplete?: (instance: any) => void; onRemoveComplete?: (instance: any) => void; + updateOnEachComponentUpdate?: boolean; } declare const Masonry: ComponentClass;