This commit is contained in:
2026-01-30 11:50:02 +01:00
parent dae058c2d4
commit 0df1e71aeb
17 changed files with 560 additions and 0 deletions

BIN
R4.01_R4.A.10/cours/dom.pdf Normal file

Binary file not shown.

View File

@@ -0,0 +1,55 @@
# TP javascript : DOM
Un peu [d'aide](./aide.md).
#### Ex0
On stocke dans un objet une liste de favoris :
```js
let favs = [
{
nom:"Google",
url:"http://www.google.fr"
},
{
nom:"Le Monde",
url:"http://www.google.fr"
},
{
nom:"L'Equipe",
url:"http://www.lequipe.fr"
}
];
```
Compléter le fichier `favoris.js` de manière à créer dans la page html la liste de liens
correspondant
![lien}](./img/liens.png?style=centerme)
Il vous faut créer dynamiquement les noeuds nécessaires avec l'api dom de javascript.
#### Ex1
Il s'agit de réaliser une version "simple" du jeu (whac-a-mole)[https://en.wikipedia.org/wiki/Whac-A-Mole].
Le principe du jeu est de frapper à l'aide d'un marteau sur le plus grand nombre
de taupes parmi celles qui sortent pour un temps très limité et aléatoirement
des trous situés sur un panneau de contrôle.
<div align="center">
<img src="./img/mole.png">
</div>
#### Ex2
Vous devez compléter les [sources](./src/ex1) d'un jeu qui consiste à essayer
d'éteindre toutes les lumières d'une grille en utilisant la règle suivante.
Quand on allume/éteint une lumière, on allume/éteint aussi ses voisines.
<div align="center">
<img src="./img/lights.png">
</div>
Chaque lumière, via l'interface dataset, possède un numéro (de 0 à size^2-1).

View File

