Pour votre progression, c'est très important de finir le TP précédent avant de commencer celui-ci.
Commençons ce TP par quelques révisions.
var parfums=XXXXX;
Que
faut-il écrire à la place de XXXXX pour créer un tableau ayant les valeurs fraise, chocolat et vanille ?
var pos=XXXXX;
Que faut-il écrire à la place de XXXXX pour créer un objet ayant les propriétés top et left respectivement associées aux valeurs 100 et 200 ?
var joueur={pseudo: "Joe"};
XXXXX
Que faut-il écrire à la place de XXXXX pour ajouter la propriété score à joueur associée à la valeur 100 ?
var parfums=["fraise","chocolat","vanille"];
XXXXX
var parfums=["fraise","chocolat","vanille"];
console.log(XXXXX);
var divTop=$('#top');
XXXXX
Que faut-il écrire à la place de XXXXX pour cacher le <div> numéroté "3" ?
Indications:
Vous avez probablement confondu "eq" avec une autre fonction...
$('img').click(function(){ XXXXX });
Que faut-il écrire à la place de XXXXX pour que le <span> correspondant à l'image cliquée soit affiché en rouge (color, red) ?
C'est à dire:
Quand on clique sur 5, 4 est affiché en rouge.
Quand on clique sur 7, 6 est affiché en rouge
Indications:
Si vous venez d'assister au cours magistral, passez à la section suivante.
Les fermetures existent dans d'autres langages, mais elles sont très utilisées en JavaScript.
Il s'agit tout simplement le fait de pouvoir utiliser des variables définies dans une fonction parent.
Ici la variable « x » est utilisée dans exemple2() alors qu'elle est définie dans exemple1().
Dans d'autres langages, une variable n'est accessible que dans la fonction qui la déclare.
Dans cet exemple la variable n est définie dans la 1ere fonction anonyme.
La variable n est utilisée (lue et modifiée) dans la fonction anonyme appelée par .each().
On a vu qu'en programmation événementielle on déclare souvent des fonctions à appeler « plus tard », quand un événement survient.
On se retrouve donc avec beaucoup de fonctions et on a besoin de partager des informations entre-elles. Les fermetures sont alors très pratiques.
Les fermetures sont simples et intuitives à utiliser, mais en y regardant de plus près, il se passe des choses un peu bizarres.
Tout d'abord l'idée d'accéder à des variables locales déclarées dans une autre fonction est surprenante.
Ensuite, on se rend compte que ces variables sont utilisées alors que la fonction qui les déclare a déjà fini d’exécuter !
Si vous venez d'assister au cours magistral, passez à la section suivante.
Dans cette partie, on va voir plus en détail la gestion d'événements.
Quand un utilisateur fait une action, un objet événement est créé. Il est successivement envoyé à :
- l'élément où il s'est produit.
- l'élément parent
- l'élément grand-parent
- ...
- ensuite est exécutée l'action par défaut
Exemples d'actions par défaut :
- "click" sur un lien : suivre le lien
- "keypress" dans un champs texte : afficher la lettre
- "click" sur un bouton : envoyer le formulaire
- "click" dans une boite à cocher : cocher
- "submit" pour un formulaire : envoyer formulaire
- ...
On peut ajouter un gestionnaire d'événement click à n'importe quel élément sur toute la chaîne. Ils seront tous appelés.
Par exemple, si on utilise un gestionnaire d'événement click sur "body", on récupère les clicks de tous les éléments de la page.
"this" est l'objet sur lequel se trouve le gestionnaire d’événement (notre fonction)
"e.target" est l'objet sur lequel s'est produit l'événement.
L'action par défaut peut-être annulée avec:
e.preventDefault()
C'est très utilisé : quand on utilise un gestionnaire d'événement, on veut souvent remplacer la fonctionnalité par défaut par notre fonctionnalité,il faut donc utiliser preventDefault().
Exemples :
- "click" sur un lien : ne suit pas le lien
- "keypress" dans un champs texte : n'affiche pas la lettre
- ...
On va prendre un moment pour bien comprendre ce qui se passe quand on utilise un gestionnaire d'événements.
La fonction anonyme de la ligne 3 est exécuté lorsque l'utilisateur clique sur sur l'image... c'est à dire bien après la fin de l'exécution des lignes 2,3 et 8.
La fonction anonyme de la ligne 3 function(e){...} est appelée « gestionnaire d'événements » : son rôle est de réagir lorsqu'un événement survient.
$('img').click(function(){...}) n'exécute pas cette fonction. Il se contente d'ajouter ce gestionnaire d'événements à l'image, pour qu'il soit appelé plus tard... quand un utilisateur cliquera sur cette image.
$(document).ready(function()
{
console.log('Doc prêt');
$('img').click(function(e)
{
console.log('Image cliquée');
$(this).hide();
});
console.log("Fin mise en place");
});
Le gestionnaire d'événements est le code en :
$(document).ready(function()
{
0 console.log('Doc prêt');
1 $('img').click(function(e)
{
2 console.log('Image cliquée');
3 $(this).hide();
});
4 console.log("Fin mise en place");
});
Quel est l'ordre d'exécution ?
Quand un utilisateur fait une action, un objet événement est créé. Il est successivement envoyé à :
- l'élément où il s'est produit.
- l'élément parent
- l'élément grand-parent
- ...
------------------
$('span').click(function(e){...});
Sur quel(s) élément(s) peut-on cliquer pour provoquer l'appel de la fonction gestionnaire d'événements ?
$('img').click(function(e){...});Sur quel(s) élément(s) peut-on cliquer pour provoquer l'appel de la fonction gestionnaire d'événements ?
$('h2').click(function(e){...});Sur quel(s) élément(s) peut-on cliquer pour provoquer l'appel de la fonction gestionnaire d'événements ?
$('div').click(function(e){...});Sur quel(s) élément(s) peut-on cliquer pour provoquer l'appel de la fonction gestionnaire d'événements ?
Suite de l'exercice du TP-3 « Tableau joueurs »
Il manque deux fonctionnalités au tableau de joueurs, qu'on va compléter, ensemble, dans les pages suivantes
Reprenez votre code du TP-3, ou bien celui-ci:
joueurs.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>joueurs</title>
<link type="text/css" rel="stylesheet" href="joueurs.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="joueurs.js"></script>
</head>
<body>
<!--------------------->
<h2>Joueurs :</h2>
<p id="ajouter">
<label>nom: <input id="ajout-nom" type="text"/></label>
<label>score: <input id="ajout-score" type="text"/></label>
<input id="ajout-bouton" type="button" value="ajouter"/>
</p>
<table id="joueurs">
<tr><td class="nom">Leïla</td><td class="score">121</td></tr>
<tr><td class="nom">Driss</td><td class="score">153</td></tr>
<tr><td class="nom">Lian</td><td class="score">210</td></tr>
<tr><td class="nom">Joe</td><td class="score">32</td></tr>
<tr><td class="nom">Naïma</td><td class="score">261</td></tr>
<tr><td class="nom">Karim</td><td class="score">183</td></tr>
<tr><td class="nom">Anon.</td><td class="score">0</td></tr>
</table>
<p>
total : <span id="total" >960</span><br/>
médiane : <span id="mediane">153</span>
</p>
<!--------------------->
</body>
</html>
joueurs.css
body
{
font-family: sans;
}
h2
{
font-size: 16px;
}
#joueurs
{
box-shadow: 2px 2px 4px rgba(0,0,0,.2);
border-radius: 2px;
border-collapse: collapse;
margin-left: 40px;
}
#joueurs td
{
padding: 3px 10px;
}
#joueurs tr
{
background-color: #f0f0ff;
}
#joueurs tr:nth-child(2n)
{
background-color: #efe;
}
#joueurs .score
{
text-align: right;
}
#ajouter input[type='text']
{
width: 80px;
}
#ajout-nom
{
margin-right: 10px;
}
joueurs.js
console.log("Ce programme JS vient d'être chargé");
$(document).ready(function()
{
console.log("Le document est pret");
$('#ajout-bouton').click(function()
{
var joueur={ nom: $('#ajout-nom' ).val(),
score: $('#ajout-score').val()
};
ajouter_joueur(joueur);
$('#ajout-nom' ).val('');
$('#ajout-score').val('');
$('#total' ).text(calculer_total());
$('#mediane').text(calculer_mediane());
trier();
});
console.log("La mise en place est finie. En attente d'événements...");
});
function ajouter_joueur(joueur)
{
var ligne=$('<tr><td class="nom"></td><td class="score"></td></tr>');
ligne.find(".nom" ).text(joueur.nom );
ligne.find(".score").text(joueur.score);
$('#joueurs').append(ligne);
}
function calculer_total()
{
var total=0;
// Pour chaque ligne du tableau .each() appelle la fonction.
$('#joueurs tr').each(function()
{
// $(this) est la ligne (tr) ...
// on veut le texte dans la case avec le score
var score=parseInt($(this).find('.score').text());
// La variable "total" est définie dans la fonction calculer_total...
// mais on peut y accéder ici (fermeture)
total+=score;
});
return total;
}
function calculer_mediane()
{
var scores=[];
$('#joueurs tr').each(function()
{
var s=parseInt($(this).find('.score').text());
scores.push(s);
});
scores.sort(function(a,b){return a-b;});
return scores[Math.floor(scores.length/2)];
}
function trier()
{
var joueurs=[];
$('#joueurs tr').each(function()
{
var s=parseInt($(this).find('.score').text());
var j=
{
ligne:$(this),
score:s
};
joueurs.push(j);
});
joueurs.sort(function(a,b){return b.score-a.score;});
for(var i=0;i<joueurs.length;i++)
{
var ligne=joueurs[i].ligne;
$('#joueurs').append(ligne);
}
}
Commençons par la validation.
Quand l'utilisateur clique sur le bouton "ajouter" faites les trois vérifications suivantes.
Dans chaque vérification, s'il y a un problème, affichez un alert() et n'ajoutez pas le joueur.
if(joueur.nom.length===0){alert("Le nom ne doit pas être vide !");return;}
if(/^[0-9]+$/.test(joueur.score)===false){alert("Score invalide");return;}
var existeDeja=false;
$('#joueurs tr').each(function()
{
if($(this).find('.nom').text()===joueur.nom){existeDeja=true;}
});
if(existeDeja){alert("Ce nom a déjà été rentré !");return;}
On veut que l'utilisateur puisse effacer chaque ligne en cliquant sur une croix:
Image croix :
Modifiez le HTML, le CSS et écrivez un gestionnaire d'événement click sur la case effacer pour effacer toute la ligne du tableau.
Utilisez la fonction jQuery .remove() (voir doc)
Vérifiez que ca marche pour les lignes du tableau.
Ajoutez des lignes en utilisant le bouton ajouter.
Vous allez remarquer qu'effacer ne marche PAS sur les nouvelles lignes ajoutées.
Pourquoi ?
joueurs.html
...
<table id="joueurs">
<tr><td class="effacer"></td><td class="nom">Leïla</td><td class="score">121</td></tr>
<tr><td class="effacer"></td><td class="nom">Driss</td><td class="score">153</td></tr>
<tr><td class="effacer"></td><td class="nom">Lian</td><td class="score">210</td></tr>
<tr><td class="effacer"></td><td class="nom">Joe</td><td class="score"> 32</td></tr>
<tr><td class="effacer"></td><td class="nom">Naïma</td><td class="score">261</td></tr>
<tr><td class="effacer"></td><td class="nom">Karim</td><td class="score">183</td></tr>
<tr><td class="effacer"></td><td class="nom">Anon.</td><td class="score"> 0</td></tr>
</table>
...
joueurs.css
...
#joueurs .effacer
{
background-image: url(effacer.png);
background-repeat: no-repeat;
background-position: 4px center;
width: 25px;
height: 16px;
padding: 0;
cursor: pointer;
}
#joueurs .effacer:hover
{
background-color: #ff0;
}
...
joueurs.js
$('#joueurs .effacer').click(function(event)
{
$(this).parent().remove();
});
Remarques :
On a choisi d'utiliser des images background CSS au lieu d'images HTML <img>.
Les deux choix sont possibles. Les images CSS ont l'avantage de laisser au graphiste plus de souplesse.
Dans un logiciel complèxe (ex. une grosse application PHP) le code HTML est plus lourd à modifier.
Actuellement, dans notre programme, les gestionnaires d'événement "effacer" sont ajoutés au démarrage.
Ils fonctionnent bien pour les lignes présentes au démarrage.
Par contre, quand l'utilisateur crée un joueur avec le bouton ajouter, la case de la nouvelle ligne n'a pas de gestionnaire d'événement.
Deux solutions sont possibles:
La deuxième est plus élégante (moins de code).
Nous allons le faire nous mêmes à la main pour comprendre comment ca marche.
(Mais en pratique on utiliserait la fonction jQuery .on() qui fait l'équivalent)
Regardez les transparents du cours sur le bubbling d'événements.
Au lieu d'installer le gestionnaire sur la case effacer, installez-le sur tout le tableau.
Dans ce gestionnaire vous récupérerez tous les clicks à l'intérieur du tableau ... y compris ceux qui viennent d'autres cases que la case "effacer".
Vous devez donc:
Indication : l'élément cliqué se trouve dans event.target
$('#joueurs').click(function(event)
{
if($(event.target).hasClass('effacer'))
{
$(event.target).parent().remove();
$('#total' ).text(calculer_total());
$('#mediane').text(calculer_mediane());
}
});
joueurs.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>joueurs</title>
<link type="text/css" rel="stylesheet" href="joueurs.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="joueurs.js"></script>
</head>
<body>
<!--------------------->
<h2>Joueurs :</h2>
<p id="ajouter">
<label>nom: <input id="ajout-nom" type="text"/></label>
<label>score: <input id="ajout-score" type="text"/></label>
<input id="ajout-bouton" type="button" value="ajouter"/>
</p>
<table id="joueurs">
<tr><td class="effacer"></td><td class="nom">Leïla</td><td class="score">121</td></tr>
<tr><td class="effacer"></td><td class="nom">Driss</td><td class="score">153</td></tr>
<tr><td class="effacer"></td><td class="nom">Lian</td><td class="score">210</td></tr>
<tr><td class="effacer"></td><td class="nom">Joe</td><td class="score"> 32</td></tr>
<tr><td class="effacer"></td><td class="nom">Naïma</td><td class="score">261</td></tr>
<tr><td class="effacer"></td><td class="nom">Karim</td><td class="score">183</td></tr>
<tr><td class="effacer"></td><td class="nom">Anon.</td><td class="score"> 0</td></tr>
</table>
<p>
total : <span id="total" >960</span><br/>
médiane : <span id="mediane">153</span>
</p>
<!--------------------->
</body>
</html>
joueurs.css
body
{
font-family: sans;
}
h2
{
font-size: 16px;
}
#joueurs
{
box-shadow: 2px 2px 4px rgba(0,0,0,.2);
border-radius: 2px;
border-collapse: collapse;
margin-left: 40px;
}
#joueurs td
{
padding: 3px 10px;
}
#joueurs tr
{
background-color: #f0f0ff;
}
#joueurs tr:nth-child(2n)
{
background-color: #efe;
}
#joueurs .score
{
text-align: right;
}
#ajouter input[type='text']
{
width: 80px;
}
#ajout-nom
{
margin-right: 10px;
}
#joueurs .effacer
{
background-image: url(effacer.png);
background-repeat: no-repeat;
background-position: 4px center;
width: 25px;
height: 16px;
padding: 0;
cursor: pointer;
}
joueurs.js
console.log("Ce programme JS vient d'être chargé");
$(document).ready(function()
{
console.log("Le document est pret");
trier();
$('#ajout-bouton').click(function()
{
var joueur={ nom: $('#ajout-nom' ).val(),
score: $('#ajout-score').val()
};
if(joueur.nom.length===0){alert("Le nom ne doit pas être vide !");return;}
if(/^[0-9]+$/.test(joueur.score)===false){alert("Score invalide");return;}
var existeDeja=false;
$('#joueurs tr').each(function()
{
if($(this).find('.nom').text()===joueur.nom){existeDeja=true;}
});
if(existeDeja){alert("Ce nom a déjà été rentré !");return;}
ajouter_joueur(joueur);
$('#ajout-nom' ).val('');
$('#ajout-score').val('');
$('#total' ).text(calculer_total());
$('#mediane').text(calculer_mediane());
trier();
});
$('#joueurs').click(function(event)
{
if($(event.target).hasClass('effacer'))
{
$(event.target).parent().remove();
$('#total' ).text(calculer_total());
$('#mediane').text(calculer_mediane());
}
});
console.log("La mise en place est finie. En attente d'événements...");
});
function ajouter_joueur(joueur)
{
var ligne=$('<tr><td class="effacer"></td><td class="nom"></td><td class="score"></td></tr>');
ligne.find(".nom" ).text(joueur.nom );
ligne.find(".score").text(joueur.score);
$('#joueurs').append(ligne);
}
function calculer_total()
{
var total=0;
// Pour chaque ligne du tableau .each() appelle la fonction.
$('#joueurs tr').each(function()
{
// $(this) est la ligne (tr) ...
// on veut le texte dans la case avec le score
var score=parseInt($(this).find('.score').text());
// La variable "total" est définie dans la fonction calculer_total...
// mais on peut y accéder ici (fermeture)
total+=score;
});
return total;
}
function calculer_mediane()
{
var scores=[];
$('#joueurs tr').each(function()
{
var s=parseInt($(this).find('.score').text());
scores.push(s);
});
scores.sort(function(a,b){return a-b;});
return scores[Math.floor(scores.length/2)];
}
function trier()
{
var joueurs=[];
$('#joueurs tr').each(function()
{
var s=parseInt($(this).find('.score').text());
var j=
{
ligne:$(this),
score:s
};
joueurs.push(j);
});
joueurs.sort(function(a,b){return b.score-a.score;});
for(var i=0;i<joueurs.length;i++)
{
var ligne=joueurs[i].ligne;
$('#joueurs').append(ligne);
}
}
Il est conseillé de (re)lire les pages du cours qui suivent.
Elles décrivent un exemple de popup.
On va ensuite travailler sur cet exemple.
Dans cet exemple, l'utilisateur peut cliquer sur un nom pour afficher un popup dans lequel sont affichées des informations sur la personne.
Pour fermer le popup, il doit cliquer sur la croix située en haut à droite du popup.
Le HTML est composé de deux parties :
- La liste dans laquelle sont affichés les noms.
- Le popup et son contenu
La liste n'a rien de particulier.
Les noms sont dans des <span> de classe "popup-mot" et ayant un attribut "data-popup" contenant un identifiant associé au nom.
La norme HTML 5 permet de créer des attributs dont le nom commence par "data-". On s'en sert ici pour stoker un identifiant qui nous permettra de trouver le popup correspondant à ce nom.
On peut imaginer qu'il existe plusieurs popup, tous ayant la même structure.
Tous les popup ont class="popup".
Ils contiennent
- un <span> avec une croix pour les fermer.
- une image "triangle.png" qui représente le petit triangle blanc en bas du popup
- le contenu du popup (photo, titre, texte, liens)
Une classe (fermer, triangle, photo) nous permettra d'agir sur ces éléments dans le CSS et le JS.
Le popup a "position: absolute", ce qui permet de le déplacer n'importe où à l'aide de "left" et "top" (ce sera fait dans le JS)
Par ailleurs, "position: absolute" transforme le popup en un "containing block" : tous les éléments à l'intérieur du popup qui ont "position: absolute" sont positionnés par rapport au popup (et non pas par rapport à la page).
C'est pour ça que "top:0" positionne .fermer en haut du popup et pas en haut de la page.
De la même manière l'image .triangle est positionné en bas du popup (et pas en bas de la page). La valeur négative de bottom, fait sortir l'image en dehors de la région d'affichage de son parent (le popup). Ce n'est pas un problème, cette situation s'appelle un "overflow".
Notre première tâche en JS est de placer le popup au-dessus du mot qui a été cliqué.
On utilise .offset() pour obtenir la position du mot cliqué. .offset() renvoie un objet avec deux propriétés (top, left).
On veut que le bas du triangle se trouve au même niveau que le mot. Pour trouver le haut de la fenêtre, il faut donc soustraire la hauteur du popup et du triangle.
.offset(pos) nous permet ensuite de positionner le popup.
.offset({...}) fonctionne en modifiant la propriété "style" de l'élément HTML.
Il existe deux fonctions pour obtenir une position:
.offset() donne la position relative à la page
.position() donne la position relative à son "containing block"
.position() correspond donc tout simplement aux propriétés CSS left et top.
.offset() fait en interne un calcul, remontant tous les "containing blocks" jusque en haut de l'arbre DOM.
Dans la fonction gérant le click sur le <span class="fermer">, on a accès à "this". Mais "this" correspond au <span>, alors qu'on a besoin du <div class="popup"> pour fermer le popup. On utilise donc $(this).parent()
.fadeOut() permet de cacher un élément progressivement, avec une animation.
Voici le JS complet.
Remarquez qu'on peut mettre les listes jQuery dans des variables. C'est plus lisible et plus rapide.
À partir de l'attribut "data-popup" du mot cliqué on construit le sélecteur '#popup-joe'.
Remarquez à la ligne 0 que $('.popup-mot') contient plusieurs mots. jQuery ajoute donc notre fonction gestionnaire d'événement à plusieurs éléments.
C'est aussi le cas pour .popup>.fermer (on peut imaginer qu'il y a plusieurs popups...)
Dans les pages suivantes on va reprendre l'exemple vu en cours.
Créez les fichiers suivants:
popup.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>popup</title>
<link type="text/css" rel="stylesheet" href="popup.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="popup.js"></script>
</head>
<body>
<div id="connectes">
<p>Connectés : </p>
<ul>
<li><span class="popup-mot" data-popup="joe" >Joe </span></li>
<li><span class="popup-mot" data-popup="marc">Marc</span></li>
<li><span class="popup-mot" data-popup="lian">Lian</span></li>
</ul>
</div>
<div id="popup-joe" class="popup">
<span class="fermer">X</span>
<img class="triangle" src="triangle.png" alt=""/>
<img src="et.png" alt="joe" class="photo"/>
<h2>Joe</h2>
<p>Célibataire, 22 ans.<br/>Aime les épinards.</p>
<p>
<a href="...">films</a> | <a href="...">page perso</a>
</p>
</div>
</body>
</html>
popup.css
body
{
font-family: sans;
background-image: url(texture-grise.jpg);
padding-top: 100px;
}
#connectes
{
background-color: #eee;
width: 150px;
padding: .5em;
}
#en-ligne p
{
margin: 0;
}
.popup-mot
{
font-weight: bold;
cursor: pointer;
}
.popup
{
position: absolute;
display: none;
width: 200px;
background-color: white;
padding: .7em;
box-shadow: 1px 1px 3px rgba(0,0,0,.4);
font-size: 12px;
}
.popup h2
{
margin-top: .2em;
}
.popup>.fermer
{
position: absolute;
top: 0;
right: 0;
padding: .5em;
padding-top: .1em;
}
.popup .photo
{
width: 80px;
height: auto;
float: right;
margin-left: .2em;
margin-bottom: .2em;
}
.popup>.triangle
{
position: absolute;
left: 10px;
bottom: -20px;
}
popup.js
$(document).ready(function()
{
$('.popup-mot').mousedown(function()
{
var mot=$(this);
var id="popup-"+mot.attr('data-popup');
var popup=$('#'+id);
var pos=mot.offset();
pos.top-=popup.outerHeight()+20;
popup.fadeIn();
popup.offset(pos);
});
$('.popup>.fermer').mousedown(function()
{
$(this).parent().fadeOut();
});
});
triangle.png : https://moodle.iutv.univ-paris13.fr/img/js/triangle.png
et.png: https://moodle.iutv.univ-paris13.fr/img/js/et.png
texture-grise.jpg: https://moodle.iutv.univ-paris13.fr/img/js/texture-grise.jpg
En modifiant uniquement le HTML, ajoutez les popup pour Marc et Lian.
Les images:
https://moodle.iutv.univ-paris13.fr/img/js/marc.png
https://moodle.iutv.univ-paris13.fr/img/js/lian.png
Il faut adapter le id des deux nouveaux popup.
Le JS utilise le nom qui se trouve dans data-popup en ajoutant "popup-" devant.
popup.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>popup</title>
<link type="text/css" rel="stylesheet" href="popup.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="popup.js"></script>
</head>
<body>
<div id="connectes">
<p>Connectés : </p>
<ul>
<li><span class="popup-mot" data-popup="joe" >Joe </span></li>
<li><span class="popup-mot" data-popup="marc">Marc</span></li>
<li><span class="popup-mot" data-popup="lian">Lian</span></li>
</ul>
</div>
<div id="popup-joe" class="popup">
<span class="fermer">X</span>
<img class="triangle" src="triangle.png" alt=""/>
<img src="et.png" alt="joe" class="photo"/>
<h2>Joe</h2>
<p>Célibataire, 22 ans.<br/>Aime les épinards.</p>
<p>
<a href="...">films</a> | <a href="...">page perso</a>
</p>
</div>
<div id="popup-marc" class="popup">
<span class="fermer">X</span>
<img class="triangle" src="triangle.png" alt=""/>
<img src="marc.png" alt="joe" class="photo"/>
<h2>Marc</h2>
<p>Marié, 29 ans.<br/>Aime les oranges.</p>
<p>
<a href="...">films</a> | <a href="...">page perso</a>
</p>
</div>
<div id="popup-lian" class="popup">
<span class="fermer">X</span>
<img class="triangle" src="triangle.png" alt=""/>
<img src="lian.png" alt="joe" class="photo"/>
<h2>Lian</h2>
<p>Joueur d'échecs, 24 ans.<br/>Aime les glaces.</p>
<p>
<a href="...">films</a> | <a href="...">page perso</a>
</p>
</div>
</body>
</html>
Quand l'utilisateur ouvre un popup, on voudrait fermer ceux qui serait déjà ouverts.
Ajoutez le code nécessaire.
Astuce:
Pour éviter
popup.js:
$(document).ready(function()
{
$('.popup-mot').mousedown(function(e)
{
// Astuce: le .stop() permet d’arrêter l'animation fadeIn si elle est encore en cours
$('.popup').stop().fadeOut();
var mot=$(this);
var id="popup-"+mot.attr('data-popup');
var popup=$('#'+id);
var pos=mot.offset();
pos.top-=popup.outerHeight()+20;
popup.fadeIn();
popup.offset(pos);
});
$('.popup>.fermer').mousedown(function()
{
$(this).parent().fadeOut();
});
});
Au lieu d'ouvrir et fermer en cliquant, on voudrait ouvrir et fermer les popups quand la souris passe pardessus le mot.
Donc, au lieu d'utiliser .mousedown() (et le bouton fermer), on va utiliser utiliser la fonction jQuery .hover(), qui prend deux paramètres:
popup.js
$(document).ready(function()
{
$('.popup-mot').hover(function(e)
{
var mot=$(this);
var id="popup-"+mot.attr('data-popup');
var popup=$('#'+id);
var pos=mot.offset();
pos.top-=popup.outerHeight()+20;
popup.fadeIn();
popup.offset(pos);
},
function(e)
{
$('.popup').stop().fadeOut();
});
});