tp3
@ -4,6 +4,10 @@
|
|||||||
[Compléments de javascript](cours/jscomp.pdf) javascript, [tp1](./td_tp/tp1)
|
[Compléments de javascript](cours/jscomp.pdf) javascript, [tp1](./td_tp/tp1)
|
||||||
|
|
||||||
#### Semaine 2
|
#### Semaine 2
|
||||||
[DOM](cours/dom.pdf), [tp2](./td_tp/tp2)
|
[DOM](cours/dom.pdf), [tp2](./td_tp/tp2), [tp2_bis](./td_tp/tp2_bis)
|
||||||
|
|
||||||
|
#### Semaine 3
|
||||||
|
[Promesses, Ajax, API de données](cours/ajax.pdf), [tp3](./td_tp/tp3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BIN
R4.01_R4.A.10/cours/ajax.pdf
Normal file
44
R4.01_R4.A.10/td_tp/tp2_bis/README.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# TP javascript : DOM
|
||||||
|
|
||||||
|
Un peu [d'aide](./aide.md).
|
||||||
|
|
||||||
|
#### Ex1
|
||||||
|
|
||||||
|
Complétez le code du fichier <code>[game.js](./src/ex1/js/game.js)</code> inclus
|
||||||
|
dans <code>[cookie.html](./src/ex1/cookie.html)</code> afin de concevoir un idle game
|
||||||
|
consistant à cliquer sur un cookie le plus grand nombre de fois en 15
|
||||||
|
secondes.
|
||||||
|
|
||||||
|
|
||||||
|
<div style="text-align:center">
|
||||||
|
<img src="./img/cookie1.png">
|
||||||
|
<img src="./img/cookie2.png">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
#### Ex2 : memory
|
||||||
|
|
||||||
|
Le jeu tirera aléatoirement des ampoules allumées, les dévoilera
|
||||||
|
pendant une seconde au joueur, puis les cachera à nouveau.
|
||||||
|
Le joueur doit alors cliquer sur chaque ampoule initialement allumée. S'il se trompe,
|
||||||
|
une alerte lui signifie qu'il a perdu. Lorsque toutes les ampoules ont été retrouvées, le joueur gagne.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Vous devez seulement complèter le fichier `memory.js`
|
||||||
|
|
||||||
|
|
||||||
|
#### Ex3 **Glisser/Déposer** (pour ceux qui ont **tout** fait)
|
||||||
|
Le but est de trier un tableau d'entiers, par ordre croissant, par glisser/déposer (drag and drop).
|
||||||
|
|
||||||
|
<img src="./img/tri.png" width="100%" class="img-polaroid">
|
||||||
|
<img src="./img/tri1.png" width="100%" class="img-polaroid">
|
||||||
|
<img src="./img/tri2.png" width="100%" class="img-polaroid">
|
||||||
|
|
||||||
|
Travail à faire
|
||||||
|
- La génération des entiers dans les divisions "draggable".
|
||||||
|
- La sensibilisation aux événements <code>dragstart, drop, dragover</code>. Vous trouverez toute l'information utilie sur l'interface drag and drog d'html5 <a target="_blank" href="http://www.w3schools.com/html/html5_draganddrop.asp">ici</a>.
|
||||||
|
- Dans la zone correspondante au tableau trié, le fond change de couleur suivant que les entiers déjà déposés sont triés correctement ou non.
|
||||||
|
|
||||||
|
Pour gérer les classes css d'un noeud, vous pouvez utilisez la propriété <a href="https://developer.mozilla.org/fr/docs/Web/API/Element/classList" target="_blank">classList</a>.
|
||||||
|
|
||||||
|
|
118
R4.01_R4.A.10/td_tp/tp2_bis/aide.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#### 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.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### 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")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
BIN
R4.01_R4.A.10/td_tp/tp2_bis/img/cookie1.png
Normal file
After ![]() (image error) Size: 256 KiB |
BIN
R4.01_R4.A.10/td_tp/tp2_bis/img/cookie2.png
Normal file
After ![]() (image error) Size: 271 KiB |
BIN
R4.01_R4.A.10/td_tp/tp2_bis/img/memory.png
Normal file
After ![]() (image error) Size: 62 KiB |
BIN
R4.01_R4.A.10/td_tp/tp2_bis/img/tri.png
Normal file
After ![]() (image error) Size: 44 KiB |
BIN
R4.01_R4.A.10/td_tp/tp2_bis/img/tri1.png
Normal file
After ![]() (image error) Size: 45 KiB |
BIN
R4.01_R4.A.10/td_tp/tp2_bis/img/tri2.png
Normal file
After ![]() (image error) Size: 46 KiB |
26
R4.01_R4.A.10/td_tp/tp2_bis/src/ex1/cookie.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||||
|
<title>Cookie clicker</title>
|
||||||
|
<link rel="stylesheet" href="./css/style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Cookie clicker</h1>
|
||||||
|
<figure>
|
||||||
|
<img src="img/cookie.png" alt="cookie">
|
||||||
|
<span>0</span>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<button>start</button>
|
||||||
|
|
||||||
|
<p class="hidden">
|
||||||
|
<img src="img/memee.png" alt="memee" width="64" height="64">
|
||||||
|
<span></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="./js/game.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
R4.01_R4.A.10/td_tp/tp2_bis/src/ex1/css/img/bg.jpg
Normal file
After ![]() (image error) Size: 54 KiB |
63
R4.01_R4.A.10/td_tp/tp2_bis/src/ex1/css/style.css
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
@import url(https://fonts.googleapis.com/css?family=Kavoon);
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-image: url("img/bg.jpg");
|
||||||
|
background-repeat: repeat;
|
||||||
|
font-family: Kavoon;
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 320px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.25);
|
||||||
|
padding: 10px 40px 10px 40px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure > span {
|
||||||
|
position: absolute;
|
||||||
|
top: 25px;
|
||||||
|
right: 50px;
|
||||||
|
border-radius: 21px;
|
||||||
|
height: 42px;
|
||||||
|
width: 56px;
|
||||||
|
background-color: #f4d03f;
|
||||||
|
box-shadow: 4px 4px 4px black;
|
||||||
|
padding-top: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
font-family: Kavoon;
|
||||||
|
font-size: 24px;
|
||||||
|
background-color: white;
|
||||||
|
padding: 9px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
img[alt="GrandMa"] {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
BIN
R4.01_R4.A.10/td_tp/tp2_bis/src/ex1/img/bg.jpg
Normal file
After ![]() (image error) Size: 54 KiB |
BIN
R4.01_R4.A.10/td_tp/tp2_bis/src/ex1/img/cookie.png
Normal file
After ![]() (image error) Size: 103 KiB |
BIN
R4.01_R4.A.10/td_tp/tp2_bis/src/ex1/img/memee.png
Normal file
After ![]() (image error) Size: 11 KiB |
1
R4.01_R4.A.10/td_tp/tp2_bis/src/ex1/js/game.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
// TODO
|
11
R4.01_R4.A.10/td_tp/tp2_bis/src/ex2/css/style.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
img{
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gagne,#perdu,.hidden{
|
||||||
|
display : none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress::-webkit-progress-value {
|
||||||
|
transition: width 0.5s ease;
|
||||||
|
}
|
BIN
R4.01_R4.A.10/td_tp/tp2_bis/src/ex2/images/off.png
Normal file
After ![]() (image error) Size: 9.1 KiB |
BIN
R4.01_R4.A.10/td_tp/tp2_bis/src/ex2/images/on.png
Normal file
After ![]() (image error) Size: 9.5 KiB |
1
R4.01_R4.A.10/td_tp/tp2_bis/src/ex2/js/memory.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
// TODO
|
64
R4.01_R4.A.10/td_tp/tp2_bis/src/ex2/memory.html
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="initial-scale=1,width=device-width">
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
||||||
|
<link rel="stylesheet" href="./css/style.css">
|
||||||
|
<script src="./js/memory.js"></script>
|
||||||
|
|
||||||
|
<title>Memory</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="m-4">
|
||||||
|
<main class="container">
|
||||||
|
<h1 class="title is-1 has-text-primary">Memory</h1>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column is-6">
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<img src="./images/off.png" alt="" />
|
||||||
|
<img src="./images/off.png" alt="" />
|
||||||
|
<img src="./images/off.png" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<img src="./images/off.png" alt="" />
|
||||||
|
<img src="./images/off.png" alt="" />
|
||||||
|
<img src="./images/off.png" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<img src="./images/off.png" alt="" />
|
||||||
|
<img src="./images/off.png" alt="" />
|
||||||
|
<img src="./images/off.png" alt="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column is-6">
|
||||||
|
<h3 class="title is-3 has-text-primary">Règles</h3>
|
||||||
|
<p class="block is-size-4">
|
||||||
|
Pendant une seconde, vous verrez l'état de l'ensemble
|
||||||
|
des ampoules, puis elles seront éteintes. Vous devrez
|
||||||
|
alors cliquer sur celles qui étaient allumées.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button class="block button is-info">COMMENCER</button>
|
||||||
|
<progress id="temps" class="progress is-primary" value="100" max="100"></progress>
|
||||||
|
|
||||||
|
<!--div id="temps">10</div-->
|
||||||
|
|
||||||
|
<div class="notification is-danger is-size-4 p-4" id="perdu">
|
||||||
|
<p>Perdu ! </p>
|
||||||
|
</div>
|
||||||
|
<div class="notification is-success is-size-4 p-4" id="gagne">
|
||||||
|
<p>Gagné ! </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
46
R4.01_R4.A.10/td_tp/tp2_bis/src/ex3/css/style.css
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
.slot{
|
||||||
|
width:52px;
|
||||||
|
height:52px;
|
||||||
|
padding:2px;
|
||||||
|
margin:11px;
|
||||||
|
border:1px solid #aaaaaa;
|
||||||
|
background-color:#ffffff;
|
||||||
|
display:inline-block;
|
||||||
|
vertical-align:middle;
|
||||||
|
}
|
||||||
|
.drag{
|
||||||
|
width:50px;
|
||||||
|
height:50px;
|
||||||
|
border:1px solid #aaaaaa;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
text-align:center;
|
||||||
|
font-size:25px;
|
||||||
|
line-height:52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ct{
|
||||||
|
height:100px;
|
||||||
|
margin:10px;
|
||||||
|
line-height:100px;
|
||||||
|
text-align:center;
|
||||||
|
|
||||||
|
}
|
||||||
|
.normal{
|
||||||
|
|
||||||
|
background-color:#1583CC;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.good{
|
||||||
|
background-color:#00867F;
|
||||||
|
|
||||||
|
}
|
||||||
|
.wrong{
|
||||||
|
|
||||||
|
background-color:#eeaaaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
[draggable=true] {
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
3
R4.01_R4.A.10/td_tp/tp2_bis/src/ex3/js/tri.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function getRandomInt(min, max) {
|
||||||
|
return Math.floor(Math.random() * (max - min)) + min
|
||||||
|
}
|
63
R4.01_R4.A.10/td_tp/tp2_bis/src/ex3/tri.html
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title></title>
|
||||||
|
<script src="./js/tri.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="./css/style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h3>Drag and Drop</h3>
|
||||||
|
|
||||||
|
<!-- Le tableau initial -->
|
||||||
|
|
||||||
|
<div class="ct normal" id="start">
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag1" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag2" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag3" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag4" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag5" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag6" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag7" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag8" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag9" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
<div class="slot">
|
||||||
|
<div id="drag10" class="drag" draggable="true"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Le tableau doit être trié ici -->
|
||||||
|
|
||||||
|
<div class="ct good" id="end">
|
||||||
|
<div class="slot"></div>
|
||||||
|
<div class="slot"></div>
|
||||||
|
<div class="slot"></div>
|
||||||
|
<div class="slot"></div>
|
||||||
|
<div class="slot"></div>
|
||||||
|
<div class="slot"></div>
|
||||||
|
<div class="slot"></div>
|
||||||
|
<div class="slot"></div>
|
||||||
|
<div class="slot"></div>
|
||||||
|
<div class="slot"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
36
R4.01_R4.A.10/td_tp/tp3/README.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# TP javascript : Ajax, promesses.
|
||||||
|
|
||||||
|
Vous disposez tous, à la racine de votre compte, d'un répertoire `public_html` qui est servi (http/https) par le serveur dwarves.
|
||||||
|
Pour accéder à vos pages, utilisez l'url :
|
||||||
|
|
||||||
|
> http(s)://dwarves.[arda|iut-fbleau.fr]/~login
|
||||||
|
|
||||||
|
Pour tester les différentes api http, vous pouvez utilisez la commande `curl`.
|
||||||
|
|
||||||
|
|
||||||
|
#### Ex1
|
||||||
|
Le but est de faire une recherche de film en utilisant l'api [OMDb](https://www.omdbapi.com/) (Open Movie Database).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Son utilisation nécessite une clé. Vous pouvez utiliser la mienne `2fcb2848`. Si
|
||||||
|
la limite de requêtes est atteinte, générez votre propre clé.
|
||||||
|
|
||||||
|
|
||||||
|
Complétez le [code](./src/ex1).
|
||||||
|
- J'ai volontairement utilisé des modules. Il vous faut donc tester l'application avec
|
||||||
|
http.
|
||||||
|
- Écrire la fonction du modèle
|
||||||
|
```js
|
||||||
|
getMovies(search)
|
||||||
|
```
|
||||||
|
Cette fonction renvoie une promesse qui permet de faire une requête ajax vers l'api OMDb. Pour ajax,
|
||||||
|
utilisez d'abord l'interface `fetch`, puis l'objet `XMLHttpRequest`.
|
||||||
|
|
||||||
|
- Ecrire la fonction du contrôleur
|
||||||
|
```js
|
||||||
|
async search(searchMovie)
|
||||||
|
```
|
||||||
|
qui permet de faire une recherche. Cette fonction utilise évidemment la fonction précédente `getMovies`.
|
||||||
|
|
||||||
|
|
35
R4.01_R4.A.10/td_tp/tp3/aide.md
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#### XMLHttpRequest
|
||||||
|
```js
|
||||||
|
let xhr = new XMLHttpRequest()
|
||||||
|
xhr.open("GET","mon/url")
|
||||||
|
|
||||||
|
xhr.onload = ...
|
||||||
|
xhr.onerror = ...
|
||||||
|
|
||||||
|
xhr.send()
|
||||||
|
```
|
||||||
|
#### Promise
|
||||||
|
```js
|
||||||
|
|
||||||
|
let promise = new Promise ((resolve,reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve("OK")
|
||||||
|
},1000)
|
||||||
|
})
|
||||||
|
promise.then(data => ....)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### async/await
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
function getUser(email){
|
||||||
|
return new Promise(...)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateUser(){
|
||||||
|
|
||||||
|
let user = await getUser(...)
|
||||||
|
console.log(user)
|
||||||
|
}
|
||||||
|
```
|
BIN
R4.01_R4.A.10/td_tp/tp3/img/foot.png
Normal file
After ![]() (image error) Size: 125 KiB |
BIN
R4.01_R4.A.10/td_tp/tp3/img/got.png
Normal file
After ![]() (image error) Size: 984 KiB |
BIN
R4.01_R4.A.10/td_tp/tp3/img/search.png
Normal file
After ![]() (image error) Size: 320 KiB |
87
R4.01_R4.A.10/td_tp/tp3/src/ex1/css/style.css
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
main {
|
||||||
|
position: absolute;
|
||||||
|
top: 2rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
}
|
||||||
|
.loader {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
.loader {
|
||||||
|
margin: 6rem 0 0;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
color: #FFFAAA;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
label span {
|
||||||
|
text-shadow: 1px 1px 2px rgba(0,0,0,0.8);
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
margin: 1rem 0 0;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
font-weight: 300;
|
||||||
|
padding: 0.8rem 1rem;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
transition: all 0.3s;
|
||||||
|
box-shadow: 1px 1px 2px rgba(0,0,0, 0.3);
|
||||||
|
-moz-appearance:none;
|
||||||
|
-webkit-appearance:none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
input:focus {
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
padding: 0;
|
||||||
|
margin: 1rem 0 2rem;
|
||||||
|
}
|
||||||
|
ul li {
|
||||||
|
padding: 0.6rem 1rem;
|
||||||
|
margin: 1px 0;
|
||||||
|
line-height: 1.4rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
align-content: space-between;
|
||||||
|
text-shadow: 1px 1px 2px rgba(0,0,0,0.8);
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
box-shadow: 0 0 2px rgba(0,0,0, 0.3);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
ul li:hover,
|
||||||
|
ul li:active,
|
||||||
|
ul li:focus {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
ul li a {
|
||||||
|
margin: 0 0.6rem 0 0;
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
ul li span {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'Helvetica Neue', Helvetica, Arial;
|
||||||
|
font-weight: 300;
|
||||||
|
background-size: cover;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-image: -webkit-radial-gradient(ellipse farthest-corner at top, #661141, #000000);
|
||||||
|
background-image: radial-gradient(ellipse farthest-corner at top, #661141, #000000);
|
||||||
|
color: white;
|
||||||
|
}
|
13
R4.01_R4.A.10/td_tp/tp3/src/ex1/img/puff.svg
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
|
||||||
|
<svg width="44" height="44" viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
|
||||||
|
<g fill="none" fill-rule="evenodd" stroke-width="2">
|
||||||
|
<circle cx="22" cy="22" r="1">
|
||||||
|
<animate attributeName="r" begin="0s" dur="1.8s" values="1; 20" calcMode="spline" keyTimes="0; 1" keySplines="0.165, 0.84, 0.44, 1" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="stroke-opacity" begin="0s" dur="1.8s" values="1; 0" calcMode="spline" keyTimes="0; 1" keySplines="0.3, 0.61, 0.355, 1" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="22" cy="22" r="1">
|
||||||
|
<animate attributeName="r" begin="-0.9s" dur="1.8s" values="1; 20" calcMode="spline" keyTimes="0; 1" keySplines="0.165, 0.84, 0.44, 1" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="stroke-opacity" begin="-0.9s" dur="1.8s" values="1; 0" calcMode="spline" keyTimes="0; 1" keySplines="0.3, 0.61, 0.355, 1" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After (image error) Size: 1.0 KiB |
28
R4.01_R4.A.10/td_tp/tp3/src/ex1/index.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="initial-scale=1,width=device-width">
|
||||||
|
<link rel="stylesheet" type="text/css" href="./css/style.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- vue html -->
|
||||||
|
<main>
|
||||||
|
<label>
|
||||||
|
<span>Search a movie</span>
|
||||||
|
<input type="input" placeholder="28 Days Later..">
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="loader">
|
||||||
|
<img src="./img/puff.svg">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="error"></p>
|
||||||
|
<div id="list-movies">
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<script type="module" src="./js/app.js"></script>
|
||||||
|
</html>
|
7
R4.01_R4.A.10/td_tp/tp3/src/ex1/js/app.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import model from './model.js'
|
||||||
|
import Controller from './controller.js'
|
||||||
|
import View from './view.js'
|
||||||
|
|
||||||
|
const view = new View()
|
||||||
|
const app = new Controller(view,model)
|
||||||
|
|
26
R4.01_R4.A.10/td_tp/tp3/src/ex1/js/controller.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
class Controller {
|
||||||
|
constructor(view,model){
|
||||||
|
this.view = view
|
||||||
|
this.model = model
|
||||||
|
|
||||||
|
this.loading = false
|
||||||
|
this.lastSearch = null
|
||||||
|
this.error = null
|
||||||
|
this.results = []
|
||||||
|
|
||||||
|
this.view.setLoading(false)
|
||||||
|
this.view.bindSearch(this.search.bind(this))
|
||||||
|
}
|
||||||
|
reset() {
|
||||||
|
this.loading = false
|
||||||
|
this.error = null
|
||||||
|
this.results = []
|
||||||
|
}
|
||||||
|
|
||||||
|
async search(searchMovie) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Controller
|
||||||
|
|
12
R4.01_R4.A.10/td_tp/tp3/src/ex1/js/helpers.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Returns a function, that, as long as it continues to be invoked, will not
|
||||||
|
// be triggered. The function will be called after it stops being called for
|
||||||
|
// N milliseconds.
|
||||||
|
function debounce(fn, wait) {
|
||||||
|
let timeout
|
||||||
|
|
||||||
|
return (...args) => {
|
||||||
|
clearTimeout(timeout)
|
||||||
|
timeout = setTimeout(() => fn(...args), wait)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default debounce
|
9
R4.01_R4.A.10/td_tp/tp3/src/ex1/js/model.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
let apiKey = '2fcb2848'
|
||||||
|
|
||||||
|
let model = {
|
||||||
|
getMovies(search){
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default model
|
54
R4.01_R4.A.10/td_tp/tp3/src/ex1/js/view.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import debounce from "./helpers.js"
|
||||||
|
|
||||||
|
class View {
|
||||||
|
constructor(){
|
||||||
|
this.listMovies = document.querySelector("#list-movies")
|
||||||
|
this.inputSearch = document.querySelector("input")
|
||||||
|
this.loader = document.querySelector(".loader")
|
||||||
|
this.message = document.querySelector("p.error")
|
||||||
|
}
|
||||||
|
|
||||||
|
_getInput(){
|
||||||
|
return this.inputSearch.value
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(loading){
|
||||||
|
if (loading)
|
||||||
|
this.loader.style.display = "block"
|
||||||
|
else
|
||||||
|
this.loader.style.display = "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMessage(error){
|
||||||
|
this.message.style.display = "block"
|
||||||
|
this.message.textContent = error
|
||||||
|
}
|
||||||
|
|
||||||
|
renderList(movies){
|
||||||
|
let ul = document.createElement("ul")
|
||||||
|
movies.forEach((movie)=>{
|
||||||
|
let li = document.createElement("li")
|
||||||
|
let a = document.createElement("a")
|
||||||
|
let span = document.createElement("span")
|
||||||
|
a.href = `http://www.imdb.com/title/${movie.imdbID}`
|
||||||
|
a.target="_blank"
|
||||||
|
a.textContent = movie.Title
|
||||||
|
span.textContent = movie.Year
|
||||||
|
|
||||||
|
|
||||||
|
li.appendChild(a)
|
||||||
|
li.appendChild(span)
|
||||||
|
ul.appendChild(li)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.listMovies.replaceChildren(ul)
|
||||||
|
}
|
||||||
|
|
||||||
|
bindSearch(handler){
|
||||||
|
this.inputSearch.addEventListener("input",debounce((e)=>{
|
||||||
|
handler(this._getInput())
|
||||||
|
},500))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default View
|