L'élément HTML5 progress
Petite introduction à l'utilisation de l'élément progress, apparu dans les recommendations HTML 5.
Introduction
L'élément progress est un nouvel élément qui permet de créer un objet plutôt courant dans les librairies graphiques d'applications : représenter la progression d'un traitement, d'une tâche, d'une action. Il se traduit simplement par une barre verticale ou horizontale qui se « remplit » au cours du temps et dont l'apparence varit en fonction du navigateur web et du système d'exploitation.
<progress value="0.7">70%</progress>
progress.Si vous affichez cette page avec Internet Explorer, Safari, Chrome < 6, Firefox < 6 ou Opera < 11, vous ne verrez pas grand chose, sans doute uniquement le texte contenu dans l'élément. Ces « anciens » navigateurs ne savent pas comment rendre un élément HTML portant le nom « progress ». Nous allons voir comment apporter un minimum de support avec un peu de CSS et du javascript.
Le principe est simple : la mise en forme de l'élément se fera à travers la classe « progress » ; celle-ci ne sera appliquée que si le navigateur ne gère pas nativement l'élément ; enfin, une fonction générique permettra de mettre à jour la valeur de progression. Par ailleurs :
- Les fonctions seront volontairement simplifiées pour éviter de surcharger le code.
- Toutes les caractéristiques de l'élément progress ne seront pas simulées (orientation, état indeterminé).
Il s'agit ici avant tout de comprendre et d'implémenter les bases du fonctionnement de l'élément.
Appliquer les traitements
La première étape consiste donc à déterminer si le navigateur gère nativement les éléments progress :
/**
* Le navigateur gère-t-il nativement progress ?
* @type Boolean
*/
var supportsProgress = ('value' in document.createElement('progress')) ? true : false;
progress.Si ce n'est pas le cas, nous allons chercher tous les éléments progress de la page pour les traiter convenablement avec une fonction dédiée, initProgress :
if (!supportsProgress) {
var els = document.body.getElementsByTagName('progress'),
i, n = els.length;
for (i = 0; i < n; i++) {
initProgress(els[i]);
}
}
Initialiser les éléments
La fonction d'initialisation va effectuer plusieurs traitements :
- Ajouter un élement enfant pour pouvoir simuler la progression.
- Appliquer la classe
progressqui permet la mise en forme. - Ajouter les propriétés
valueetmaxà l'élément. - Initialiser la valeur de progression.
/**
* Méthode d'initialisation des éléments progress
* @param {HTMLProgressElement} el Elément progress à initialiser
*/
var initProgress = function (el) {
var
// Element enfant à ajouter
span = document.createElement('span');
// contenu textuel de l'élément
textNode = el.firstChild || document.createTextNode(' '),
// Valeur de progression
value = el.getAttribute('value') || 0,
// valeur maximale
maxi = el.getAttribute('max') || 1;
// append markup
span.appendChild(textNode);
el.appendChild(span);
// define className
el.className = el.className + ' progress';
// init values
updateProgress(el, parseFloat(value, 10), parseFloat(maxi, 10));
};
progress.Comme préciser plus haut, il s'agit ici d'une version simplifiée de ce qu'il faudrait faire. Nous devrions par exemple vérifier que l'élément ne contienne pas déjà un élément enfant, et utiliser celui-ci au lieu d'en créer un artificiellement.
Définir la valeur de progression
La modification de la valeur de progression est assurer par la fonction updateProgress, en faisant varier la taille de l'élément enfant que la fonction initProgress à préalablement inséré :
/**
* Mettre à jour la valeur d'un élément progress.
* @param {HTMLProgressElement} el Elément progress à initialiser.
* @param {Number} value Nouvelle valeur (doit être supréieure à -1).
* @param {Number} [maxi] Si la valeur maximale est aussi à modifier (doit être positive).
*/
var updateProgress = function (el, value, maxi) {
if (maxi && maxi !== el.max) {
el.max = maxi;
el.setAttribute('max', maxi);
}
if (value < 0) {
value = 0;
} else if (value > el.max) {
value = el.max;
}
if (value !== el.value) {
el.value = value;
if (!supportsProgress) {
var w = (el.clientWidth * (el.value/el.max)) + 'px';
if (value === null) {
w = 0;
el.removeAttribute('value');
} else {
el.setAttribute('value', value);
}
el.firstChild.style.width = w;
}
}
};
Nous utilisons le test supportsProgress pour pouvoir utiliser la même fonction à la fois avec les navigateurs gérant nativement progress et ceux ne le gérant pas.
Là aussi, le traitement est simplifié : pour un élément progress vertical, les grandeurs à récupérer et à calculer ne seront pas les mêmes.
Mise en forme
Il ne nous reste plus qu'à définir les règles css pour assurer le rendu. Ce rendu variant grandement selon les navigateurs et le système d'exploitation, nous appliquerons un look dés plus simple.
.progress {
/* flow content */
display: inline-block;
/* size */
height: 1em;
width: 10em;
/* typo */
font-size: 1em;
line-height: 1;
vertical-align: middle;
/* box */
padding: 0;
margin: 0;
/* borders */
border-width: 1px;
border-style: solid;
-webkit-border-radius: 0.5em;
-moz-border-radius: 0.5em;
border-radius: 0.5em;
/* colors */
background: #E6E6E6;
border-color: #666;
}
.progress > span {
/* flow content */
display: inline-block;
/* size */
height: 1em;
/* borders */
-webkit-border-radius: 0.5em;
-moz-border-radius: 0.5em;
border-radius: 0.5em;
/* colors */
background: #999;
color: #999;
}
Exemple d'utilisation
<p>
<progress id="myProgress" value="0.2">20%</progress>
<button id="update">Mise à jour</button>
</p>
progress avec un bouton de mise à jour.// code javascript précédent
document.getElementById('update').addEventlistener('click', function (e) {
var el = document.getElementById('myProgress');
updateProgress(el, el.value + 0.2);
}, false);
Ressources et références
. HTML 5. W3C, . 4.10.16 The progress element
. HTML 5. W3C, . 10.4.13 The progress element
. progress. Mozilla Developer Network,