Responsive JavaScript

Zilele trecute a trebuit să lucrez la un site responsive ce folosea Isotope (mai bine zis masonry) pentru layout. Problema era că aveam un număr diferit de coloane, în funcție de rezolutie: trei coloane pentru mai mult de 1000px lățime, două pentru intervalul 501-999px și una pentru ce era sub 500px. Desigur, în caz de resize, numărul de coloane ar fi trebuit să se ajusteze corespunzător.

Prima idee care mi-a trecut prin cap a fost:

function getNumberOfColumns() {
  var windowWidth = $(window).width();
  if( windowWidth <= 500 ){
    return 1;
  }else if ( windowWidth > 500 && windowWidth < 1000 ){
    return 2;
  }else {
    return 3;
  }
}

$(window).on('resize', function(){
  var tiles = $('#tiles');
  tiles.isotope({
    masonry: {
      columnWidth: tiles.width() / getNumberOfColumns()
    }
  });
});

E o soluție aproape bună. Ce probleme apar?

Presupunând că se răzgândește clientul și vrea să schimbe puțin layout-ul, adăugând încă vreo două coloane, având un total de cinci breakpoints. Va trebui să schimbăm CSS (să adăugăm breakpoints pentru stilizare) dar să edităm și funcția de mai sus, adăugând două condiții noi. Încălcăm astfel principiul DRY dar este și un tight coupling din care sigur nu are cum să iasă ceva bun.

Prin urmare, m-am gândit la următoarea chestie: ce-ar fi dacă am un element HTML (fie hard coded, fie injectat cu JS) și îi setez un stil diferit pentru fiecare breakpoint?

#responsiveBreakpointDetector { font-size:1px; }

@media all and (min-width:501px) and (max-width:999px) {
  #responsiveBreakpointDetector { font-size:2px; }
}

@media all and (min-width:1000px) {
  #responsiveBreakpointDetector { font-size:1px; }
}

Acum, dacă folosim jQuery/Zepto (sau orice bibliotecă), putem citi font-size și vom ști imediat la ce breakpoint ne aflăm:

function responsiveBreakpointDetector() {
  return parseInt( $('#responsiveBreakpointDetector').css('fontSize'), 10 );
}

Sigur, putem face același lucru și fără nici o bibliotecă:

function getStyle( el, styleProp ) { // http://stackoverflow.com/a/1955160/23810
  var camelize = function( str ) {
    return str.replace( /\-(\w)/g, function( str, letter ){ return letter.toUpperCase(); });
  };
  if ( document.defaultView && document.defaultView.getComputedStyle ){
    return document.defaultView.getComputedStyle( el, null ).getPropertyValue( styleProp );
  } else {
    return el.style[ camelize( styleProp ) ];
  }
}

function responsiveBreakpointDetector() {
  var container = document.getElementById('responsiveBreakpointDetector');
  return parseInt( getStyle(container, 'font-size' ), 10 );
}

În ambele situații, apelarea funcției responsiveBreakpointDetector() ne va spune ce font-size (respectiv câte coloane) avem. Putem adăuga oricâte breakpoints din CSS fără a edita absolut nimic în JavaScript.

Resurse

Ți-a plăcut articolul? Lasă un comentariu!

You can insert code snippets using BBcode:
[js].[/js] [html].[/html] [php].[/php] [css].[/css]
You can also use some HTML tags:
<blockquote>.</blockquote> <code>.</code> <a href="">.</a> <strong>.</strong> <em>.</em>

windows apple dropbox facebook twitter