r-michel
8/6/2015 - 1:32 PM

Egalise des lignes de blocs par sous éléments

Egalise des lignes de blocs par sous éléments

/*
 * Egalisation de blocs par ligne
 * @container : sélecteur bloc parent
 * @child : sélecteur éléments ligne
 * @adapt : tabelau sélecteurs sous éléments enfants à égaliser
 * @breakpoints : tableau des breakpoints avec nb d'éléments par ligne attendus
 *                ex : {0: 1, 768: 2, 1024: 3}
 * @statics : tableau des classes d'éléments de hauteur statique
 */
var equalRows = function(container, childs, adapt, breakpoints, statics) {
  if(isProcessingRows) {
    return;
  }
  isProcessingRows = true;
  statics = (typeof statics === 'undefined') ? [] : statics;
  
  // Calcul nb éléments par ligne
  var items_per_line = 0;
  var elements = $(container+' '+childs);
  for(var breakpoint in breakpoints) {
    if($(window).width() >= breakpoint) {
      items_per_line = breakpoints[breakpoint];
    }
  }
  if(items_per_line === 0 || $(elements).size() <= 1) {
    isProcessingRows = false;
    return;
  } else if(items_per_line == 1) { // Mobile
    $(adapt, elements).removeAttr('style');
  } else {
    var classes, item, is_static;
    var heights = buildHeightObject(adapt);
    $(elements).each(function(index) {
      item = this;
      is_static = hasClasses(statics, item);
      if(!is_static) {
        // Calcul hauteurs max
        $.each(heights, function(el, height) {
          if($(el, item).length) {
            $(el, item).removeAttr('style');
            heights[el] = ($(el, item).height() > height) ? $(el, item).height() : height;
          }
        });
      } else {
        heights.static_height = ($(item).outerHeight() > heights.static_height) ? $(item).outerHeight() : heights.static_height;
      }
      if(index > 0 && (index+1) % items_per_line === 0 || index == $(elements).size()-1) {
        // Attribution nouvelles hauteurs
        var item_l, dyn_item;
        for(var i = index; i > (index - items_per_line); i--) {
          item_l = $(container+' '+childs+':eq('+i+')');
          if(!hasClasses(statics, item_l)) {
            $.each(heights, function(el, height) {
              if($(el, item_l).length) {
                $(el, item_l).css('min-height', height);
                dyn_item = item_l;
              }
            });
          }
        }
        // Si bloc(s) statique(s) présent dans la ligne
        if(heights.static_height > 0 && dyn_item) {
          if(heights.static_height > $(dyn_item).outerHeight()) {
            // Bloc(s) statique(s) supérieur(s) aux blocs dynamiques
            var last_s_el = adapt[adapt.length-1];
            heights[last_s_el] += heights.static_height - $(dyn_item).outerHeight();
            // Réattribution hauteurs
            for(i = index; i > (index - items_per_line); i--) {
              item_l = $(childs+':eq('+i+')', container);
              if(!hasClasses(statics, item_l)) {
                $(last_s_el, item_l).css('min-height', heights[last_s_el]);
              } else {
                newHeight = (($(item_l).outerHeight() - $(item_l).height()) > 0) ?
                $(dyn_item).outerHeight() - ($(item_l).outerHeight() - $(item_l).height()) :
                $(dyn_item).outerHeight();
                $(item_l).css('min-height', newHeight);
              }
            }
          } else {
            // Si bloc(s) statique(s) inférieur(s) aux blocs dynamiques
            var newHeight;
            for(i in statics) {
              newHeight = (($(elements+'.'+statics[i]).outerHeight() - $(elements+'.'+statics[i]).height()) > 0) ?
              $(dyn_item).outerHeight() - ($(elements+'.'+statics[i]).outerHeight() - $(elements+'.'+statics[i]).height()) :
              $(dyn_item).outerHeight();
              $(elements+'.'+statics[i]).css('min-height', newHeight);
            }
          }
        }
        // Reset hauteurs (nouvelle ligne)
        heights = buildHeightObject(adapt);
      }
    });
  }
  isProcessingRows = false;
}
var buildHeightObject = function(properties) {
  var object_heights = {};
  for(var i = 0; i < properties.length; i++) {
	object_heights[properties[i]] = 0;
  }
  object_heights.static_height = 0;
  return object_heights;
}
var hasClasses = function(classes, el) {
  if(classes.length === 0) {
	return false;
  }
  var haveOneClass = false;
  var el_classes = $(el).attr('class').split(/\s+/);
  $.each(el_classes, function(index, item) {
	if($.inArray(item, classes) >= 0) {
    haveOneClass = true;
	}
  });
  return haveOneClass;
}
var isProcessingRows = false;


/**
 * Exemple d'appel
 */
var responsiveGrid = function() {
  equalRows(
	'#block-view',
	'.views-row',
	['h2', '.field-content'],
	{0: 1, 768: 2, 1030: 3},
	['views-row-static']
  );
}
$(document).ready(function() {
  responsiveGrid();
  $(window).resize(function() {
    responsiveGrid();
  });
});