Pour votre progression, c'est très important de finir le sujet précédent avant de commencer celui-ci.
Vous devez travailler connectés (lien « Connexion » en haut à droite de la page). Sinon, vous rencontrerez des problèmes d'avancement et vous risquez d'être comptés absent. En étant connectés vous retrouverez l'endroit où vous en étiez à la séance suivante.
Commençons par une rapide révision des notions des sujets précédents.
Comment s'appelle le type d'événement qui survient lorsque l'utilisateur relâche une touche du clavier ?
Vous êtes sur la bonne voie. Vous avez bien indiqué un type d'événement... mais pas le bon. Ici, on veut une touche du clavier relâché.
HTML
<body>
<p>bonjour</p>
<body>
JS:
document.querySelector('p').XYZ='coucou';
Que faut-il écrire à la place de XYZ pour remplacer 'bonjour' par 'coucou' ?
Dans le doute regardez le JS que vous avez écrit.
Par exemple,
HTML
<body>
<input type="text" />
</body>
JS
let s=document.querySelector('input').XYZ;
Que faut-il écrire à la place de XYZ pour mettre dans la variable "s" ce que l'utilisateur a tapé dans le input ?
Indice:
Dans texte.html, comment avez vous fait pour lire le contenu des input ?
let liste=document.querySelectorAll('.abc');Que faut-il écrire à la place de XYZ pour afficher le nombre d'éléments ayant la classe abc ?
console.log(liste.XYZ);
HTML:
<ul>
<li class="joueur">Wang</li>
<li class="joueur">Alaoui</li>
<li class="joueur">Saidi</li>
</ul>
JS:
let liste=document.querySelectorAll('.joueur');Que faut-il écrire à la place de XYZ pour afficher "Saidi" dans la console ?
console.log(XYZ.textContent);
« liste » c'est toute la liste. Vous ne voulez modifier qu'un seul élément de cette liste.
Rappelez vous: une liste fonctionne comme un tableau.
Réécrivez, en une seule ligne, le programme suivant en utilisant une fonction anonyme
document.addEventListener('click',exemple);
function exemple(){console.log('coucou');}
Faites bien attention aux parenthèses et accolades, particulièrement à la fin.
Vous êtes sur la bonne voie. Votre réponse commence par :
document.addEventListener('click',function()...
Ce qui est correct. Le problème est après.
let a = function(){return 456;}
Que contient la variable a ?
setTimeout(exemple,3000);
function exemple() { return 100; }
Ici, quel est le premier paramètre de la fonction setTimeout ?
Que faut-il écrire en JS pour transformer ceci:
<body>
<p>bonjour</p>
</body>
en ceci:
<body>
<p class="encart">bonjour</p>
</body>
Presque! "p" n’existe pas. Vous devez aller chercher le paragraphe...
En utilisant classList, que faut-il écrire en JS pour transformer ceci:
<body>
<p class="encart important actu">bonjour</p>
</body>
en ceci:
<body>
<p class="encart actu">bonjour</p>
</body>
HTML:
<p id="ahmed">Ahmed</p>
<p id="leo">Léo</p>
CSS:
XYZ
{
background-color: green;
}
Que faut-il écrire à la place de XYZ pour afficher uniquement "Léo" en fond vert ?
HTML:
<p><span class="nom">Ahmed</span> a marqué <span class="points">321</span> points</p>
CSS:
XYZ
{
background-color: green;
}
Que faut-il écrire à la place de XYZ pour afficher uniquement "321" en fond vert ?
HTML:
<div id="tom">
<p>Tom:</p>
<p class="score">Score: 123</p>
</div>
<div id="joe">
<p>Joe:</p>
<p class="score">Score: 456</p>
</div>
CSS:
XYZ
{
background-color: green;
}
Que faut-il écrire à la place de XYZ pour afficher "Score: 456" en fond vert ? (uniquement "Score: 456")
<ul>Quand l'utilisateur clique sur un <li>, il devient vert.
<li>Chocolat </li>
<li>Fraise </li>
<li>Praliné </li>
...
</ul>
<script>
let lis=document.querySelectorAll('li');
for(let i=0;i<lis.length;i++){
lis[i].addEventListener('click',function(){
XYZ.style.color='green';
});
}
</script>
Les événements sont des actions de l'utilisateur. Par exemple: bouton de souris enfoncé, touche de clavier relâchée, etc.
Presque tous les programmes qu'on écrit dans ce cours réagissent à des événements.
La gestion d'événements est un des aspects les plus difficiles à comprendre de ce cours.
Déroulement:
Vocabulaire:
La fonction (ici fonction_a_appeler) en paramètre de addEventListener est appelée « Gestionnaire d'événements » (« event listener » en anglais).
Cette fonction est appelée par le navigateur quand survient l'événement.
...L'utilisateur ouvre la page puis clique sur le bouton.
<input type="button" value="Appuyer"/>
<script>
console.log('A');
let bouton=document.querySelector('input');
console.log('B');
bouton.addEventListener('click',fonction_a_appeler);
console.log('C');
function fonction_a_appeler()
{
console.log('D');
}
console.log('E');
</script>
...
Utilisons maintenant une fonction anonyme:
...L'utilisateur ouvre la page puis clique sur le bouton.
<input type="button" value="Appuyer"/>
<script>
console.log('A');
let bouton=document.querySelector('input');
console.log('B');
bouton.addEventListener('click',function()
{
console.log('C');
});
console.log('D');
</script>
...
L'ordre est bien A,B,D,C
bouton.addEventListener() ne fait qu'enregistrer la fonction anonyme sur le bouton. Il n’appelle pas la fonction anonyme.
Essayons maintenant de comprendre ce qui se passe entre D et C:
Après D, notre JS dans <script> a fini de s’exécuter. Notre JS rend la main au navigateur.
Le navigateur doit en permanence gérer plein de choses (rafraîchissement de l'affichage, interactions avec l'utilisateur, ...).
Si on ne rendait pas la main au navigateur, il resterait bloqué ... inutilisable !
Le navigateur continue donc son travail.
Si l'utilisateur clique sur le bouton, alors le navigateur s’aperçoit qu'il y a une fonction (notre fct anonyme) enregistrée sur ce bouton et l’appelle.
...L'utilisateur ouvre la page puis clique sur le bouton.
<input type="button" value="Appuyer"/>
<script>
console.log('A');
let bouton=document.querySelector('input');
console.log('B');
bouton.addEventListener('click',function()
{
console.log('C');
});
console.log('D');
</script>
...
...
<input type="button" value="Appuyer"/>
<script>
console.log('A');
let bouton=document.querySelector('input');
console.log('B');
bouton.addEventListener('click',function()
{
console.log('C');
});
console.log('D');
</script>
...
Dans les pages suivantes, on va programmer, ensemble, un petit jeu comme celui-ci:
Un joueur déplace le pingouin (Tux), avec les flèches du clavier.
L'autre joueur essaie de l'atteindre avec la souris.
N'hésitez pas à vous inspirer des fichiers écrits précédemment
Créez un fichier HTML complet appelé jeu.html
Créez un fichier séparé jeu.js
Créez un fichier séparé jeu.css
Assurez vous que ces deux fichiers sont bien pris en compte dans le HTML.
Dans le body, créez un div ayant pour id "cadre" et contenant juste l'image suivante: https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png
L'image doit avoir pour id "tux"
Créez un paragraphe. A l'intérieur de celui-ci, créez un span ayant pour id
"score", qui affichera la valeur du score.
Dans le CSS créez une bordure pour le cadre et donnez lui une taille de 500x500.
Donnez une marge de 10px au body.
Positionnez tux au centre, en vous inspirant du positionnement utilisé pour le splat vert au sujet-1
Pour l'instant, laissez le JS vide.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Jeu</title>
<link href="jeu.css" rel="stylesheet" />
</head>
<body>
<div id="cadre">
<img id="tux" src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
</div>
<p>Score: <span id="score">---</span></p>
<script src="jeu.js"></script>
</body>
</html>
body
{
margin: 10px;
}
#cadre
{
width: 500px;
height: 500px;
border: 1px solid black;
}
#tux
{
position: absolute;
top: 100px;
left: 100px;
}
(vide)
Comment s'appelle la fonction qui permet d'enregistrer sur un élément une autre fonction, qui devra être appelée lorsqu'un événement surviendra ?
(on veut uniquement le nom)
Indice: on a utilisé cette fonction dans presque tous nos programmes.
Oui, quand on fait :
abc.addEventListener('click',def)
function def() {
...
}
on dit au navigateur « Enregistre la fonction def sur l'élément abc. Plus tard, si l'utilisateur clique sur abc, il faudra appeler def. »
Habituellement, on réagit sur un élément (abc) particulier, par exemple un paragraphe, un titre, un bouton ...jeu.js
document.addEventListener('keydown',function(){
console.log('bonjour');
});
Comme on l'a vu précédemment, quand le navigateur appelle notre fonction anonyme, il lui donne un paramètre qu'on peut appeler "event".
"event" décrit l'événement clavier qui vient de survenir. event.key décrit quelle touche a été enfoncée.
Dans votre programme, affichez sur la console event.key
Si vous ne vous souvenez pas comment utiliser event, regardez dans vos fichiers précédents, ou l'aide mémoire
jeu.js
document.addEventListener('keydown',function(event){
console.log('Touche:',event.key);
});
Rechargez jeu.html dans votre navigateur pour exécuter jeu.js et regardez dans la console.
Que vaut event.key quand l'utilisateur appuie sur la flèche vers le bas ?
let tux=XYZ;
Que faut-il écrire à la place de XYZ pour mettre dans tux l'élément DOM ayant id="tux" ?
La ligne suivante fonctionne:
let tux=document.querySelector('#tux');
mais dans ce cas, on peut utiliser une fonction plus simple getElementById (qui se traduit par "Chercher élement par son id):
let tux=document.getElementById('tux');
Dorénavant, on utilisera getElementById si on connaît le id de l'élément.
Pour pouvoir déplacer Tux, il faut d'abord connaître les coordonnées de l'endroit où il se trouve actuellement.
Dans la fonction anonyme, il faut tout d'abord obtenir l'image
let tux=document.getElementById('tux');
Puis ajoutez la ligne suivante:
let rect=tux.getBoundingClientRect();
Après cette ligne, affichez rect dans la console.
Quelles informations trouve-t-on dans rect ?
Mettons les coordonnées left et top dans des variables que l'on va pouvoir manipuler:
let left=rect.left;
let top=rect.top;
XYZ
Que faut-il écrire à la place de XYZ pour modifier la variable left de manière à indiquer un déplacement de 30 pixels vers la gauche ?
Rappel: left est un nombre
Attention: "left" est la même chose qu'une coordonnée x. Réfléchissez bien à ce que veut dire augmenter ou diminuer cette coordonnée
Supposons qu'on ait le code suivant:
let tux=document.getElementById('tux');
let rect=tux.getBoundingClientRect();
let left=rect.left;
let top=rect.top;
left-=30;
XYZ
Que faut-il écrire à la place de XYZ pour réellement modifier la position left de tux (en utilisant la variable tux et la variable left).
Indication: n'oubliez pas les unités (px)
En cas de doute, regardez comment on a fait pour positionner le splat vert au Sujet-1
On a écrit le code suivant:
let tux=document.getElementById('tux');Par ailleurs, on sait, avec event.key quelle touche a été enfoncée
let rect=tux.getBoundingClientRect();
let left=rect.left;
let top=rect.top;
left-=30;
tux.style.left=left+'px';
let tux=document.getElementById('tux');
document.addEventListener('keydown',function(event){
console.log('Touche enfoncée:',event.key);
let rect=tux.getBoundingClientRect();
console.log(rect);
let d=300;
let left=rect.left;
let top=rect.top;
if(event.key==='ArrowRight'){left+=d;}
if(event.key==='ArrowLeft' ){left-=d;}
if(event.key==='ArrowDown' ){top+=d;}
if(event.key==='ArrowUp' ){top-=d;}
tux.style.left=left+"px";
tux.style.top=top+"px";
});
Ça y est ... on a réussi à faire déplacer le pingouin !
Pour rendre les déplacements plus fluides on peut utiliser des transitions CSS.
Dans jeu.css, ajoutez la lige suivante à #tux:
transition: top .3s, left .3s;
Cette ligne veut dire « Les changements de top et left prennent 0,3 secondes »
On a réussi à faire déplacer le pingouin.
Maintenant pour avancer sur le jeu, il va falloir ajouter les splats verts vus au Sujet-1.
Fusionnez le CSS et JS du splat vert du SUjet-1 dans les fichiers CSS et JS du programme actuel.
Voici le résultat souhaité:
Et voici la correction du splat vert vu au Sujet-1:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pingouin</title>
<style>
.splat
{
position: absolute;
/* La position de départ: en bas, au centre */
top: 500px;
left: 100px;
/* Agrandir 4 fois l'image */
transform: scale(4);
/* Définir les propriétés CSS à animer. Toutes en 1 seconde */
transition: top 1s,left 1s,transform 1s;
}
</style>
</head>
<body>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
<script>
document.addEventListener('mousedown',ajouter_splat);
function ajouter_splat(event)
{
// Petit détail: éviter la sélection
event.preventDefault();
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
document.body.append(i);
// Forcer le navigateur à prendre en compte la situation actuelle (position, scale).
// Ceci permettra au navigateur de s'apercevoir d'un changement futur des propriétés CSS.
window.getComputedStyle(i).top;
// Changer les propriétés CSS qui transitionnent.
// Le navigateur s'aperçoit du changement et déclenche la transition.
i.style.top =(event.pageY-16)+'px';
i.style.left=(event.pageX-16)+'px';
i.style.transform='scale(1)';
}
</script>
</body>
</html>
body
{
margin: 10px;
}
#cadre
{
width: 500px;
height: 500px;
border: 1px solid black;
}
#tux
{
position: absolute;
top: 100px;
left: 100px;
}
.splat
{
/* Ceci permet de placer les splats avec top et left */
position: absolute;
/* La position de départ: en bas, au centre */
top: 500px;
left: 100px;
/* Agrandir 4 fois l'image */
transform: scale(4);
/* Définir les propriétés CSS à animer. Toutes en 1 seconde */
transition: top 1s,left 1s,transform 1s;
}
let tux=document.getElementById('tux');
document.addEventListener('keydown',function(event){
console.log('Touche enfoncée:',event.key);
let rect=tux.getBoundingClientRect();
console.log(rect);
let d=300;
let left=rect.left;
let top=rect.top;
if(event.key==='ArrowRight'){left+=d;}
if(event.key==='ArrowLeft' ){left-=d;}
if(event.key==='ArrowDown' ){top+=d;}
if(event.key==='ArrowUp' ){top-=d;}
tux.style.left=left+"px";
tux.style.top=top+"px";
});
document.addEventListener('mousemove',ajouter_splat);
function ajouter_splat(event)
{
// Petit détail: éviter la sélection
event.preventDefault();
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
document.body.append(i);
// Forcer le navigateur à prendre en compte la situation actuelle (position, scale).
// Ceci permettra au navigateur de s'apercevoir d'un changement futur des propriétés CSS.
window.getComputedStyle(i).top;
// Changer les propriétés CSS qui transitionnent.
// Le navigateur s'aperçoit du changement et déclenche la transition.
i.style.top =(event.pageY-16)+'px';
i.style.left=(event.pageX-16)+'px';
i.style.transform='scale(1)';
}
A l'intérieur de la fonction qui gère le bouton de la souris, ajoutez une condition sur event.pageX et event.pageY qui vérifie si l'image est bien à l'intérieur du cadre.
Si ce n'est pas le cas, vous pouvez quitter la fonction avec return.
Indications pour être précis:
Condition:
...
document.addEventListener('mousedown',function (event)
{
// Petit détail: éviter la sélection
event.preventDefault();
if(event.pageX-16<10 ||
event.pageY-16<10 ||
event.pageX-16+32>500+10 ||
event.pageY-16+40>500+10 ){return;}
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
document.body.append(i);
...
Maintenant, il s'agit de limiter les déplacements de Tux au cadre.
Dans le gestionnaire d'événements keydown, bloquez le coordonnées left et right pour que l'image ne puisse pas sortir du cadre.
Indications:
...
document.addEventListener('keydown',function(event){
console.log('Touche enfoncée:',event.key);
let rect=tux.getBoundingClientRect();
console.log(rect);
let d=100;
let left=rect.left;
let top=rect.top;
if(event.key==='ArrowRight'){left+=d;}
if(event.key==='ArrowLeft' ){left-=d;}
if(event.key==='ArrowDown' ){top+=d;}
if(event.key==='ArrowUp' ){top-=d;}
left=Math.max(10,left);
top =Math.max(10,top);
left=Math.min(510-rect.width ,left);
top =Math.min(510-rect.height,top);
tux.style.left=left+"px";
tux.style.top=top+"px";
});
...
La fonction setTimeout permet d’exécuter une fonction après un délai donné en paramètre.
Elle s'utilise comme ceci:
setTimeout( fonction à exécuter , délai en millisecondes )
Que faut-il écrire pour afficher un alert avec 'coucou' après 2000 millisecondes ?
Essayez dans la console avant de répondre ici.
Utilisez une fonction anonyme.
Dans le CSS on avait écrit:
.splat
{
/* Ceci permet de placer les splats avec top et left */
position: absolute;
/* La position de départ: en bas, au centre */
top: 500px;
left: 100px;
/* Agrandir 4 fois l'image */
transform: scale(4);
/* Définir les propriétés CSS à animer. Toutes en 1 seconde */
transition: top 1s,left 1s,transform 1s;
}
La ligne "transition" dit au CSS d'animer les propriétés top et left de leur position initiale (top=500, left=100) à l'endroit cliqué en 1 seconde.
On voudra vérifier si le splat a touché le pingouin à la fin de l'animation, c'est à dire, après 1000 millisecondes.
Pour l'instant, utilisez setTimeout juste pour afficher 'fin animation' dans la console au bon moment.
(on verra ensuite comment vérifier si le splat a touché)
document.addEventListener('mousedown',function (event)
{
// Petit détail: éviter la sélection
event.preventDefault();
if(event.pageX-16<10 ||
event.pageY-16<10 ||
event.pageX-16+32>500+10 ||
event.pageY-16+40>500+10 ){return;}
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
document.body.append(i);
// Forcer le navigateur à prendre en compte la situation actuelle (position, scale).
// Ceci permettra au navigateur de s'apercevoir d'un changement futur des propriétés CSS.
window.getComputedStyle(i).top;
// Changer les propriétés CSS qui transitionnent.
// Le navigateur s'aperçoit du changement et déclenche la transition.
i.style.top =(event.pageY-16)+'px';
i.style.left=(event.pageX-16)+'px';
i.style.transform='scale(1)';
setTimeout(function(){
console.log('fin animation');
},1000);
});
On voudrait vérifier si les images de tux et splat se touchent.
Pour ça, on va utiliser leurs rectangles:
let rectTux=tux.getBoundingClientRect();
let rectSplat=i.getBoundingClientRect();
on peut utiliser les propriétés des rectangles top, left, width et height pour construire une condition (assez compliquée) qui permette de vérifier s'il y a une collision entre ces deux rectangles.
Essayez de trouver par vous mêmes, éventuellement en faisant un dessin des rectangles dans différentes configurations.
setTimeout(function(){
let rectTux=tux.getBoundingClientRect();
let rectSplat=i.getBoundingClientRect();
let touche=
rectSplat.top +rectSplat.height >= rectTux.top &&
rectSplat.top < rectTux.top +rectTux.height &&
rectSplat.left+rectSplat.width >= rectTux.left &&
rectSplat.left < rectTux.left +rectTux.width ;
...
la variable "touche" vaut true seulement si les rectangles se touchent
Déclarez une variable score au tout début de votre fichier et initialisez-la à 0.
Ensuite, augmentez le score de 10 quand les rectangles se touchent et diminuez de 5 quand ils ne se touchent pas.
Utilisez textContent pour afficher le score dans l'élément qui a id="score"
Écrivez le code, vérifiez qu'il fonctionne dans votre navigateur,
puis copiez-le ici pour que votre enseignant puisse le relire plus tard:
setTimeout(function(){
let rectTux=tux.getBoundingClientRect();
let rectSplat=i.getBoundingClientRect();
let touche=
rectSplat.top +rectSplat.height >= rectTux.top &&
rectSplat.top < rectTux.top +rectTux.height &&
rectSplat.left+rectSplat.width >= rectTux.left &&
rectSplat.left < rectTux.left +rectTux.width ;
if(touche){
score+=10;
}
else
{
score-=5;
}
document.getElementById('score').textContent=score;
},1000);
Pour supprimer un élément on utilise la méthode element.remove()
Faites en sorte que l'image splat soit supprimée lorsqu'elle a touché le pingouin.
Par ailleurs, on voudrait que les images qui n'ont pas touché soient affichées derrière le pingouin, pas devant.
Pour ça, on peut utiliser la propriété CSS z-index (en JS elle s'écrit zIndex).
Faites en sorte que l'image splat prenne un zIndex de -1 quand elle n'a pas touché.
setTimeout(function(){
let rectTux=tux.getBoundingClientRect();
let rectSplat=i.getBoundingClientRect();
let touche=
rectSplat.top +rectSplat.height >= rectTux.top &&
rectSplat.top < rectTux.top +rectTux.height &&
rectSplat.left+rectSplat.width >= rectTux.left &&
rectSplat.left < rectTux.left +rectTux.width ;
if(touche){
i.remove();
score+=10;
}
else
{
i.style.zIndex=-1;
score-=5;
}
document.getElementById('score').textContent=score;
},1000);
jeu.js
let score=0;
let tux=document.getElementById('tux');
document.addEventListener('keydown',function(event){
console.log('Touche enfoncée:',event.key);
let rect=tux.getBoundingClientRect();
console.log(rect);
let d=100;
let left=rect.left;
let top=rect.top;
if(event.key==='ArrowRight'){left+=d;}
if(event.key==='ArrowLeft' ){left-=d;}
if(event.key==='ArrowDown' ){top+=d;}
if(event.key==='ArrowUp' ){top-=d;}
left=Math.max(10,left);
top =Math.max(10,top);
left=Math.min(510-rect.width ,left);
top =Math.min(510-rect.height,top);
tux.style.left=left+"px";
tux.style.top=top+"px";
});
document.addEventListener('mousedown',function (event)
{
// Petit détail: éviter la sélection
event.preventDefault();
if(event.pageX-16<10 ||
event.pageY-16<10 ||
event.pageX-16+32>500+10 ||
event.pageY-16+40>500+10 ){return;}
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
document.body.append(i);
// Forcer le navigateur à prendre en compte la situation actuelle (position, scale).
// Ceci permettra au navigateur de s'apercevoir d'un changement futur des propriétés CSS.
window.getComputedStyle(i).top;
// Changer les propriétés CSS qui transitionnent.
// Le navigateur s'aperçoit du changement et déclenche la transition.
i.style.top =(event.pageY-16)+'px';
i.style.left=(event.pageX-16)+'px';
i.style.transform='scale(1)';
setTimeout(function(){
let rectTux=tux.getBoundingClientRect();
let rectSplat=i.getBoundingClientRect();
let touche=
rectSplat.top +rectSplat.height >= rectTux.top &&
rectSplat.top < rectTux.top +rectTux.height &&
rectSplat.left+rectSplat.width >= rectTux.left &&
rectSplat.left < rectTux.left +rectTux.width ;
if(touche){
i.remove();
score+=10;
}
else
{
i.style.zIndex=-1;
score-=5;
}
document.getElementById('score').textContent=score;
},1000);
});
Ceci n'est pas indispensable. C'est uniquement pour s'amuser.
Vous pouvez passer çà la page suivante si vous n'êtes pas en avance.
Au lieu de supprimer le splat qui a touché, changez son image et utilisez:
https://moodle.iutv.univ-paris13.fr/img/bjs/splat2.png
En utilisant un autre setTimeout, faites disparaître le splat qui a touché après 3000 millisecondes
let score=0;
let tux=document.getElementById('tux');
document.addEventListener('keydown',function(event){
console.log('Touche enfoncée:',event.key);
let rect=tux.getBoundingClientRect();
console.log(rect);
let d=100;
let left=rect.left;
let top=rect.top;
if(event.key==='ArrowRight'){left+=d;}
if(event.key==='ArrowLeft' ){left-=d;}
if(event.key==='ArrowDown' ){top+=d;}
if(event.key==='ArrowUp' ){top-=d;}
left=Math.max(10,left);
top =Math.max(10,top);
left=Math.min(510-rect.width ,left);
top =Math.min(510-rect.height,top);
tux.style.left=left+"px";
tux.style.top=top+"px";
});
document.addEventListener('mousedown',function (event)
{
// Petit détail: éviter la sélection
event.preventDefault();
if(event.pageX-16<10 ||
event.pageY-16<10 ||
event.pageX-16+32>500+10 ||
event.pageY-16+40>500+10 ){return;}
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
document.body.append(i);
// Forcer le navigateur à prendre en compte la situation actuelle (position, scale).
// Ceci permettra au navigateur de s'apercevoir d'un changement futur des propriétés CSS.
window.getComputedStyle(i).top;
// Changer les propriétés CSS qui transitionnent.
// Le navigateur s'aperçoit du changement et déclenche la transition.
i.style.top =(event.pageY-16)+'px';
i.style.left=(event.pageX-16)+'px';
i.style.transform='scale(1)';
setTimeout(function(){
let rectTux=tux.getBoundingClientRect();
let rectSplat=i.getBoundingClientRect();
let touche=
rectSplat.top +rectSplat.height >= rectTux.top &&
rectSplat.top < rectTux.top +rectTux.height &&
rectSplat.left+rectSplat.width >= rectTux.left &&
rectSplat.left < rectTux.left +rectTux.width ;
if(touche){
i.src="https://moodle.iutv.univ-paris13.fr/img/bjs/splat2.png";
getComputedStyle(i).top;
i.style.opacity=0;
setTimeout(function(){i.remove();},3000);
score+=10;
}
else
{
i.style.zIndex=-1;
score-=5;
}
document.getElementById('score').textContent=score;
},1000);
});
Le JavaScript (JS) est un langage de programmation, initialement développé pour le navigateur, mais maintenant aussi utilisé dans d'autres contextes. Il suit un standard appelé ECMAScript (ES). Le langage JavaScript n'a aucun lien avec le Java. Son nom a été choisi pour des raisons commerciales.
Le JavaScript est souvent utilisé dans le navigateur. Il est, en pratique, le langage qui permet d’interagir directement avec le navigateur. L’interaction avec le navigateur se fait à travers le DOM. C'est ce qu'on fait depuis le début de ce cours.
Le JavaScript peut aussi être utilisé en dehors du navigateur, principalement avec Node.js
De nombreux logiciels et librairies utilisant Node.js sont disponible par npm. Node.js est souvent utilisé coté serveur.
Quelles affirmations sont vraies ?
Le "serveur" musique.org est une machine dans un Datacenter distant.
Sur cette machine tourne un logiciel appelé un "serveur web".
Remarquez que le terme "serveur" peut avoir deux sens: la machine et le logiciel
1) Le navigateur demande au serveur web la page.html. C'est ce qu'on appelle une "requête"
2) Sur la machine tourne un logiciel appelé serveur web qui, reçoit la demande.
Le serveur web trouve le fichier page.html
3) Le serveur envoie page.html au navigateur. C'est ce qu'on appelle une "réponse"
4) Le navigateur reçoit page.html et l'affiche.
Ensuite, le navigateur va recommencer la même opération pour les fichiers CSS, JS, images, etc. référencés dans page.html
Pour une page HTML statique, quelles affirmations sont vraies ?
La distinction statique / dynamique est uniquement faite coté serveur. Dans les deux cas, le navigateur reçoit du HTML et ne voit pas la différence.
Pour une page dynamique, quelles affirmations sont vraies ?
Quelles technologies s'ont principalement employées coté serveur ?
Jusqu'à présent, dans ce cours, on a manipulé des fichiers HTML, CSS et JS. On n'a donc pas eu besoin de serveur.
Plus tard, on verra une technologie appelée AJAX, qui permet au JS de faire des requêtes au serveur.
Ce cours étant orienté IHM, on ne verra pas Node.js
Dans cette partie, on va apprendre à utiliser les objets et les tableaux.
En Java:
En JavaScript
Quelles affirmations sont vraies ?
En JavaScript, on peut créer un objet en utilisant les accolades "{", "}", et en spécifiant directement des propriétés et leurs valeurs.
Cette syntaxe est très utilisée en pratique.
Elle sert aussi comme un format d'échange de données appelé JSON. JSON est utilisé, entre autres, pour la communication entre le navigateur et le serveur. On étudiera JSON dans un autre cours.
let 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 ?
Oui, mais les guillemets ("left", "top") ne sont pas indispensables.
Les crochets "[" "]" servent à déclarer un tableau. Ici, on vous demande un objet.
En Java on ne peut pas utiliser une propriété qui n'a pas été déclarée dans la classe.
En JavaScript on peut ajouter des propriétés dynamiquement. Il n'y a pas de classe.
let joueur={pseudo: "Joe"};
XXXXX
Que faut-il écrire à la place de XXXXX pour ajouter à joueur la propriété score associée à la valeur 100 ?
Non. L'utilisation de parenthèses indique un appel de fonction. Ce n'est pas ce que l'on veut faire ici.
Non. Indice: L'ajout d'une propriété à un objet se fait très
simplement, sans utiliser de fonction.
En JavaScript, les fonctions sont des valeurs comme les autres (number, String, object...). On peut les attribuer à des variables. On peut aussi les attribuer aux propriétés d'un objet.
Donc, pour créer une méthode, il suffit de créer une propriété dont la valeur est de type "function".
Le JS ne fait rien de spécial pour gérer la méthode. afficherNotes est juste une propriété de l'objet, dont la valeur se trouve être de type "function".
Les tableaux JavaScript se déclarent avec des crochets [ ... ]. Les tableaux sont indexés par un entier et sont numérotés à partir de 0.
De nombreuses méthodes sont associées aux tableaux. Par exemple :
.push(v) permet d'ajouter une valeur à la fin d'un tableau.
.indexOf(v) renvoi l'indice de la première valeur v trouvée dans le tableau
Pour parcourir un tableau, utilisez une boucle for
.length permet d'obtenir la taille d'un tableau.
let parfums=XXXXX;Que faut-il écrire à la place de XXXXX pour créer un tableau contenant les chaînes suivantes : fraise, chocolat et vanille ?
let parfums=["fraise","chocolat","vanille"];
XXXXX
Que faut-il écrire à la place de XXXXX pour ajouter la valeur framboise à la fin du tableau parfums ?
let parfums=["fraise","chocolat","vanille"];Que faut-il écrire à la place de XXXXX pour afficher la taille du tableau dans la console ?
console.log(XXXXX);
let parfums=['fraise','chocolat','vanille','framboise'];Que faut-il écrire à la place de XXXXX pour créer une boucle for sur une variable numérique i qui affiche tous les éléments du tableau dans la console ?
XXXXX
On veut créer un panier comme ceci:
Voici le HTML à l'intérieur de <body>
<p id="parfums"><span>Fraise</span><span>Chocolat</span><span>Vanille</span><span>Framboise</span></p>
<h4>Panier:</h4>
<ul id="panier">
</ul>
Complétez le fichier panier.html
On mettra le CSS et le JS dans ce même fichier panier.html
Ajustez le CSS pour obtenir l'affichage ci-dessus.
Écrivez le code, vérifiez qu'il fonctionne dans votre navigateur,
puis copiez-le ici pour que votre enseignant puisse le relire plus tard:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Jeu</title>
<style type=>
#parfums span
{
padding: .5em;
margin: 1em;
border: 1px solid blue;
}
#parfums span:hover
{
background-color: #ffa;
}
</style>
</head>
<body>
<p id="parfums"><span>Fraise</span><span>Chocolat</span><span>Vanille</span><span>Framboise</span></p>
<h4>Panier:</h4>
<ul id="panier">
</ul>
<script>
</script>
</body>
</html>
Essayez de faire le JavaScript par vous même.
Vous pouvez vous inspirer de ce qui a été vu dans morpion.html pour réagir au click.
Vous pouvez vous inspirer de la création des images splat pour la création des li.
Si vous y arrivez, félicitations !
Dans tous les cas, on va le faire (ou refaire) ensemble, étape par étape, dans les pages suivantes.
Écrivez le sélecteur CSS permettant de désigner tous les span contenus dans l'élément ayant id="parfums"
Affichez 'click' sur la console chaque fois que l'utilisateur clique sur un des span dans parfums.
Indices:
let parfums=document.querySelectorAll('#parfums span');
for(let i=0;i<parfums.length;i++)
{
parfums[i].addEventListener('click',function(){
console.log('click');
});
}
Voyons comment créer puis ajouter un élément.
---
On va suivre les étapes ci-dessus, mais pas pour créer une image. On veut (2) créer une ligne <li>, puis (3) remplir son contenu, puis (4) l'ajouter au <ul id="panier"> (et non pas au body)
Commençons par l'étape (2) création:
Que faut-il écrire pour créer un élément li et le mettre dans une variable appelée « ligne » ?
let parfums=document.querySelectorAll('#parfums span');
for(let i=0;i<parfums.length;i++)
{
parfums[i].addEventListener('click',function(){
ICI
});
}
On voudrait copier ce qui est écrit dans le span cliqué vers ce qui sera écrit dans la ligne.
Que faut-il écrire ?
Rappel:
On a donc
let parfums=document.querySelectorAll('#parfums span');En vous inspirant du rappel ci-dessus, et en utilisant la variable panier (voir ci-dessus), que faut-il écrire pour ajouter la ligne crée au panier.
for(let i=0;i<parfums.length;i++)
{
parfums[i].addEventListener('click',function(){
console.log(this);
let ligne=document.createElement('li');
ligne.textContent=this.textContent;
let panier=document.getElementById('panier');
...
});
}
Attention: ici on veut ajouter la ligne au panier, pas au body.
Essayez avant de répondre. Votre programme devrait fonctonner.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Jeu</title>
<style type=>
#parfums span
{
padding: .5em;
margin: 1em;
border: 1px solid blue;
}
#parfums span:hover
{
background-color: #ffa;
}
</style>
</head>
<body>
<p id="parfums"><span>Fraise</span><span>Chocolat</span><span>Vanille</span><span>Framboise</span></p>
<h4>Panier:</h4>
<ul id="panier">
</ul>
<script>
let parfums=document.querySelectorAll('#parfums span');
for(let i=0;i<parfums.length;i++)
{
parfums[i].addEventListener('click',function(){
console.log(this);
let ligne=document.createElement('li');
ligne.textContent=this.textContent;
let panier=document.getElementById('panier');
panier.append(ligne);
});
}
</script>
</body>
</html>