Les images

Les objets natifs en JavaScript couvrent de nombreux domaines comme le temps ou les mathématiques, mais il existe des objets encore plus particuliers commeImage! Cet objet permet de faire des manipulations assez sommaires sur une image et permet surtout de savoir si elle a été entièrement téléchargée, c'est généralement pour cela que l'on va se servir de cet objet.

L'objet Image

Comme dit dans l'introduction, la manipulation des images se fait par le biais de l'objetImage, qui possède plusieurs propriétés permettant d'obtenir divers renseignements sur l'image actuellement instanciée.

Le constructeur

Le constructeur de l'objetImagene prend aucun argument en paramètre, cela a au moins le mérite d'être simple :

var myImg = new Image();

Propriétés

Voici une liste non exhaustive des propriétés de l'objetImage. Consultez la documentation pour une liste complète (mais pas forcément fiable).

Nom de la propriété

Contient…

width

Contient la largeur originale de l'image. Vous pouvez redéfinir cette propriété pour modifier la taille de l'image.

height

Contient la hauteur originale de l'image. Vous pouvez redéfinir cette propriété pour modifier la taille de l'image.

src

Cette propriété vous sert à spécifier l'adresse (absolue ou relative) de l'image. Une fois que cette propriété est spécifiée, l'image commence immédiatement à être chargée.

Événements

L'objetImagene possède qu'un seul événement nomméload, il est très utile, notamment lorsque l'on souhaite créer un script de type Lightbox , car il vous permet de savoir quand une image est chargée.

Son utilisation se fait comme tout événement :

var myImg = new Image();
myImg.src = 'adresse_de_mon_image';
myImg.addEventListener('load', function() {
// Etc.
});

Cependant, ce code risque de causer un problème majeur : notre événement pourrait ne jamais se déclencher ! Pourquoi donc ? Eh bien, parce que nous avons spécifié l'adresse de notre image avant même d'avoir spécifié notre événement, ce qui fait que si l'image a été trop rapidement chargée, l'événementloadse sera déclenché avant même que nous n'ayons eu le temps de le modifier.

Il existe une solution toute simple pour pallier ce problème, il suffit de spécifier l'adresse de notre image après avoir modifié notre événement :

var myImg = new Image();
myImg.addEventListener('load', function() { // Étape 1 : on modifie notre événement
// Etc.
});
myImg.src = 'adresse_de_mon_image'; // Étape 2 : on spécifie l'adresse de notre image

Ainsi, vous n'aurez aucun problème : votre événement sera toujours déclenché !

Particularités

L'objetImageest un peu spécial, dans le sens où vous pouvez l'ajouter à votre arbre DOM comme vous le feriez avec la valeur retournée par la méthodedocument.createElement(). Ce comportement est spécial et ne peut se révéler utile que dans de très rares cas d'application, mais il est quand même préférable de vous en parler afin que vous connaissiez l'astuce :

var myImg = new Image();
myImg.src = 'adresse_de_mon_image';
document.body.appendChild(myImg); // L'image est ajoutée au DOM

Mise en pratique

Nous allons rapidement voir une petite mise en pratique de l'objetImageen réalisant une Lightbox très simple. Le principe d'une Lightbox est de permettre l'affichage d'une image en taille réelle directement dans la page Web où se trouvent les miniatures de toutes nos images.

Commençons tout d'abord par un code HTML simple pour lister nos miniatures et les liens vers les images originales :

<p>
<a href="imgs/1.jpg" title="Afficher l'image originale"><img src="imgs/1_min.jpg" alt="Miniature" /></a>
<a href="imgs/2.jpg" title="Afficher l'image originale"><img src="imgs/2_min.jpg" alt="Miniature" /></a>
<a href="imgs/3.jpg" title="Afficher l'image originale"><img src="imgs/3_min.jpg" alt="Miniature" /></a>
<a href="imgs/4.jpg" title="Afficher l'image originale"><img src="imgs/4_min.jpg" alt="Miniature" /></a>
</p>

Notre but ici est de bloquer la redirection des liens et d'afficher les images d'origine directement dans la page Web, plutôt que dans une nouvelle page. Pour cela, nous allons devoir parcourir tous les liens de la page, bloquer leurs redirections et afficher l'image d'origine une fois que celle-ci aura fini d'être chargée (car une Lightbox est aussi conçue pour embellir la navigation).

Commençons par parcourir les liens et bloquons leurs redirections :

var links = document.getElementsByTagName('a'),
linksLen = links.length;
for (var i = 0; i < linksLen; i++) {
links[i].addEventListener('click', function(e) {
e.preventDefault(); // On bloque la redirection
// On appelle notre fonction pour afficher les images
// currentTarget est utilisé pour cibler le lien et non l'image
displayImg(e.currentTarget);
});
}

Vous pouvez constater que nous faisons appel à une fonctiondisplayImg()qui n'existe pas, nous allons donc la créer !

Que doit donc contenir notre fonction ? Il faut tout d'abord qu'elle commence par charger l'image originale avant de l'afficher, commençons par cela :

function displayImg(link) {
var img = new Image();
img.addEventListener('load', function() {
// Affichage de l'image
});
img.src = link.href;
}

