Hi coders!
I have this project: www.mercatocentrale.it - I have used isotope to generate a liquid masonry with different width and height dimensions for each box.
I have sorted each box with a "sort order" value that i parse with isotope class.
When you click on specific boxes i append a new div to isotope and I want to positionate it in the next row of the grid. Actually the effect works but on mobile the page crashes.
I would like to have my huge script simplified and also to fix the crash on mobile devices.
Just other few info: i am on Wordpress, i generate dynamically all the boxes + i need a working page, please don''t send me Javascript''s frameworks or other stuff, just the working code with the actual contents so i can just edit my file and go go go + all my jQuery code is in the footer of the page.
Thank you so much.
Isotope is a generally cool concept but it is buggy and Dave Desandro is not very interested in fixing those bugs. It is naturally responsive so it would fit your mobile app however the biggest problem is the amount of DOM leaking Isotope makes which cause browsers to crash. This link is to that very issue with isotope on Desandro's github repo for isotope https://github.com/metafizzy/isotope/issues/295
My recommendation is either use khiltd's solution or find an alternative to isotope. There are plenty!
Hope that helps!
Cheers!
Thank you for your reply michaeln... (@Codersclan fix this css problem, i can't see the whole username!)
I will check for the solution proposed but i think that at this time i can't use a different solution. @yfei when will you send a simple and less redundant code maybe you could take a look for me at that issue?
PS Desandro told me about this forum :)
michaelmuxica is my username!
I figured as much, Lenus. But wouldn't have felt right otherwise. I have played with isotope so much for the desire of using it and learned of all the small issues preventing it from becoming THE GRID of the internet.
Anyways, I wish you all the luck in taming it to your needs :D
Sorry, I'm late. My laptop just stop working last night, I finally got my data out this afternoon, so I was unable to post the modified files here before the deadline.
3 problems solved:
To use it, just repalce you script at the end of homepage with code below
There are still a lot we can improve about your homepage, like asnyc loading, responsiveness, but that will need more info and time.
jQuery(function($){
// this won't conflict with other js loiarbries using $. no need to call jQuery.noConflict()
// Globals in this file
var $container = $('#main');
var items_per_row; // so basically, 2 means on mobile devices and 7 means on desktop or tablets
var item_width;
var iso_options;
var $current_bollino;
var $bollini = $('.has_content');
function on_window_resize () {
items_per_row = ($container.width() < 641) ? 2 : 7; // why 641? it's a magic number, try to define it.
item_width = Math.round($container.width() / items_per_row)
resize_items (item_width, items_per_row);
iso_options = gen_iso_options();
$container.isotope(iso_options);
console.log(iso_options);
}
function resize_items (item_width, items_per_row){
var item_height = item_width;
$('.item').width(item_width);
$('.item').height(item_height);
$('.item-horizontal').width(2*item_width);
$('.item-horizontal').height(item_height);
$('.item-vertical').width(item_width);
$('.item-vertical').height(2*item_height);
$('.item-square').width(2*item_width);
$('.item-square').height(2*item_height);
$('.hoverChange').width(2*item_height); // strongly recommend you change the camelCase to css-var-case
$('.hoverChange').height(2*item_height);
$('.hoverChangeBack').width(2*item_height);
$('.hoverChangeBack').height(2*item_height);
$('.boxscroll').css('width', 3*item_width + 'px');
$('.hoverBox').css('height', '100%');
$('.ballon').width(items_per_row*item_width);
$('.ballon').css('min-height', 2*item_height);
$('.ballon').css('height', 'auto');
}
function replaceAll (str, oldToken, newToken, ignoreCase) {
if (ignoreCase) {
return ;// not used in your program
} else {
return str.split(oldToken).join(newToken);
}
}
function gen_iso_options () {
// get late binding of item_width
return {
getSortData : {
sorting : function ( elem ) {
return parseInt($(elem).find('.sorting').text(), 10);
},
resorting : function ( elem ) {
return parseInt($(elem).find('.resorting').text(), 10);
}
},
animationOptions: { queue: true, duration: 10000 },
sortBy: 'sorting',
layoutMode: 'masonry',
transformsEnabled: false,
animationEngine: 'best-available',
masonry: {
columnWidth: item_width
},
itemSelector: '.elemento',
itemPositionDataEnabled: true
};
}
function toggle_bollino ($elemento) {
if ($current_bollino && ($current_bollino.clicker.is($elemento))){
hide_bollino();
} else {
open_bollino($elemento);
}
}
function open_bollino ($elemento) {
if ($current_bollino) {
hide_bollino();
}
var sorting = $elemento.children('p.sorting').text();
var target_sorting = $elemento.children('p.target_sorting').text();
if (items_per_row < 7) {
target_sorting = parseInt(sorting) + 0.5;
}
var htmlcontents = $elemento.children('.htmlcontents').html().replace(/(rn|n|t|r)/gm, "");
if (htmlcontents !== '' && $elemento.hasClass('contenutohtml')) {
if ($elemento.hasClass('rosa')) {
var color = 'rose';
} else if ($elemento.hasClass('verde')) {
var color = 'verde';
} else if ($elemento.hasClass('rosso')) {
var color = 'rosso';
} else if ($elemento.hasClass('giallo')) {
var color = 'giallo';
} else if ($elemento.hasClass('blu')) {
var color = 'blu';
} else if ($elemento.hasClass('panna')) {
var color = 'panna';
} else if ($elemento.hasClass('aqua')) {
var color = 'aqua';
} else if ($elemento.hasClass('pizza')) {
var color = 'pizza';
} else if ($elemento.hasClass('paglia')) {
var color = 'paglia';
}
var bollino = {}
bollino.str = replaceAll('<div class="elemento ballon artigiani has_content_to_display losapevi"><div class="toparrow" "> </div>'+htmlcontents+'<p class="sorting">'+target_sorting+'</p></div>', "[incremento]", "appendend_");
var $bollino = $(bollino.str);
$bollino.clicker = $elemento;
$current_bollino = $bollino;
$bollino.id = 'appended_to_' + $elemento.id;
// $bollino.height(item_width);
$bollino.addClass(color);
$bollino.addClass('bollino');
$('.bollino').remove();
$bollino.appendTo($container)
$container.isotope('insert', $bollino)
// nice scroll for lightboxes
var $boxscroll_active = $('.bollino .boxscroll-active')
$boxscroll_active.niceScroll({
cursorcolor:"#000000",
cursoropacitymin: 1,
cursoropacitymax: 1,
cursorwidth: 8,
cursorborder: '0'
});
$boxscroll_active.getNiceScroll().resize();
$(".bollino").mouseover(function(){
$boxscroll_active.getNiceScroll().resize();
})
$('html, body').animate({
scrollTop: $bollino.offset().top - item_width - 100
}, 1000);
}
};
function hide_bollino () {
$('.bollino .boxscroll-active').getNiceScroll().hide();
$container.isotope('remove', $current_bollino).isotope('layout');
$current_bollino.remove();
$current_bollino = null;
}
function next_bollino () {
var next;
$bollini.each(function (index, bollino) {
// console.log($(bollino));
// console.log($current_bollino)
if ($(bollino).is($current_bollino.clicker)) {
next = index+1;
open_bollino($('#'+$bollini[next].id));
return false;
}
});
}
function prev_bollino () {
var prev;
$bollini.each(function (index, bollino) {
// console.log($(bollino));
// console.log($current_bollino)
if ($(bollino).is($current_bollino.clicker)) {
prev = index-1;
open_bollino($('#'+$bollini[prev].id));
return false;
}
});
}
function open_popup(uri, scrollable){
var src = uri;
if (scrollable == 1){
addcss = 'scrolling="no" style="padding: 5px; border:0; overflow: hidden;"';
} else {
addcss = 'scrolling="no" style="padding: 5px; border:0; overflow: hidden;"';
}
$.modal('<iframe src="' + src + '" frameborder="0" width="850" height="450" '+ addcss +'>', {
closeHTML:"",
containerCss:{
backgroundColor:"#fff",
width:860,
height:470,
padding:0,
},
overlayClose:true
});
}
window.hide_bollino = hide_bollino;
window.next_bollino = next_bollino;
window.prev_bollino = prev_bollino;
window.open_popup = open_popup;
// run immediately after page loaded
$('#loading').fadeOut(); // I don't see this line working
$('body').css('overflow', 'auto'); // You should write this line into CSS files
on_window_resize(); // init the window
// flippers
$(".flip-container").click(function(){
$(this).toggleClass('hover');
});
// won't crash on phones
$(".elemento").click(function(){
toggle_bollino($(this));
});
// recalculate all if window resized
$(window).resize(on_window_resize);
});
Hi there yifeikong, we have made a little implementation to the code in another task...could you check for the little updates on open_bollino(), close_bollino(), next_bollino(), prev_bollino()?
Actually we have few troubles to fix:
www.mercatocentrale.it (it's live). But it seems to be broken on my Firefox at the first load: www.mercatocentrale.it/first_load.gif and I have to resize to have the right effect.
Or sometimes under "stress" the niceScroll effect ...doesn't work properly www.mercatocentrale.it/bar.gif
If I try to load just one kind of boxes like here: http://www.mercatocentrale.it/gli-artigiani-gusto/ it seems to not work properly...
@Lenus I've checked your updated version. It seems better but broken on my firefox, too. And it's still not working on mobile phones.
My version works on desktop and do not crash on phones (This is the problems you stated in this ticket).
If you wish to use fix your problems in your last reply. Here are 2 things you can do:
jQuery.ready()
, which makes you don't have to mannully resize the window to make it right in firefox.$('.bollino .boxscroll-active').getNiceScroll().hide();
in your hide_bollino
function, which hide the scrollbar generated by niceScroll.But this is still a quick and dirty fix, you should tweak the dynamically generated boxes and use javascript generate the boxes dynamically rather than store the data in html to get better results. Hope it helps :).
Hi there! I prefer to use you incredible compact script of your previous comment.
Could you (take your time, it's saturday!) Take the new functions (they allow me to open bollinos in the next avaible row (it seems to work) and do the wonderful clean up to have it fast, readable and awsome (without crashes and mobile-ready?)
Lenus
Hi, LenusMedia
It's done and working on mobile, scroll-bar issue also fixed.
jQuery.noConflict();
var $main = jQuery('#main');
String.prototype.replaceAll = function(token, newToken, ignoreCase) {
var _token;
var str = this + "";
var i = -1;
if (typeof token === "string") {
if ( ignoreCase ) {
_token = token.toLowerCase();
while((i = str.toLowerCase().indexOf(token, i >= 0 ? i + newToken.length : 0)) !== -1) {
str = str.substring( 0, i ) + newToken + str.substring( i + token.length );
}
} else {
return this.split(token).join(newToken);
}
}
return str;
};
function scroll_and_select (id){
jQuery('body, html').scrollTo( jQuery('#' + id) , 800);
jQuery('ul.sort-by li').removeClass('selected');
jQuery('ul.sort-by li#link_' + id).addClass('selected');
}
function recall () {
var main_width = $main.width();
var main_offset = $main.offset();
if (main_offset.top == 0){
$main.css('marginTop', jQuery('#top').height() + 'px');
}
var num = 7;
if (main_width < 641){
num = 2;
}
var item_width = Math.round(main_width / num);
// *
// * correggiamo la larghezza della barra a sx
// *
var full_width = item_width * num;
var diff = full_width - main_width;
if (diff > 0){
item_width = item_width - 1;
}
calculate_dimensions(item_width, num);
var isoOptions = {
getSortData : {
sorting : function ( elem ) {
return parseInt(jQuery(elem).find('.sorting').text(), 10);
},
resorting : function ( elem ) {
return parseInt(jQuery(elem).find('.resorting').text(), 10);
}
},
animationOptions: { queue: true, duration: 10000 },
sortBy: 'sorting',
layoutMode: 'masonry',
transformsEnabled: false,
animationEngine: 'best-available',
masonry: {
columnWidth: item_width
},
itemSelector: '.elemento',
itemPositionDataEnabled: true
};
$main.isotope( isoOptions );
}
function open_bollino (id) {
var $ = jQuery;
var $bollino = $('#bollino');
if ($bollino) {
var activeItem = $bollino.data('item-id');
hide_bollino();
if (activeItem == id) return;
}
var elem = $('#'+id);
if (!elem.hasClass('contenutohtml')) return;
var main_width = $main.width();
var num = (main_width < 641) ? 2 : 7;
var item_width = Math.floor(main_width / num);
calculate_dimensions(item_width, num);
var htmlcontents = elem.children('.htmlcontents').html().replace(/(rn|n|t|r)/gm, "");
if (htmlcontents != '') {
var valid_colore = [ 'rosa', 'verde', 'rosso', 'giallo', 'blu', 'panna', 'aqua', 'pizza', 'paglia' ];
var colore = '';
for (c in valid_colore) {
if (elem.hasClass(c)) {
colore = c;
}
}
var sorting = 9999;
var isoElems = $main.isotope('getItemElements');
var hunt = false;
for (var i=0;i <isoElems.length;i++) {
if (id == isoElems[i].id) {
hunt = true;
continue;
}
if (hunt == true && isoElems[i].offsetLeft == 0) {
if (isoElems[i+1].offsetLeft == 0) {
i++;
}
sorting = $('#' + isoElems[i].id).children('.sorting').text() - 0.5;
break;
}
}
// fix mobile issue
if (num < 7) {
sorting = parseInt(elem.children('p.sorting').text()) + 0.5;
}
var marginesx = elem.offset().left + (elem.width() / 2) - 7 - $('#mainmenu').width();
var newItem = $('<div id="bollino" data-item-id="'+ id + '" class="elemento ballon artigiani has_content_to_display losapevi"><div class="toparrow '+colore+'" style="margin-left: '+marginesx+'px"> </div>'+htmlcontents+'<p class="sorting">'+sorting+'</p></div>');
// calcoliamo la posizione della pagina.
var body_pos = $('#top').offset();
// generiamo il nuovo
$main.append( newItem ).isotope('insert', newItem).isotope({ sortBy: 'sorting' });
elem.children('.hoverBox').addClass('hovered');
if (num < 7){
} else { //$("#appended_to_"+id+" .boxscroll-active").niceScroll({
$("#bollino .boxscroll-active").niceScroll({
cursorcolor:"#000000",
cursoropacitymin: 1,
cursoropacitymax: 1,
cursorwidth: 8,
cursorborder: '0'
});
$("#bollino .boxscroll-active").getNiceScroll().resize();
$("#bollino").mouseover(function(){
$("#bollino .boxscroll-active").getNiceScroll().resize();
})
// definiamo lo scorrimento
setTimeout(function() {
dest = $('#bollino').offset().top;
$('body, html').scrollTo(dest, 300);
}, 500);
}
}
}
// fixed
function hide_bollino () {
var $bollino = jQuery('#bollino');
if ($bollino) {
var activeItem = $bollino.data('item-id');
jQuery('.bollino .boxscroll-active').getNiceScroll().hide();
jQuery('.nicescroll-rails').remove(); // bug in nice scroll
jQuery('#'+activeItem + ' .hoverBox').removeClass('hovered');
$main.isotope('remove', $bollino).isotope('layout');
$bollino.remove();
$bollino = null;
}
}
// fixed
function next_bollino () {
var $bollino = jQuery('#bollino');
if ($bollino){
var activeItem = $bollino.data('item-id');
var $bollini = jQuery('.has_content');
for (i=0; i < $bollini.length; i++){
if ($bollini[i].id == activeItem){
var $nextBollino = $bollini[i+1];
}
}
}
if ($nextBollino){
open_bollino($nextBollino.id);
}
}
// fixed
function prev_bollino () {
var $bollino = jQuery('#bollino');
if ($bollino){
var activeItem = $bollino.data('item-id');
var $bollini = jQuery('.has_content');
for (i=0; i < $bollini.length; i++){
if ($bollini[i].id == activeItem){
var $prevBollino = $bollini[i-1];
}
}
}
if ($prevBollino){
open_bollino($prevBollino.id);
}
}
function filter (className) {
$main.isotope({ filter: '.' + className });
}
function destroy_isotope (){
$main.isotope( isoOptions );
}
function rebuild_isotope( isoOptions ){
$main.isotope( isoOptions );
}
function calculate_dimensions(item_width, num){
var item_height = (item_width);
jQuery('.item').width(item_width).height(item_height);
jQuery('.item-horizontal').width(2*item_width).height(item_height);
jQuery('.item-vertical').width(item_width).height(2*item_height);
jQuery('.item-square').width(2*item_width).height(2*item_height);
jQuery('.hoverChange').width(2*item_height).height(2*item_height);
jQuery('.hoverChangeBack').width(2*item_height).height(2*item_height);
jQuery('.boxscroll').css('width', 3*item_width + 'px');
jQuery('.hoverBox').css('height', '100%');
jQuery('.ballon').width(num*item_width).css('min-height', 2*item_height).css('height', 'auto');
}
function open_popup(uri, scrollable){
var src = uri;
if (scrollable == 1){
addcss = 'scrolling="no" style="padding: 5px; border:0; overflow: hidden;"';
} else {
addcss = 'scrolling="no" style="padding: 5px; border:0; overflow: hidden;"';
}
jQuery.modal('<iframe src="' + src + '" frameborder="0" width="850" height="450" '+ addcss +'>', {
closeHTML:"",
containerCss:{
backgroundColor:"#fff",
width:860,
height:470,
padding:0,
},
overlayClose:true
});
}
function fade_home_top(){
if (jQuery(window).width() > 800) {
window_scroll = jQuery(this).scrollTop();
jQuery(".fadeafterscrolling").css({
'opacity' : 1-(window_scroll/300)
});
}
}
jQuery(function ($) { // all function wrapped in jQuery so it wont confilct with other libs
// when page loaded
recall();
$('#loading').fadeOut();
$('body').css('overflow', 'auto');
// register listeners
$(".elemento").click(function(){
open_bollino(this.id);
});
$(".flip-container").click( function( event ){
$(this).toggleClass('hover');
});
$(window).scroll(fade_home_top).resize(function(){
$('#main').isotope();
recall();
});
$('.parallax').parallax({
speed : 0.10
});
});
Hi yifeikong,
http://www.mercatocentrale.it/homepage-alternativa/
-
1) first load (see this attach: http://www.mercatocentrale.it/home.gif)
2) Click on box and css trouble: http://www.mercatocentrale.it/css.gif
Could you have a look?
Emanuele
Yeah, I see it's broken on your site. But it's fine on my local computer. based on http://dev.lenuslab.com/mcf, I created http://yifeikong.pancakeapps.com/italy/index.html you could check it out here.
There might be some mis-configurations.
yifeikong
Hi, LenusMedia
Here is the file I used. The html file is downloaded from http://dev.lenuslab.com/mcf , the only change I've made is deleting the old script at the bottom of the page and adding my own script, which is the fixed2.js
file. I'm looking into your file meanwhile.
Congratulations!
Now that your task is posted let the world know
Make your task famous