I have been tinkering with some thoughts on a round-about way of making gridster.js responsive. I found a code snippit in the github issues in gridster and realized if I ran it under certain window sizing and destroyed and re-ran gridster I can get the effect of gridster responding responsivley. Let me show you what I mean -
$(window).resize(function(){
var width = $(window).width();
var columns = "";
if(Modernizr.mq('screen and (max-width:640px)')){
columns = 1;
gridster.destroy();
var tooFar = $('.gridster .gs-w').filter(function () {
return $(this).data('col') > columns;
});
$(tooFar).each(function () {
$(this).attr('data-col', '1');
});
var tooBig = $('.gridster li').filter(function () {
return $(this).data('sizex') > columns;
});
$(tooBig).each(function () {
$(this).attr('data-sizex', columns);
});
$(".gridster ul").gridster({
widget_base_dimensions: [300, 300],
widget_margins: [5, 5],
max_cols: 1,
resize: {
enabled: true
},
draggable: {
handle: '.dragDiv'
},
serialize_params: function ($w, wgd) {
return {
/* add element ID to data*/
id: $w.attr('id'),
/* defaults */
col: wgd.col,
row: wgd.row,
size_x: wgd.size_x,
size_y: wgd.size_y,
/* htmlContent: $($w).html() */
}
}
}).data('gridster');
}
});
So when gridster should break into 1 column (it has a base of 4), it destroys and re runs with 1 column. This works surprisingly well, the issue is this is not a pretty way of achieving this. I am also not showing all the break points ( it breaks into, 3 -2 -1 columns based on window size). It runs very poorly because its firing on every window resize, and I'm wondering if there is a cleaner way to do this where the functions would only fire once when they hit the window size.
Also - this is only to size gridster down, so if you size out it will not expand, I have not tried building those functions yet.
Any pointers or suggestions in using something that maybe isn't listening to every single instance of a window re-size would be super helpful.
Thanks!!
I gather from your question that gridster is being re-run continuously as the user resizes the window; that is, if you resize the window by dragging the window slowly, pixel by pixel, there is a gridster re-run for every pixel change.
Try throttling the resize
event with setTimeout
. When resize
fires, you set a timer to do the re-run of gridster -- say the timer duration is 200ms. If within that 200ms, another resize
fires, you reset the timer. With this approach, the re-run only occurs when the user is done resizing (at least for the moment). You can tweak the timer duration for a better experience.
Try:
var resizeTimeout;
$(window).resize(function(){
if(!!resizeTimeout){ clearTimeout(resizeTimeout); }
resizeTimeout = setTimeout(function(){
//do gridster re-run here
},200);
});
example fiddle (look at the console as you slowly resize the window)
EDIT: For anyone interested in this pattern, I've extracted the throttling logic from the above code and put it into a jQuery plugin:
(function($){
$.fn.onDelayed = function(eventName,delayInMs,callback){
var _timeout;
this.on(eventName,function(e){
if(!!_timeout){
clearTimeout(_timeout);
console.log('timer being re-set: ' + eventName);
} else {
console.log('timer being set for the first time: ' + eventName);
}
_timeout = setTimeout(function(){
callback(e);
},delayInMs);
});
};
})(jQuery);
which would be used like
$(function(){
$(document).onDelayed('click',500,function(){
alert('clicking is done');
});
$(window).onDelayed('resize',1000,function(){
alert('resize is finished');
});
});
Fiddle with two example uses of onDelayed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With