@@ -0,0 +1,132 @@
#### Selection d'éléments
```js
// le premier
document.querySelector(".box")
// ou tous
document.querySelectorAll(".box")
// avec l'id
document.getElementById("toto")
// selection d'un élément dans un autre
let container = document.querySeletor('.container')
container.querySelector('.box')
```
#### Traverser le dom
```js
var box = document.querySelector(".box")
box.nextElementSibling
box.previousElementSibling
box.parentElement
box.childNodes
```
#### Création/insertion d'éléments
```js
let p = document.createElement('p')
p.textContent="blabla"
document
.getElementById("myDiv")
.appendChild(p)
div.replaceChildren(p)
```
#### Gestionnaire évènementiels
```js
document.querySelector(".button").addEventListener("click", (e) => { /* ... */ })
document.querySelector(".button").addEventListener("mouseenter", (e) => { /* ... */ })
document.addEventListener("keyup", (e) => { /* ... */ })
```
#### window/document prêt
```js
document.addEventListener("DOMContentLoaded",() = > { .....})
// le dom a été construit (on n'attend pas le chargement du css, images, etc.
windon.addEventListener('load',()=>{...})
// le dom est prêt et toutes les ressources ont été chargées.
```
#### dataset
```html
<div id="user" data-id="1234567890" data-user="carinaanand" data-date-of-birth>
Carina Anand
</div>
```
```javascript
const el = document.querySelector("#user");
// el.id === 'user'
// el.dataset.id === '1234567890'
// el.dataset.user === 'carinaanand'
// el.dataset.dateOfBirth === ''
```
#### Local storage
```js
localStorage.setItem('monChat', 'Tom')
let cat = localStorage.getItem('myCat')
localStorage.clear()
```
#### Limiter les appels successifs à une fonction
```js
function debounce(f,wait)
{
let timeout
return function(...args){
clearTimeout(timeout)
timeout=setTimeout(()=>f(...args),wait)
}
}
```
#### Gestion du css depuis le DOM
```js
// Select the first .box and change its text color to #000
document.querySelector(".box").style.color = "#000";
// Set color to #000 and background to red
var box = document.querySelector(".box")
box.style.color = "#000"
box.style.backgroundColor = "red"
// Set all styles at once (and override any existing styles)
box.style.cssText = "color: #000; background-color: red"
// Hide and show an element by changing "display" to block and none
document.querySelector(".box").style.display = "none"
document.querySelector(".box").style.display = "block"
// Add, remove, and the toggle the "focus" class
var box = document.querySelector(".box")
box.classList.add("focus")
box.classList.remove("focus")
box.classList.toggle("focus")
box.classList.add("focus", "highlighted")
box.classList.remove("focus", "highlighted")
box.classList.add("focus", "highlighted")
box.classList.remove("focus", "highlighted")
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
>
<title>Favoris</title>
<script src="./js/favoris.js"></script>
</head>
<body>
<main>
<h1>Favoris</h1>
</main>
</body>
</html>

View File

@@ -0,0 +1,24 @@
let favoris = [
{
nom:"Google" ,
url:"www.google.fr",
img:"https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/200px-Google_2015_logo.svg.png"
},
{
nom:"Le Monde",
url:"lemonde.fr",
img:"https://upload.wikimedia.org/wikipedia/commons/thumb/2/22/Lemonde_fr_2005_logo.svg/200px-Lemonde_fr_2005_logo.svg.png?uselang=fr"
},
{
nom:"L'Equipe",
url:"www.lequipe.fr",
img:"https://upload.wikimedia.org/wikipedia/commons/thumb/3/32/L%27%C3%89quipe_wordmark.svg/200px-L%27%C3%89quipe_wordmark.svg.png"
}
]
window.addEventListener("load",()=>{
// TODO
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Whack-a-Mole Game</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main>
<div class="game">
<h1>Whack-a-Mole!</h1>
<div class="score-board">
<span>Score: </span><span id="score">0</span>
</div>
<div class="holes">
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole up"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
</div>
<button id="startButton">START</button>
</div>
</main>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,53 @@
const holes = document.querySelectorAll('.hole');
const moles = document.querySelectorAll('.mole');
const scoreBoard = document.getElementById('score');
const startButton = document.getElementById('startButton');
let lastHole;
let timeUp = false;
let score = 0;
let duration = 30
function randomTime(min, max) {
return Math.round(Math.random() * (max - min) + min);
}
function randomHole(holes) {
const idx = Math.floor(Math.random() * holes.length);
const hole = holes[idx];
if (hole === lastHole) {
return randomHole(holes);
}
lastHole = hole;
return hole;
}
function peep() {
const time = randomTime(1000, 1500);
const holerandomHole(holes);
// TODO
setTimeout(() => {
// TODO
//
}}, time);
}
function startGame() {
scoreBoard.textContent = 0;
score = 0;
timeUp = false;
// TODO
}
function bonk(e) {
// TODO
}
moles.forEach(mole => mole.addEventListener('click', bonk));
startButton.addEventListener('click', startGame);

View File

@@ -0,0 +1,68 @@
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
/* font-family: Arial, sans-serif;*/
}
.game {
text-align: center;
}
.holes {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
width: 400px;
margin: 20px auto;
}
.hole {
width: 100px;
height: 100px;
background : radial-gradient(rgb(150,250,150), #00ee00);
/* background-color: red;/*#8b4513;*/
/* background-image : url('img/mole2.png');*/
position: relative;
border-radius: 50%;
margin: 10px;
overflow: hidden;
}
.mole img{
width: 10px;
height: 10px;
/* background-color: #555;*/
position: absolute;
bottom: -100px;
left: 0px;
/*border-radius: 50%;*/
transition: bottom 0.3s;
}
.mole.up img{
/* background-image : url('img/mole2.png');
background-size:contain;
background-repeat: no-repeat;*/
width:90px;
height:90px;
bottom: 0px;
}
.mole.whacked img {
content: url('img/mole-whacked.png');
/* background-image : url('img/mole-whacked.png');
background-size:contain;
background-repeat: no-repeat;*/
width:90px;
height:90px;
bottom: -20px;
}
.score-board {
font-size: 1.5em;
margin: 20px;
}

View File

@@ -0,0 +1,71 @@
// variables de vue
const button = document.querySelector("input[type=submit]");
const select = document.querySelector("select");
const board = document.querySelector(".board");
const message = document.querySelector("#message");
let lights = null
// state <-> tableau de booléen pour
// stocker l'état des lumières
// neighbors <-> tableau des voisins de chaque lumière
let state = [];
let neighbors = [];
let newBoard = ( (size ) => {
let frag = document.createDocumentFragment()
// TODO
// la fonction crée dans le dom la grille des lumières
board.replaceChildren(frag)
});
let calcNeighbours = ( (size) =>{
let res = [];
for(let i = 0; i < size; i ++){
for(let j = 0; j < size; j++){
let v = [];
v.push(i*size + j);
if ( (j - 1) >= 0) v.push(i*size + j - 1);
if ( (j + 1) < size) v.push(i*size + j + 1);
if ( (i - 1) >= 0) v.push(size*(i-1) + j );
if ( (i + 1) < size) v.push(size*(i+1) + j);
res.push(v)
}
}
return res
});
function play(){
let size = select.value;
newBoard(size);
neighbors = calcNeighbours(size);
lights = document.querySelectorAll(".board span");
state = Array.from({length: size*size}, () => Math.random() < 0.5 ? 1:0);
state.forEach((el,i)=>{
if (el) lights[i].classList.toggle("off");
});
message.textContent = "";
}
// abonnements
document
.querySelector(".board")
.addEventListener("click", ev => {
// TODO
// permet de choisir d'éteindre/allumer une lumière et
// ses voisines
// Il faut en outre detecter la fin de partie
});
button.addEventListener("click",play);
play();

View File

@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!-- Centered viewport -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" title="no title" charset="utf-8">
</head>
<body>
<main>
<h4>Lights</h4>
<p>Le but est d'éteindre l'ensemble des lumières.</p>
<p id="message"></p>
<article>
<div class="board">
<!--div class="row">
<span data-num="0"></span>
<span data-num="1"></span>
<span data-num="2"></span>
</div>
<div class="row">
<span data-num="3"></span>
<span data-num="4"></span>
<span data-num="5"></span>
</div>
<div class="row">
<span data-num="6"></span>
<span data-num="7"></span>
<span data-num="8"></span-->
</div>
</div>
</article>
<div role="group">
<select aria-label="Select size" required>
<option selected value="3">3x3</option>
<option value="2">2x2</option>
<option value="6">6x6</option>
<option value="7">7x7</option>
<option value="8">8x8</option>
<option value="10">10x10</option>
</select>
<input type="submit" value="New Game">
</div>
</main>
<script src="app.js"></script>
</body>
</html>

View File

@@ -0,0 +1,50 @@
/*.grid {
display:grid;
grid-template-columns : 100px 100px 100px;
grid-template-rows: auto;
grid-gap: 10px;
}*/
.board > div {
display : flex;
}
.board span {
display: inline-block;
vertical-align:baseline;
width: 100px;
height: 100px;
/*padding : 1em;*/
margin : 0.1em;
cursor: pointer;
border: 1px solid #444;
border-radius: 50px;
background: radial-gradient(rgb(150,250,150), #00ee00);
}
.board span.off {
background: #009900;
}
.board span.off:hover {
background: #3AB903;
}
.board span:hover {
background: #3AB903;
background: radial-gradient(rgb(66, 255, 66), #065006);
}
/*
.wrapper {
display : flex;
justify-content: space-around;
}
.wrapper .grid {
flex-basis : auto;
}
*/