Présentation▲
Il existe de nombreux scripts de fenêtres modales (de type pop-up) simples à implémenter et élégantes.
Mais la plupart du temps, ces scripts peuvent rentrer en conflit avec la logique propre de la page.
J'ai été récemment confronté à un cas où il m'était impossible d'utiliser les scripts comme
fancybox ou prettyPhoto.
J'ai donc dû développer ma propre fenêtre modale pour y insérer du code (X)HTML.
Je vais vous expliquer comment j'ai procédé.
La structure HTML▲
Commençons par ajouter une balise <a> avec les attributs suivants :
- href - #?w=500 : spécifie la largeur de la fenêtre ;
- rel : définit la relation avec la pop-up à ouvrir ;
- class="poplight" : classe CSS pour gérer les pop-up.
<a href
=
"#?w=500"
rel
=
"popup_name"
class
=
"poplight"
>
En savoir plus</a>
Ensuite, nous ajoutons le code (X)HTML des fenêtres.
Vous pouvez les placer où vous voulez dans la page, pour ma part, j'ai opté pour les mettre en fin de code.
Notez bien que l'attribut id correspond à l'attribut rel de la balise <a>.
Cela permet d'établir la relation entre le lien et la fenêtre correspondante.
La mise en forme avec le CSS▲
Le code CSS est commenté afin de vous expliquer comment il fonctionne.
Notez que nous ne précisons pas le margin pour la classe .popup_block :
comme la taille de la fenêtre peut varier, c'est jQuery qui le calculera à l'étape suivante.
#fade
{
/*--Masque opaque noir de fond--*/
display:
none
;
/*--masqué par défaut--*/
background:
#000
;
position:
fixed
;
left
:
0
;
top
:
0
;
width:
100
%;
height:
100
%;
opacity:
.80;
z-index:
9999
;
}
.popup_block
{
display:
none
;
/*--masqué par défaut--*/
background:
#fff
;
padding:
20
px;
border:
20
px solid
#ddd
;
float:
left
;
font-size:
1.2
em;
position:
fixed
;
top
:
50
%;
left
:
50
%;
z-index:
99999
;
/*--Les différentes définitions de Box Shadow en CSS3--*/
-webkit-box-shadow:
0
px 0
px 20
px #000
;
-moz-box-shadow:
0
px 0
px 20
px #000
;
box-shadow:
0
px 0
px 20
px #000
;
/*--Coins arrondis en CSS3--*/
-webkit-border-radius:
10
px;
-moz-border-radius:
10
px;
border-radius:
10
px;
}
img.btn_close
{
float:
right
;
margin:
-55px -55px 0
0
;
}
/*--Gérer la position fixed pour IE6--*/
*
html #fade
{
position:
absolute
;
}
*
html .popup_block
{
position:
absolute
;
}
Mise en place de jQuery▲
Pour ceux qui ne sont pas familiers avec jQuery, je vous invite à mieux connaitre cette librairie sur leur site pour comprendre comment elle fonctionne.
Vous pouvez choisir de téléchargerTélécharger jQuery ou de le charger depuis le site Google.
<script type
=
"text/javascript"
src
=
"http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"
></script>
Après avoir chargé jQuery, vous pouvez ouvrir une nouvelle balise <script>
et commencer votre code avec l'événement $(document).ready,
ce qui permet au code jQuery d'être exécuté dès que le DOM est disponible.
Le reste du code nécessaire au script s'y trouvera.
$(
document
).ready
(
function(
) {
//Le code ici
}
);
La touche finale : le code jQuery▲
Le code suivant est commenté pour vous permettre de comprendre le fonctionnement du script.
//Lorsque vous cliquez sur un lien de la classe poplight et que le href commence par #
$(
'a.poplight[href^=#]'
).click
(
function(
) {
var popID =
$(
this).attr
(
'rel'
);
//Trouver la pop-up correspondante
var popURL =
$(
this).attr
(
'href'
);
//Retrouver la largeur dans le href
//Récupérer les variables depuis le lien
var query=
popURL.split
(
'?'
);
var dim=
query[
1
]
.split
(
'&'
);
var popWidth =
dim[
0
]
.split
(
'='
)[
1
];
//La première valeur du lien
//Faire apparaitre la pop-up et ajouter le bouton de fermeture
$(
'#'
+
popID).fadeIn
(
).css
({
'width'
:
Number(
popWidth)
}
)
.prepend
(
'<a href="#" class="close"><img src="close_pop.png" class="btn_close" title="Fermer" alt="Fermer" /></a>'
);
//Récupération du margin, qui permettra de centrer la fenêtre - on ajuste de 80px en conformité avec le CSS
var popMargTop = (
$(
'#'
+
popID).height
(
) +
80
) /
2
;
var popMargLeft = (
$(
'#'
+
popID).width
(
) +
80
) /
2
;
//On affecte le margin
$(
'#'
+
popID).css
({
'margin-top'
:
-
popMargTop,
'margin-left'
:
-
popMargLeft
}
);
//Effet fade-in du fond opaque
$(
'body'
).append
(
'<div id="fade"></div>'
);
//Ajout du fond opaque noir
//Apparition du fond - .css({'filter' : 'alpha(opacity=80)'}) pour corriger les bogues de IE
$(
'#fade'
).css
({
'filter'
:
'alpha(opacity=80)'
}
).fadeIn
(
);
return false;
}
);
//Fermeture de la pop-up et du fond
$(
'a.close, #fade'
).live
(
'click'
,
function(
) {
//Au clic sur le bouton ou sur le calque...
$(
'#fade , .popup_block'
).fadeOut
(
function(
) {
$(
'#fade, a.close'
).remove
(
);
//...ils disparaissent ensemble
}
);
return false;
}
);
Démo et conclusion▲
Voir la démo en ligneVoir la démo
Si vous êtes à l'aise avec jQuery et que vous voyez des améliorations à apporter au code, n'hésitez pas à les proposer.
À l'inverse, si vous êtes débutant et que des points ne vous semblent pas clairs, faites la demande sur le forum.
66 commentaires
Mise à jour février 2013▲
Depuis la première publication de cet article très populaire, jQuery a beaucoup évolué et le code de la démonstration est devenu incompatible avec les versions les plus récentes de la bibliothèque.
Il nous a donc paru utile de le mettre à jour. Cependant, nous avons souhaité respecter au maximum le script initial tout en rendant la page compatible avec les standards actuels.
La structure HTML▲
Nous avons passé le code HTML en HTML5.
Peu de choses ont évolué si ce n'est le doctype et la déclaration de charset.
Cependant, la modification la plus importante va permettre d'avoir un code jQuery plus concis : nous avons décidé de ne plus utiliser l'attribut rel ni l'attribut href
pour déterminer quelle popup devra être ouverte ainsi que ses dimensions,
en effet, ces attributs ne sont pas destinés à ce genre d'information et rendent la page sémantiquement fausse.
À la place, nous utiliserons les attributs data-* de HTML5. data-width correspondra aux dimensions voulues, data-rel à l'identifiant de la popup à afficher.
Voici comment se présentent désormais les liens :
<a href
=
"#"
data-width
=
"500"
data-rel
=
"popup1"
class
=
"poplight"
>
Voir la pop-up - Width = 500px</a>
Le code jQuery▲
Le code jQuery correspond à la version 1.9.1 qui est la dernière disponible au moment de cette mise à jour, elle est chargée depuis le CDN de jQuery :
<script src
=
"http://code.jquery.com/jquery-1.9.1.min.js"
></script>
La modification majeure consiste à remplacer les affectations d'événements (.click() et surtout .live()) par la méthode recommandée .on().
Le code jQuery complet est le suivant :
jQuery
(
function(
$){
//Lorsque vous cliquez sur un lien de la classe poplight
$(
'a.poplight'
).on
(
'click'
,
function(
) {
var popID =
$(
this).data
(
'rel'
);
//Trouver la pop-up correspondante
var popWidth =
$(
this).data
(
'width'
);
//Trouver la largeur
//Faire apparaitre la pop-up et ajouter le bouton de fermeture
$(
'#'
+
popID).fadeIn
(
).css
({
'width'
:
popWidth}
).prepend
(
'<a href="#" class="close"><img src="close_pop.png" class="btn_close" title="Close Window" alt="Close" /></a>'
);
//Récupération du margin, qui permettra de centrer la fenêtre - on ajuste de 80px en conformité avec le CSS
var popMargTop = (
$(
'#'
+
popID).height
(
) +
80
) /
2
;
var popMargLeft = (
$(
'#'
+
popID).width
(
) +
80
) /
2
;
//Apply Margin to Popup
$(
'#'
+
popID).css
({
'margin-top'
:
-
popMargTop,
'margin-left'
:
-
popMargLeft
}
);
//Apparition du fond - .css({'filter' : 'alpha(opacity=80)'}) pour corriger les bogues d'anciennes versions de IE
$(
'body'
).append
(
'<div id="fade"></div>'
);
$(
'#fade'
).css
({
'filter'
:
'alpha(opacity=80)'
}
).fadeIn
(
);
return false;
}
);
//Close Popups and Fade Layer
$(
'body'
).on
(
'click'
,
'a.close, #fade'
,
function(
) {
//Au clic sur le body...
$(
'#fade , .popup_block'
).fadeOut
(
function(
) {
$(
'#fade, a.close'
).remove
(
);
}
);
//...ils disparaissent ensemble
return false;
}
);
}
);
Vous noterez que le script est initié avec jQuery(function($){...});. Cette notation correspond à $(document).ready(function(){});, la différence est que jQuery permet d'éviter tout conflit de nommage pour la fonction $() utilisée par de nombreux scripts et bibliothèques. La fonction de rappel anonyme appelée par l'événement .ready() prend en paramètre l'objet jQuery, vous pouvez dons le nommer ($) afin de pouvoir l'utiliser à l'intérieur de la fermeture (closure).
La méthode .on() prend au minimum deux paramètres : le type d'événement à écouter et le code à exécuter lorsque l'événement est déclenché.
Dans la seconde version, un troisième paramètre vient s'intercaler entre les deux précédents. Si cet argument correspond à un sélecteur, alors c'est sur les éléments correspondant à ce sélecteur que sera affecté l'événement, même s'ils ne sont pas présents dans le DOM au moment de la déclaration.
Il s'agit de la délégation d'événements.
Le second événement est affecté à la balise <body>, en effet, nous souhaitons que lors du clic sur le masque opaque, la popup disparaisse, or ce masque opaque est ajouté directement dans le body, c'est donc la balise la plus proche contenant tous les éléments sur lesquels nous souhaitons déléguer des événements.
Si nous avions souhaité que seuls les clics sur les croix ferment les popups, alors nous aurions pu les encapsuler dans un élément commun et affecter la délégation sur cet élément.
Voir la démonstration pour cette version : exemple modifié
Remerciements▲
Ce tutoriel a été traduit avec l'aimable autorisation de Soh Tanaka.
Merci à ClaudeLELOUP pour sa relecture attentive et efficace.