20.072015

JavaScript bei bestimmten Media-Queries ausführen

Möchte man JavaScript Funktionen bei einer bestimmten Bildschirmauflösung ausführen, so bieten sich dazu verschiedene Techniken an. Beispielweise könnte man per window.outerWidth eine bestimmte Pixelbreite des Fensters in Erfahrung bringen und diese Abfragen. Nun ist es so, dass JavaScript Funktionen die auf einer bestimmten Auflösung basieren, häufig mit dem Design der Seite zu tun haben. Für die Steuerung des Designs sollten aber doch CSS-Angaben zuständig sein. Zudem wird es Problematisch wenn sich das Design der Seite ändert und ganz andere Pixelbreitenangaben nötig sind, für die man dann wieder die zweite Baustelle JavaScript bearbeiten und synchron halten muss. Im Folgenden stelle ich ein Grundgerüst vor, dass es erlaubt die Logik JavaScript zu überlassen, und per CSS die Bedingungen für jene zu setzen.

JavaScript steuern per Media-Queries

Für CSS nutzen wir schon lange Media-Queries um Veränderungen der Auflösung zu reflektieren und damit wir das genauso schön mit JavaScript können machen wir uns die Pseudoklasse :before zu nutze. Diese bietet sich an da wir eine Klasse rein zur Abfrage eines Wertes in JS benötigen und außerdem klingt content doch irgendwie noch am passendsten ;) . Sofern wir es nicht für Debug-Zwecke nutzen möchten, blenden wir den content aus und verleihen im je nach aktiven Media-Query einen anderen Wert:

body:before {
    display: none;
    content: 'S';
}

@media only screen and (min-width: 768px) {
  body:before {
      content: 'M';
  }
}

@media only screen and (min-width: 1024px) {
  body:before {
      content: 'L';
  }
}

Die Abfrage der Media-Queries per JavaScript

Nun wollen wir natürlich das ganze Abfragen. Ein kleines Script dazu, welches den Wert von content zurück gibt:

function getMq() {
  return window.getComputedStyle(document.querySelector('body'), ':before').getPropertyValue('content').replace(/"/g, '').replace(/'/g, '');
}

Das Script im Einsatz

Nun kann man bei einem Seitenaufruf in einem If schön abfragen, welcher Media Query grade überhaupt aktiv ist.

if(getMq() == "S"){
  console.log("Media Query S beim Aufruf aktiv");
} else if(getMq() == "M") {
  console.log("Media Query M beim Aufruf aktiv");
} else if(getMq() == "L"){
  console.log("Media Query L beim Aufruf aktiv");
}

Wenn der Media Query sich ändert...

Möchtet ihr mit JavaScript irgendwas während der Laufzeit der Seite machen, müsst ihr damit rechnen das der Media Query sich verändert. Durch die Abfrage eines onresize oder onorientationchange Events kann man darauf reagieren.

Im folgendem ein Beispiel für eine praktische Funktion mit der man beim Wechsel eines Media-Query  reagieren kann.
Durch die eingesetzte Kombination aus setInterval und onresize ist ressourcenschonender wie alles bei jedem Resize Event abzuhandeln.

// Wir checken ob die Größe des Browserfensters sich verändert hat:
var resized = false;
window.onresize = function(event) {
  resized = true;
};

// Dieser function uebergbeben wir eine Mediaquery groesse (S,M,L) und die bei diesem Mediaquery auszufuehrende function:
function doOnMq(Mq, callback) {
  setInterval(function() {
    if (resized === true && getMq() === Mq) {
      callback();
      resized = false;
    }
  }, 250);
}

// functions bei bestimmten Mediaqueries weden ausgeführt
doOnMq("S", function(){console.log("Media Query S ist jetzt aktiv");} );
doOnMq("M", function(){console.log("Media Query M ist jetzt aktiv");});
doOnMq("L", function(){console.log("Media Query L ist jetzt aktiv");} );

Das Script ausprobieren

Zum Ausprobieren und damit spielen habe ich das Script auf JSbin bereitgestellt:

D E M O