Avant de commencer à implémenter l'affichage de l'image, il nous faut tout d'abord mettre en place un overlay. Mais qu'est-ce que c'est ? En développement Web, il s'agit généralement d'une surcouche sur la page Web, permettant de différencier deux couches de contenu. Vous allez vite comprendre le principe quand vous le verrez en action. Pour l'overlay, nous allons avoir besoin d'une balise supplémentaire dans notre code HTML :

<div id="overlay"></div>

Et nous lui donnons un style CSS afin qu'il puisse couvrir toute la page Web :

#overlay {
display : none; /* Par défaut, on cache l'overlay */
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
text-align: center; /* Pour centrer l'image que l'overlay contiendra */
/* Ci-dessous, nous appliquons un background de couleur noire et d'opacité 0.6. Il s'agit d'une propriété CSS3. */
background-color: rgba(0,0,0,0.6);
}

Maintenant, le principe va être d'afficher l'overlay quand on cliquera sur une miniature. Il faudra aussi mettre un petit message pour faire patienter le visiteur pendant le chargement de l'image. Une fois l'image chargée, il ne restera plus qu'à supprimer le texte et à ajouter l'image originale à la place. Allons-y !

function displayImg(link) {
var img = new Image(),
overlay = document.getElementById('overlay');
img.addEventListener('load', function() {
overlay.innerHTML = '';
overlay.appendChild(img);
});
img.src = link.href;
overlay.style.display = 'block';
overlay.innerHTML = '<span>Chargement en cours...</span>';
}

Voilà, notre image se charge et s'affiche, mais il nous manque une chose : pouvoir fermer l'overlay pour choisir une autre image ! La solution est simple, il suffit de quitter l'overlay lorsque l'on clique quelque part dessus :

document.getElementById('overlay').addEventListener('click', function(e) {
// currentTarget est utilisé pour cibler l'overlay et non l'image
e.currentTarget.style.display = 'none';
});

Il ne nous reste plus qu'à ajouter un petit bout de CSS pour embellir le tout, et c'est fini :

#overlay img {
margin-top: 100px;
}
p {
margin-top: 300px;
text-align: center;
}

Et voilà ! Notre Lighbox ultra-minimaliste est terminée !

Vous pouvez essayer le script ici ! Nous vous redonnons les codes complets si vous souhaitez travailler dessus :

<p>
<a href="imgs/1.jpg" title="Afficher l'image originale"><img src="imgs/1_min.jpg" alt="Miniature" /></a>
<a href="imgs/2.jpg" title="Afficher l'image originale"><img src="imgs/2_min.jpg" alt="Miniature" /></a>
<a href="imgs/3.jpg" title="Afficher l'image originale"><img src="imgs/3_min.jpg" alt="Miniature" /></a>
<a href="imgs/4.jpg" title="Afficher l'image originale"><img src="imgs/4_min.jpg" alt="Miniature" /></a>
</p>
<div id="overlay"></div>
#overlay {
display : none; /* Par défaut, on cache l'overlay */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center; /* Pour centrer l'image que l'overlay contiendra */
/* Ci-dessous, nous appliquons un background de couleur noire et d'opacité 0.6. Il s'agit d'une propriété CSS3. */
background-color: rgba(0,0,0,0.6);
}
#overlay img {
margin-top: 100px;
}
p {
margin-top: 300px;
text-align: center;
}
var links = document.getElementsByTagName('a'),
linksLen = links.length;
for (var i = 0; i < linksLen; i++) {
links[i].addEventListener('click', function(e) {
e.preventDefault(); // On bloque la redirection
// On appelle notre fonction pour afficher les images
// currentTarget est utilisé pour cibler le lien et non l'image
displayImg(e.currentTarget);
});
}
function displayImg(link) {
var img = new Image(),
overlay = document.getElementById('overlay');
img.addEventListener('load', function() {
overlay.innerHTML = '';
overlay.appendChild(img);
});
img.src = link.href;
overlay.style.display = 'block';
overlay.innerHTML = '<span>Chargement en cours...</span>';
}
document.getElementById('overlay').addEventListener('click', function(e) {
// currentTarget est utilisé pour cibler l'overlay et non l'image
e.currentTarget.style.display = 'none';
});

Comme nous vous l'avons précisé plus tôt, ce script est actuellement inutilisable sur un site en production. Cependant, si vous souhaitez améliorer ce code afin de le publier, nous vous conseillons d'étudier ces quelques points :

  • Évitez d'appliquer l'événementclickà tous les liens de la page. Ajoutez un élément différenciateur aux liens de la Lightbox, tel qu'une classe ou un attributname.

  • Redimensionnez dynamiquement les images originales afin d'éviter qu'elles ne débordent de la page. Utilisez soit un redimensionnement fixe (très simple à faire), soit un redimensionnement variant selon la taille de l'écran (des recherches sur le Web seront nécessaires).

  • Implémentez l'utilisation des touches fléchées : flèche droite pour l'image suivante, flèche gauche pour la précédente.

  • Faites donc quelque chose de plus beau, notre exemple est vraiment moche ! :-°

En résumé
  • L'objetImageest généralement utilisé pour s'assurer qu'une image a été chargée, en utilisant l'événementload().

  • Il est possible d'ajouter uneImagedirectement dans l'arbre DOM, mais ce n'est pas chose courante.