Reputation: 748
I have initialize masonry plugin - works OK,
than I destroy it for media width <= 767px - it was destroyed
but when I return back to media width > 767px and initialize masonry again it doesn't work.
why?
or is there any another solution to turn off masonry plugin and later turn it on on some event?
this is my code:
var masonryData = {
isInitLayout: true,
isResizeBound: false,
itemSelector: '.item',
columnWidth: 300,
gutter: 20,
transitionDuration: '0.5s'
};
function initializeMasonry(masonryData){
if (jQuery().masonry) {
var masonryContainer = jQuery('.masonry').masonry(masonryData);
jQuery(masonryContainer).imagesLoaded(function(){
jQuery(masonryContainer).masonry(masonryData);
});
}
}
function destroyMasonry(){
if (jQuery().masonry) {
jQuery('.masonry').masonry();
jQuery('.masonry').masonry('destroy');
}
}
I'm using enquire plugin so I use match/unmatch methods for js media queries:
$.Site.Match.smallScreen = function() {
...
destroyMasonry();
...
}
$.Site.Match.mediumScreen = function() {
...
initializeMasonry(masonryData);
...
}
Many thanks for help
Upvotes: 2
Views: 12192
Reputation: 71
Finally after hours of reading the docs, I found that masonry will make a $.data('masonry') to masonry element.
You can read more about it in masonry docs here.
This data will affect the items position in masonry. So, we need to remove this data with $.removeData('masonry') after we destroy the masonry.
// init masonry
$('.masonry-container').masonry();
// destroy masonry
$('.masonry-container').masonry('destroy');
$('.masonry-container').removeData('masonry'); // This line to remove masonry's data
// re-init masonry again. The position will be nice
$('.masonry-container').masonry();
Upvotes: 7
Reputation: 676
Eli Gassert's answer might be more clever than going all javascript.
However, I found myself doing this quite successfully like this:
$(window).on('resize', function (event) {
var $window = $(window);
if ($window.width() < 768) {
var $masonryTarget = $('.masonry-container'),
$hasMasonry = $masonryTarget.data('masonry') ? true : false
;
if ($masonryTarget.length > 0 && $hasMasonry) {
// Destroy masonry if exists.
$masonryTarget.masonry('destroy');
}
} else {
// Enable all masonry instances.
$('.mansonry-container').masonry({
'itemSelector': '.masonry-item',
'columnWidth': '.masonry-item'
});
}
});
The basic idea is that masonry, initialized as a jQuery plugin is stored in a data attribute. If a masonry data attribute is defined, we destroy the instance.
Might be worth mentioning that debouncing this function improves a lot the performance.
Upvotes: 1
Reputation: 9763
For what it's worth, I ended up solving this a different way. Masonry is just setting some styles. So using a media query, I set the following CSS to basically render masonry useless:
@media (max-width: 768px) {
.item {
position: relative !important;
left: auto !important;
top: auto !important;
}
}
Now, I always initialize masonry, and never uninitialize/reinitialize it. It's on all the time, but CSS media queries with !important
take priority over the inline styles set by Masonry.
Upvotes: 3
Reputation: 1
$(document).ready(function() {
if ($(window).width() <= 767) {
$('#container').masonry( 'destroy' );
}
if ($(window).width() > 768) {
$('#container').masonry({
columnWidth: 350,
gutter: 20,
});
}
if ($(window).width() > 992) {
$('#container').masonry({
columnWidth: 300,
gutter: 20,
});
}
if ($(window).width() > 1200) {
$('#container').masonry({
columnWidth: 270,
gutter: 20,
});
}
});
Upvotes: -1