Alsacreations.com - Apprendre - Archives (novembre 2012)

Les dernières ressources publiées sur Alsacreations.com

Le: 29 11 2012 à 13:00 Auteur: dew

Vous connaissez certainement les Media Queries CSS. Celles-ci permettent d'adapter les instructions de style appliquées à un document HTML, en fonction de nombreux critères (résolution de l'écran, dimensions, périphérique de sortie). C'est la technique la plus souple et la plus utilisée actuellement pour ajuster dynamiquement l'affichage et obtenir un rendu graphique différent sur écrans classiques, mobiles, tablettes, et autres moyens d'accéder au web.

Avec matchMedia(), les mêmes capacités de détection sont rendues disponibles en JavaScript. La syntaxe de la requête média reste la même, ce qui est bien agréable. Ainsi, il sera possible de déclencher des actions complémentaires à ce que l'on peut déjà construire en CSS, que ce soit au chargement du document ou bien à n'importe quel moment à la demande en exécutant matchMedia().

C'est une méthode qui dépend de l'objet window (la fenêtre du navigateur) et qui prend en argument une chaîne de texte contenant l'expression à tester, pour retourner true ou false via sa propriété matches.

<script>
if (window.matchMedia("(min-width: 600px)").matches) {
  /* La largeur minimum de l'affichage est 600 px inclus */
} else {
  /* L'affichage est inférieur à 600px de large */
}
</script>

Voir la démonstration n°1

Si l'on examine de plus près l'objet retourné dans une console JavaScript...

matchmedia console

Celui-ci est de type MediaQueryList, et équipé de deux propriétés de base :

  • matches (booléen true/false qui permet de faire le test)
  • media (la requête elle-même)

Bien sûr, cette méthode vient en complément de CSS et n'est pas vouée à remplacer les Media Queries là où elles sont déjà efficaces. Le but est de se brancher sur la gestion de la détection pour aller plus loin qu'une conséquence sur l'affichage des éléments.

// Fonction exécutée au redimensionnement
function redimensionnement() {
  var result = document.getElementById('result');
  if("matchMedia" in window) { // Détection
    if(window.matchMedia("(min-width:600px)").matches) {
      // Il y a de la place
    } else {
      // Il y en a moins...
    }
  }
}
// On lie l'événement resize à la fonction
window.addEventListener('resize', redimensionnement, false);

L'événement resize est tout indiqué pour déclencher une vérification avec matchMedia(). Consultez l'exemple suivant pour le voir en action.

Voir la démonstration n°2

Le dernier exemple va plus loin en chargeant des fichiers JavaScript selon le résultat renvoyé par matchMedia().

if(window.matchMedia("(min-width:800px)").matches) {
  // Chargement de jQuery dans un nouvel élément <script> ajouté à la section <head>
  var script1 = document.createElement('script');
  script1.type='text/javascript';
  script1.src = '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js';
  script1.onload = function() {
    // Lorsque jQuery est chargé...
    // On fait la même chose : chargement dynamique // mais cette fois-ci avec jQuery (c'est plus simple)
    $.getScript('slideshow.js');
  }
  // Insertion dans le DOM de la balise script initiale
  document.getElementsByTagName('head')[0].appendChild(script1);
}

Il s'agit de faire appel à jQuery et un autre fichier de script conçu sur mesure pour lancer un slideshow si la largeur de l'affichage le permet.

Voir la démonstration n°3

Cette technique ici sert uniquement à la démonstration et exploite un script minimaliste pour sa compréhension. L'intérêt majeur serait de pouvoir détecter ce que l'on ne peut pas faire avec du JavaScript conventionnel, par exemple l'orientation (mentionnée précédemment) ou la densité de pixels pour charger des images appropriées : une démonstration est disponible sur Thinkmobilefirst : Conditional retina pictures loading.

Tableau des compatibilités

Navigateurs Versions
Internet Explorer Internet Explorer 10
Firefox Firefox 6 Firefox Android 15
Chrome Chrome 9 Chrome Mobile 18 (Android 4+)
Opera Opera 12.1 Opera Mobile 12.1
Safari

Safari 5.1 Safari Mobile 5.0

Android Browser Android Browser 3.0
Blackberry Logo Blackberry Browser 10

Pour les anciens moteurs qui ne supporteraient pas nativement matchMedia, il existe des bibliothèques JavaScript, détectant (du mieux qu'elles peuvent) les changements d'état, notamment matchMedia.js développée par Paul Irish.

Le: 05 11 2012 à 11:00 Auteur: dew

Une petite fonctionnalité qui peut faire beaucoup de différence sur le temps de développement : classList est une des propriétés d'un élément HTML (accessibles en JavaScript) assez méconnue. Et pour cause, elle n'est supportée qu'à partir d'Internet Explorer 10, ce qui a longtemps freiné son utilisation (des scripts aidant les versions antérieures sont mentionnés au bas de cet article).

L'API classList permet d'accéder à la liste des classes appliquées à un élément HTML, de manière simple et efficace via les méthodes suivantes :

  • length : retourne le nombre de classes
  • add(nom_classe) : ajoute une classe
  • contains(nom_classe) : retourne true si une classe est présente et false sinon
  • remove(nom_classe) : supprime une classe
  • toggle(nom_classe) : ajoute ou supprime une classe, si elle est présente initialement ou non
  • toString() : retourne la chaîne de texte complète

Ceci autorise des changements dynamiques, de style principalement, dans le document, en appliquant ou non des classes, à la volée, par exemple suite à des actions de l'utilisateur. En revanche, cela suppose d'avoir au préalable sélectionné un élément, entre autres grâce aux méthodes DOM de sélection telles que document.getElementById, document.getElementsByClassName, ou des fonctions plus récentes telles que querySelector et querySelectorAll de l'API Selectors.

<div id="monid"></div>

<script>
var monelement = document.getElementById('monid');
monelement.classList.add('maclasse');
monelement.classList.remove('maclasse');
monelement.classList.toggle('maclasse');
monelement.classList.contains('maclasse');
var nb_classes = monelement.classList.length;
</script>

Voir la démonstration n°1 

On peut aller au-delà du simple style graphique, et s'en servir pour catégoriser des éléments (l'attribut class est conçu pour cela !).

// Sélection grâce à querySelectorAll
var liens = document.querySelectorAll('#galerie a');
for (var i = 0; i < liens.length; i++) {
  liens[i].onclick = function() {
    this.classList.toggle('hopla');
    return false;
  }
};

// Comptage
document.getElementById('btnlength').onclick = function() {
  alert(document.querySelectorAll('#galerie a.hopla').length);
};

Consultez la source du document pour découvrir les fonctions appliquées.

Voir la démonstration n°2 

En combinant ces quelques techniques, il devient inutile de charger la bibliothèque jQuery (qui dispose de ses propres méthodes addClasstoggleClassremoveClass, etc) pour effectuer ces actions.

Tableau des compatibilités

Navigateurs Versions
Internet Explorer Internet Explorer 10
Firefox Firefox 3.6
Chrome Chrome 8
Chrome Mobile 18 (Android 4+)
Opera Opera 11.5
Opera Mobile 11.1
Safari

Safari 5.1
Safari Mobile 5.0

Android Browser Android Browser 3.0
Blackberry Logo Blackberry Browser 7

Pour les plus anciens navigateurs, il existe deux polyfills JavaScript : classList.js et classList shim.