Bases de programmation illustrées en javascript,
Manipulation du Dom
Olivier Pons
(olivier.pons@lecnam.net)
2022
L'Extension showDomTree de chrome, permet (pour de petits exemples) de visualiser l'arbre de balise graphiquement.
Dans cette partie, nous utiliserons intensivement les outils de développement du navigateur (généralement accessibles par F12).
L'arbre est composé de noeuds. Il y a différents types de noeud.
Ce qui nous intéresseront le plus étant les noeuds élément (les rectangles sur l'image) et les noeuds texte (ellipse sur l'image).
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>exemple DOM</title>
<style>
#lediv {
height:10em;width:50%;border:solid;
background-color: orange;
}
</style>
</head>
<body>
<h1>Exemple pour la manipulation du DOM</h1>
<p>Un <em>petit</em> paragraphe</p>
<p>Un autre paragraphe</p>
<div id="lediv">un div</div>
</body>
</html>
L'objet document
(défini dans l’environnement hôte ,
ie. le navigateur) donne accès à l'arbre du document courant
(c'est-à-dire à votre page).
Il dispose d'un certain nombre de méthodes, notamment
document.getElementById(id)
Sur l'exemple précédent , on peut ainsi récupérer le
noeud d'id lediv
Ce noeud
est un object construit avec le constructeur
HTMLDivElement
getElementById
renvoie un noeud unique
ou null
si l'id
n'existe pas !
Sur l'exemple précédent , on peut ainsi récupérer les
noeud correspondants à des paragraphes (balise
p
)
Le résultats est un ensemble de noeuds
(techniquement une HTMLCollection
).
il peut être convertie en tableau de noeuds par :[...les_p]
document.getElementsByName(name)
et
[document.getElementsByClassName(nom_de_class)]https://developer.mozilla.org/fr/docs/Web/API/Document/getElementsByClassName)
fonctionnent sur le meme modèle pour récupérer des ensembles de noeuds à
partir d'un name
(pour les formulaires) ou d'un nom de
classe.
### Remarque :
Notez dans getElementById
il n'y a pas de s
à Element
car il renvoie un noeud unique. tout les autres
ont un s
car ils renvoient un ensemble de noeud.
On peut aussi récupérer les noeuds à partir de sélecteur css.
Pour récupérer le premier noeud correspondant au
sélecteur donc ici le premier paragraphe qui suit un paragraphe
(rappel +
est le combinateur
de voisin direct)
Pour récupérer tous les noeuds correspondant au sélecteur donc ici les paragraphes qui suivent un paragraphe.
Le résultat du premier est bien un noeud.
Le résultat du second est un ensemble de noeuds (qui là encore n'est pas
un tableau mais peut être converti). Ici l'ensemble de type
NodeList
ne contient qu'un noeud.
HTMLCollection
et NodeList
sont tres
similaire et ne sont pas des tableaux.
voir ici pour
une comparaison.
On a présenté javascript comme un langage événementiel et on a déjà présenté brièvement avec les timers le modèle d'execution et la notion de callback (ou fonction de rappel).
Les événements sont des actions ou des occurrences qui se produisent dans le système.
Il y a des « événements généraux » comme un temps écroulé dans les
timers et des événement associé à des object (généralement
window
, document
ou un noeud Élément).
Javascript permet de définir du code attaché au déclenchement d'un un événement sur un object.
Attaché à un élément peut se faire en html
c'est simple pour débuter,
mais il est mieux pour la separation des rôles (description en html,
présentation en css, comportement en js) de le faire dans le code
javascript en attachant une gestion d'événement sur un object l'aide de
addEventListener
et d'une fonction de callback.
let p=document.getElementByid("unid");
p.addEventListener("click",function (){alert("on a cliqué")});
On peut aussi ajouter des événements sur l'object
window
, par exemple un événement load
. qui est
déclenché lorsque la page et toutes ses ressources
dépendantes (telles que des feuilles de style et des images)
sont complètement chargées.
load
Cet événement est souvent utilisé; En effet pour pouvoir récupérer et manipuler un noeud (ou une ressource (par exemple une image)), il faut que ce noeud (ou cette ressource) existe, donc qu'il aie été créer et donc que le chargement et le traitement (analyse du source et creation du dom) soit terminé.
C'est ce que permet d'attendre l'événement load.
par exemple:
click
se déclenche quand l’élément auquel il est attaché st cliqué.
mouseUp
et mousseDown
precise un peut les chose et correspondent à l'appui ou au relâchement
du bouton de souris. (sur tablette, ou dispositif tactile, ils
correspondent aussi au fait de poser ou enlever le doigt).
Lors du déclenchement de l'événement, les caractéristiques de
l'évènement sont transmises à la fonction de rappel. On peut par exemple
récupérer la position du click
:
Dans l'exemple ci-dessous on affiche les coordonnées du
click
grace au propriétes clientX
et clientY
.
<div id="exDomClickEvent" style="width=50%; height: 5em; border:solid 2px;"></div>
<script>
document.getElementById("exDomClickEvent").addEventListener("click",testClick)
function testClick(ev) {
alert("souris en " + ev.clientX + " " + ev.clientY);
}
</script>
La encore des caractéristiques de l’événement sont disponible notamment la touche pressée.
La propriété key
de l’objet évènement permet d’obtenir un caractère, tandis que la
propriété code
de l’objet évènement objet permet d’obtenir le code de la touche
physique (il y a un code de touche car il peut y avoir plusieurs touches
pour le même caractère , par exemple pour les chiffres).
Il faut parfois combiné les 2, par exemple, la même touche A peut être appuyée avec ou sans Shift. Cela nous donne deux caractères différents : minuscule a et majuscule A.
<p>Tapez sur des touches ...
<input id=exDomKeyEvent type="text">
</p>
<script>
document.getElementById("exDomKeyEvent").addEventListener("keydown",montreTouche)
function montreTouche(e){
alert("code de touche "+e.code);
alert("caractère "+e.key);
}
</script>
Tapez sur des touches ...
A noter que si la fonction de rappel fait appel a
preventDefault
(ou si elle est lié dans le html par un
onkeydown
et renvoie false
), le caractère
taper n'est pas inséré.
Dans l'exemple ci dessous on interdit de taper des chiffres
<p id="exKeyFiltre">Tapez du texte (mais pas de chiffre)
<input type="text" >
</p>
<script>
let i=document.querySelector("#exKeyFiltre input");
i.addEventListener("keydown",filtreNombre);
function filtreNombre(e)
{
console.log(e.key);
if( "0123456789".indexOf(e.key) != -1)
{e.preventDefault()};
}
<script>
Tapez du texte (mais pas de chiffre)
Une fois un (ou des noeuds) « récupérés » on peut récupérer, positionner ou modifier leur style (inline).
On pourra aussi (c'est moins simple) récupérer, ajouter , supprimer des feuille de style, et y ajouter ou supprimer des règles
autrenoeud=document.querySelector("monId")
autrenoeud.display="block"
autrenoeud.width="100px"
autrenoeud.color="red"
Le nom des propriétés est généralement le meme qu'en CSS,
sauf s'il contient des tirets -
, auquel cas on supprime le
tiret et capitalise la premiere lettre du mot suivant.
Par exemple: background-color
devient
backgroundColor
<div id="ex1" style="border:solid">
<p id="dutext"> Du texte </p>
<button id="changer">Changer la couleur</button>
</div>
<script>
let i=0;
//tableau des couleurs
let colors=["green","yellow","red"];
let t=document.querySelector("#ex1 #dutext");
let b=document.querySelector("#ex1 #changer");
// a chaque appel i augment et l'indice de la couleur est i%3
b.addEventListener("click",()=>{t.style.backgroundColor=colors[++i%3]})
</script>
Du texte
Modifier l'attribut style
d'un élément nous limite à
l'élément.
On peut aussi accéder aux styles définis dans les feuilles de style.
On peut acceder à la liste des feuille de style par
la propriété stylesSheets
du document qui renvoie une
collection de feuille de style.
On accède aux feuille de style par leur indice dans cette collection.
Puis dans chaque feuille de style à la liste des règles par la
propriété cssRules
qui renvoie une liste de règle.
On accède à chaque règle par son indice.
Puis pour chaque règle on a les propriétés: - cssText
qui correspond au texte de la règle dans la feuille de style -
selectorText
qui correspond au sélecteur utilisé dans la
feuille de style - style
qui donne une liste des propriétés
positionnées, suivie des couples (clef/valeur)
On peut ajouter des réglés( méthode addRule
ou
insertRule
) ou supprimer une règle à partir de son indice
grace à deleteRule
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="exempleDomStyleSheet.css">
<style>
#deux {background-color:yellow}
</style>
</head>
<body>
<p id="un">Un </p>
<p id="deux">Deux </p>
<p style="background-color:red">Trois</p>
<button onclick="voir()">voir feuille</button>
</body>
<script>
function voir(){
//récupérer toute les feuilles
// de style (externe et interne)
lesfeuilles=document.styleSheets;
alert(lesfeuilles)
//recuperer la feuille interne
// indice 1 car c'est la seconde
let interne= document.styleSheets[1];
alert(interne);
//les regle de cette page
lesregles=interne.cssRules;
alert(lesregles);
//le texte de la regle 0
alert(lesregles[0].cssText);
//ajouter une regle
interne.insertRule("#un {color:red}",0)
}
</script>
</html>
Vous ne pouvez accéder aux règles d'une feuille externe que si elle
est sur le meme serveur que votre page html. En particulier certain
navigateur refuse cette accès si vous lisez la page en locale
(file://
)
Quand un style est hérité ou peut provenir de plusieurs réglés on
peut vouloir savoir quelle valeur a (au moment de l'execution) une
certaine propriété , c'est le style calculé qu'on peut acceder par la
propriété getComputedStyle
On peut aussi modifier d'autres attribut que le style par exemple la
source (src
) sur une image.
class
et
id
Lorsque vous récupérez un noeud n
.
Les propriétés id
et className
vous permettent de lire ou de positionner les attributs id
ou class
du noeud.
c'est bien className
car le mot clef class
est réservé la definition de classe en programmation objet ).
La propriété classList
(en lecture seule) renvoie une liste des attributs class
de
l'objet.
Pour modifier cette liste on dispose des méthodes add
et
remove
<style>
#exempleDomClassId .rouge {
color:red
}
#exempleDomClassId .gros {
font-size:200%;
}
#exempleDomClassId #mondiv {
background-color:yellow;
}
</style>
<div id="exempleDomClassId">
<div class="rouge" style="height:50px;">
cliquer un bouton
</div>
<button onclick="montreClasse()">voir classe</button>
<button onclick="ajouteClasseGros()">ajouter classe cadre</button>
<button onclick="addId()">ajouter id</button>
<button onclick="reinitialiser()">réinitialise</button>
</div>
<script>
let mondiv=document.querySelector("#exempleDomClassId div");
function montreClasse(){alert(mondiv.className);}
function ajouteClasseGros(){mondiv.className="gros";}
function addId(){mondiv.id="mondiv";}
function reinitialiser(){
mondiv.classList.remove("gros");
mondiv.classList.add("rouge");
mondiv.id="";
}
</script>
cliquer un bouton
On a vu que les attributs (style
, id
,
class
, src
...) peuvent être lu et positionné
a partir de leur nom. Pour les supprimer on peut positionner la valeur a
""
mais ca ne supprime pas l'attribut.
On dispose aussi de méthode de manipulation générale d'attribut :
getAttribute
pour la lecture
setAttribute
pour le positionnement d'un attribut
removeAttribute
pour supprimer un attribut
hasAttribute
pour tester la présence d'un attribut.
Il y a essentiellement deux méthodes:
Lorsque vous récupérez un noeud n
.
innerHTML
vous permet de a. lire le code html correspondant
au sous arbre issus de n
:
```js
n.innerHTML;
```js
b. remplacer le sous arbre issus de `n` par l'arbre obtenu en analysant la chaîne, contenant du code html , passée en argument :
```js
n.innerHTML="du <b>code <em> html </em> <b>."
```
Cela peut pauser problème si le code html que vous passez en argument n'est pas valide.
avec createTextNode
createElement
Une fois les noeuds crées ils n'apparaissent pas pour autant car il n'est pas encore rattaché a l'arbre du document qui est le seul visible.
Pour cela il faut les rattaché à un noeud existant de l'arbre au moyen d'une des méthodes:
appendChild
append
insertBefore
after
replaceChild
](https://developer.mozilla.org/fr/docs/Web/API/Node/replaceChild-
...<html>
<head>
<script>
//
//
window.onload = function() {
//créer un noeud element h1
const h1 = document.createElement("h1");
//creer un noeud texte
const texte_du_h1 = document.createTextNode("Ajout d'un titre H1");
//liaison du texte au h1
h1.appendChild(texte_du_h1);
//liaison du h1 sur l'arbre du document
//comme dernier enfant du noeud body
document.body.appendChild(h1);
}
</script>
</head>
<body>
</body>
</html>
Pour « descendre » depuis un noeud : 1. Les noeuds enfants d'un
noeud: - childNodes
renvoie la liste des fils d'un noeud.
On a deux cas particulier:
firstChild
renvoie le premier filslastChild
renvoie le dernier filsnextSibling
donne le frère droit
previousSibling
donne le frère gauche
Pour remonter:
parentNode
pour remonter sur le parent.
<ol id="maListeOrdonnee">
<li> Récupérer l'élément racine à partir duquel on fera le parcours.</li>
<li> Utiliser childNodes pour parcourir les fils des éléments en question.</li>
<li> Pour les dit fils, on regardera quel est leur type, et on agira en conséquence.</li>
</ol>
<p>Parcours d'<strong>arbre</strong></p>
Exemple: on veut afficher le <em>texte</em> de la liste précédente dans l'élément ci-dessous.
<button onclick="copierListe()">copier</button>
<div id="ciblePourCopie" style="border:solid">
texte quelconque
</div>
<script type="text/javascript">
function copierListe() {
// On récupère l'élément de base
var eltDeBase= document.getElementById('maListeOrdonnee');
var txt= getTexteDans(eltDeBase);
document.getElementById('ciblePourCopie').firstChild.nodeValue= txt;
}
function getTexteDans(noeud) {
var result= "";
var i;
// Le texte contenu dans un noeud
// est celui contenu dans ses enfants, si c'est un élément
// et est nodeValue si c'est un noeud texte.
switch (noeud.nodeType) {
case 1: // element
for (i=0; i< noeud.childNodes.length; i++) {
result+= getTexteDans(noeud.childNodes[i]);
}
break;
case 3: // texte
result= noeud.nodeValue;
break;
}
return result;
}
</script>
Parcours d'arbre
Exemple: on veut afficher le texte de la liste précédente dans l'élément ci-dessous.Javascript permet de valider les formulaires côté client.
Cela ne dispense pas de la validation côté serveur,
qui est indispensable pour des raisons de sécurité; en effet
le serveur n'a a priori aucune raison de faire confiance au client.
On peut accéder facilement aux formulaires et au
champs par leurs id
si on leur en donne.
On peut toujours accéder aux formulaires et au champs via querySelector
ou une autre méthode de selection.
On lie des fonctions javascript à certains événements (on soumet le formulaire, on quitte un champ, on valide le formulaire, on presse une touche...)
On veut que le formulaire soit vérifié juste avant d'être expédié
On utilise l'événement submit
Quand le formulaire va être envoyé, apres un élément
submit
, le navigateur appelle le code javascript dans
onsubmit
ou associé a submit
par
addEventListener
Si la valeur de onsubmit
a la forme
return nomDeFonction()
alors,
Si on a un addEventListener
de la forme
addEventListener("submit",nomDeFonction)
(sans les
()
) alors,
preventDefault
,
l'action est effectuéeOn veut tester que le nom et le prénom fournis par l'utilisateur ne sont pas vides.
<div>
<form id="ExForm1" action=https://cedric.cnam.fr/~pons/NFA040/echo.php>
<label for='nom'> Nom </label>
<input type='text' id='nom' name='nom'>
<label for='prenom'> prenom </label>
<input type='text' id='prenom' name='prenom'>
<input type='submit' id='envoyerEx1'>
</form>
<script>
function verifNomPrenom(){
let nom=document.getElementById('nom').value;
let prenom=document.getElementById('prenom').value;
if (nom !="" && prenom !=""){
alert("c'est bon on envoi");return true;
}
else {
alert("c'est pas bon on n'envoi pas ");return false;
}
}
document.getElementById('ExForm1').addEventListener("submit",function (e){
if (!verifNomPrenom()){
e.preventDefault();
return false;
}
return true})
</script>
</div>
on peut utiliser les événements blur
ou change
,
(onblur
et onchange
si vous les prositionner
comme attribut dans le html) pour tester des champs en cours ou en fin
d'editions.
blur
, le code est appelé quand le curseur quitte
le champ (il perd le "focus"),change
, le code est appelé quand le curseur quitte
le champ et que la valeur a changé;change
s'utilise aussi pour un champ de type
select
, auquel cas il permet tout simplement de savoir que
la sélection a été modifiée.
Ils s'utilise en complément de
submit
On n'a pas besoin de retourner une valeur
cliquez dans nom, puis dans prenom, taper des lettre, cliquez en dehors...
<div>
<form id="Ex2Form" action="https://cedric.cnam.fr/~pons/NFA040/echo.php">
<label for='Ex2nom'> Nom </label>
<input type='text' id='Ex2nom' name='Ex2nom'>
<span id="Ex2ErreurNom" class="error"></span> <br>
<label for='Ex2prenom'> prenom </label>
<input type='text' id='Ex2prenom' name='Ex2prenom'>
<span id="Ex2ErreurPrenom" class="error"></span> <br>
<input type='submit' id='envoyerEx2'>
</form>
<script>
function verifNomPrenom(){
let nom=document.getElementById('Ex2nom').value;
let prenom=document.getElementById('Ex2prenom').value;
if (nom !="" && prenom !=""){
alert("c'est bon on envoi");return true;
}
else {
alert("c'est pas bon on n'envoi pas ");return false;
}
}
document.getElementById('Ex2Form').addEventListener("submit",function (e){
if (!verifNomPrenom()){
e.preventDefault();
return false;
}
return true})
let Ex2nom=document.getElementById('Ex2nom') ;
let Ex2ErreurNom=document.getElementById('Ex2ErreurNom') ;
let Ex2prenom=document.getElementById('Ex2prenom') ;
let Ex2ErreurPrenom=document.getElementById('Ex2ErreurPrenom') ;
alert(Ex2nom.id)
Ex2nom.addEventListener("blur",function (e){
alert("sortie du champ Nom");
if(Ex2nom.value===""){
Ex2ErreurNom.innerHTML="nom ne doit pas être vide !";
}
e.preventDefault();
});
Ex2prenom.addEventListener("change",function (e){
alert("changement dans prenom");
if(Ex2prenom.value===""){
Ex2ErreurPrenom.innerHTML="prenom ne doit pas être vide !";
}
e.preventDefault();
});
</script>
</div>
radio
, checkbox
select/option
name : c'est le nom de l'élément (et de la variable qui sera
envoyée au serveur)
On peut l'utiliser (avec getElementsByName
) pour récupérer
toutes les « cases » d'un groupe de checkbox ou de bouton radio
checked :est booléen permettant de savoir si l'élément est coché.
en lecture et en écriture (pour cocher la case, on positionnera
checked=checked
).
value : valeur de l'élément.
<div id="checkbox1Code"><p>Checkbox <input type="checkbox" value="checkcheck" id="checkbox1"/></p>
<p><button onclick="alert(document.getElementById('checkbox1').checked)">montrer valeur</button></p>
<p><button onclick="document.getElementById('checkbox1').checked=!
document.getElementById('checkbox1').checked">
changer valeur</button>
</p>
</div>
Checkbox
il n'y pas d'événement change
sur les checkbox ou radio
!
Utilisez l'évènement click
<div id="checkbox2Code">
<p>Checkbox <input type="checkbox" value="checkcheck" id="checkbox2" onclick="montreCheckBox()"/></p>
<script type="text/javascript">
function montreCheckBox() {
var elt= document.getElementById('checkbox2');
alert("cochée : "+ elt.checked);
}
</script>
</div>
Checkbox
select
Un élément select
contient des éléments
option
.
Si le select
ne permet qu'une sélection (ie. n'a pas
l'attribut multiple
), on utilisera la propriété value du
select :
Sinon, on récupérera le tableau des options (options[]) ou on attaquera directement l'option désirée.
Le code suivant donne la première option sélectionnée:
Dans le cas où il y a plusieurs options sélectionnables, le code suivant les range les options sélectionnées dans un tableau:
<select id="Exmonselect" multiple="multiple" size="3">
<option selected="selected">un</option>
<option>deux</option>
<option selected="selected">trois</option>
<option>quatre</option>
</select>
<button onclick="voirLesSelect()">voir les valeurs sélectionnées</button>
<script>
function voirLesSelect(){
let ExmonSelect=document.getElementById("Exmonselect");
let o= ExmonSelect.options;
let resultat=[];
for (let i= 0; i < o.length; i++) {
if (o[i].selected) {
resultat.push(o[i].value);
}
}
alert(resultat)
}
</script>
Le select a aussi une propriété selectedIndex
qui donne
la position du premier élément sélectionné.
Notez que value
, selectedIndex
(pour les
select) et selected
pour les options peuvent être
modifiés.
<canvas>
est une balise qui permet de définir une
zone graphique ou l'on peut dessiner des graphiques, placer et manipuler
des images ou des trame video.
Le contenu visuel à l'intérieur du canevas peut être scripté pour
changer au fil du temps (d'où l'animation) et en réponse à des
événement.
Il faut d'abord récupérer le canvas et le context de dessin 2D associé.
Il est aussi possible de récupérer un context 3D et de le manipulé
avec la bibliothèque three.js
mais cela dépasse
le cadre de ce cours.
On peut alors dessiner dans la zone à l'aide des méthodes suivant:
ctx.strokeRect(x, y, largeur, hauteur)
et ctx.fillRect(x, y, largeur, hauteur)
permettent
de dessiner des rectangles (plein ou non), x
et
y
donnant les coordonnées du coins supérieur gauche.ctx.arc(x, y, rayon, angleDépart, angleFin, sensAntiHoraire)
angleDépart
et angleFin
sont
respectivement de 0 et \(2x\Pi\).fill
(rempli) ou stroke
(contour) `On peut aussi dessiner diverse forme grace à cette notion de chemin.
Un chemin est une liste d'action. L'idée et de lister des
déplacements et des tracés qui ne seront effectués qu'après par un appel
a stroke
ou fill
.
ctx.moveTo(x, y)
permet d'enregistrer un déplacement sans tracer vers un point.
ctx.lineTo(120, 120)
permet d'enregistrer un tracé une ligne de puis le point courant vers un
point.
ctx.rect(x, y, largeur, hauteur)
permet
d'enregistrer le tracé d'un rectangle.
ctx.stroke()
permet de déclencher l'affichage du contours
ctx.fill()
permet
de déclencher l'affichage du contours rempli.
ctx.beginPath()
et ctx.closePath()
d'initier et de fermer un chemin (close reliera éventuellement le
dernier point au point initial) .
On peut aussi définir des style, essentiellement des couleurs
d'écriture ou de remplissage. par les méthodes ctx.fillStyle
et ctx.strokeStyle
.
<html>
<head>
<script>
// les objects
let balle = {
x:150, // position de la balle en x.
y: 150, // position de la balle en y.
dX: 2, // pas de déplacement en x
dY: 4, // pas de déplacement en y
move(terrain,pallet){
}
}
let terrain ={
l: 300, // largeur du terrain de jeu.
h:300 // hauteur du terrain de jeu
}
let palet ={
x: 150, // position de de la raquette
h: 10, // épaisseur de la raquette
l: 150, // largeur de la raquette.
y:function() {return terrain.h - this.h} // position de la raquette en y (coin sup gauche).
}
let canvas; // l'element Canvas.
let ctx; // le context du Canvas.
let gameLoop; // nom du timer utilise dans la boucle de jeu (via setInterval)
// fonction d'initialisation sera appellé sur l'evenement onLoad
function initGame() {
// recuperer le canvas.
canvas = document.getElementById("gameBoard");
// verifier qu'il existe.
if (canvas.getContext) {
// choisir le context 2d
ctx = canvas.getContext("2d");
// jouer jusqu'a ce qu'on perde
gameLoop = setInterval(drawBall, 16);
// Add keyboard listener.
window.addEventListener('keydown', quelleTouche, true);
}
}
//fonction de dessin
function drawBall() {
// Effacer le terrain.
ctx.clearRect(0, 0, terrain.l, terrain.h);
// Remplir le terrain.
ctx.fillStyle = "green";
ctx.beginPath();
ctx.rect(0, 0, terrain.l, terrain.h);
ctx.closePath();
ctx.fill();
// Dessinner la balle.
ctx.fillStyle = "red";
ctx.beginPath();
ctx.arc(balle.x, balle.y, 15, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
// Dessinner la raquette
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.rect(palet.x, palet.y(), palet.l, palet.h);
ctx.closePath();
ctx.fill();
// Changer la position de la balle.
balle.x += balle.dX;
balle.y += balle.dY;
// Rebond sur la gauche ou la droite (inversion du DX)
if (balle.x + balle.dX > terrain.l - 15 ||
balle.x + balle.dX < 15) {
balle.dX = -balle.dX;
}
// Rebond au sommet (inversion du DY)
if (balle.y + balle.y < 15) balle.dY = -balle.dY;
// Si la balle touche le bas, verifier si elle touche la raquette
else if (balle.y + balle.dY > terrain.h - 15) {
// Si elle touche la raquette, rebondir (inversion du DY)
if (balle.x > palet.x && balle.x < palet.x + palet.l) balle.dY = -balle.dY;
// Sinon c'est perdu
else {
clearInterval(gameLoop);
alert("Game over!");
}
}
}
/* Traitement des événements */
function quelleTouche(evt) {
switch (evt.code) {
// fleche gauche.
case "ArrowLeft":
palet.x = palet.x - 20;
if (palet.x < 0) palet.x = 0;
break;
// fleche droite.
case "ArrowRight":
palet.x = palet.x + 20;
if (palet.x > terrain.l - palet.l) palet.x = terrain.l - palet.l;
break;
}
}
</script>
</head>
<body onload="initGame()">
<h1>
jeux de raquette
</h1>
<div>
<canvas id="gameBoard" width="300" height="300">
</canvas>
</div>
</body>
</html>
Que vous pouvez tester ici