rinomina esercizi js
This commit is contained in:
109
javascript/08_DOM+/00_ripasso/index.html
Normal file
109
javascript/08_DOM+/00_ripasso/index.html
Normal file
@@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Ripasso DOM</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold; font-size: 14px;">← Dashboard</a>
|
||||
|
||||
<div class="container">
|
||||
<h1>🎓 Ripasso DOM - Step by Step</h1>
|
||||
<p class="subtitle">Selettori, Manipolazione Testo, Eventi</p>
|
||||
|
||||
<!-- ============ STEP 1: SELETTORI ============ -->
|
||||
<div class="step">
|
||||
<h2>Step 1️⃣ - Selettori CSS</h2>
|
||||
<p class="step-description">Impara a selezionare elementi dal DOM usando querySelector</p>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 1.1: Seleziona per ID</h3>
|
||||
<p id="messaggio-id">Questo elemento ha un ID</p>
|
||||
<p class="risultato" id="risultato-1-1">Aspettando...</p>
|
||||
</div>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 1.2: Seleziona per Classe</h3>
|
||||
<p class="testo-blu">Sono blu</p>
|
||||
<p class="testo-blu">Anche io sono blu</p>
|
||||
<p class="risultato" id="risultato-1-2">Aspettando...</p>
|
||||
</div>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 1.3: Seleziona per Tag</h3>
|
||||
<span>Sono uno span</span>
|
||||
<span>Sono un altro span</span>
|
||||
<p class="risultato" id="risultato-1-3">Aspettando...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============ STEP 2: MANIPOLAZIONE TESTO ============ -->
|
||||
<div class="step">
|
||||
<h2>Step 2️⃣ - Manipolazione Testo</h2>
|
||||
<p class="step-description">Cambia il contenuto dei tag usando textContent</p>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 2.1: Cambia Testo in un Paragrafo</h3>
|
||||
<p id="paragrafo-da-cambiare">Clicca il bottone qui sotto per cambiarmi!</p>
|
||||
<button id="btn-cambiaP">Cambia Testo</button>
|
||||
<p class="risultato" id="risultato-2-1">Aspettando...</p>
|
||||
</div>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 2.2: Scrivi nel DOM</h3>
|
||||
<div id="area-scrittura" class="area-output"></div>
|
||||
<button id="btn-scrivi">Scrivi nel DOM</button>
|
||||
<p class="risultato" id="risultato-2-2">Aspettando...</p>
|
||||
</div>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 2.3: Testo Dinamico</h3>
|
||||
<input type="text" id="input-nome" placeholder="Scrivi il tuo nome">
|
||||
<button id="btn-saluta">Saluta</button>
|
||||
<p id="area-saluto" class="area-output"></p>
|
||||
<p class="risultato" id="risultato-2-3">Aspettando...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============ STEP 3: EVENTI ============ -->
|
||||
<div class="step">
|
||||
<h2>Step 3️⃣ - Eventi</h2>
|
||||
<p class="step-description">Rispondi ai click dell'utente e agli input</p>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 3.1: Click Semplice</h3>
|
||||
<button id="btn-click">Cliccami!</button>
|
||||
<p id="contatore-click" class="area-output">Click: 0</p>
|
||||
<p class="risultato" id="risultato-3-1">Aspettando...</p>
|
||||
</div>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 3.2: Input Event</h3>
|
||||
<p>Scrivi qualcosa e vedi il risultato in tempo reale:</p>
|
||||
<input type="text" id="input-tempo-reale" placeholder="Digita qui...">
|
||||
<p id="echo" class="area-output">Qui apparirà quello che scrivi...</p>
|
||||
<p class="risultato" id="risultato-3-2">Aspettando...</p>
|
||||
</div>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 3.3: Click su Elemento Specifico</h3>
|
||||
<div class="box-click" id="box1">Box 1</div>
|
||||
<div class="box-click" id="box2">Box 2</div>
|
||||
<div class="box-click" id="box3">Box 3</div>
|
||||
<p id="log-click" class="area-output">Log click:</p>
|
||||
<p class="risultato" id="risultato-3-3">Aspettando...</p>
|
||||
</div>
|
||||
|
||||
<div class="exercise">
|
||||
<h3>Esercizio 3.4: Toggle Classe CSS (Bonus)</h3>
|
||||
<p id="elemento-toggle" class="elemento-normale">Clicca su di me per cambiarmi</p>
|
||||
<p class="risultato" id="risultato-3-4">Aspettando...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
263
javascript/08_DOM+/00_ripasso/script.js
Normal file
263
javascript/08_DOM+/00_ripasso/script.js
Normal file
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* ============================================================
|
||||
* RIPASSO DOM - STEP BY STEP
|
||||
* ============================================================
|
||||
* Questo file contiene esercizi di base sul DOM.
|
||||
* Ogni esercizio ha una soluzione che modifica l'HTML
|
||||
* e mostra il risultato visibile immediatamente.
|
||||
*/
|
||||
|
||||
|
||||
// ============ STEP 1: SELETTORI ============
|
||||
|
||||
/**
|
||||
* ESERCIZIO 1.1: Selettori per ID
|
||||
* Passi:
|
||||
* 1. Seleziona l'elemento con id="messaggio-id" usando document.querySelector('#messaggio-id')
|
||||
* 2. Scrivi il risultato in console per verificare
|
||||
* 3. Aggiorna il paragrafo con id="risultato-1-1" scrivendo "✅ Elemento selezionato: " + il testo dell'elemento
|
||||
*/
|
||||
function esercizio_1_1() {
|
||||
const elemento = document.querySelector('');
|
||||
|
||||
if (elemento) {
|
||||
const risultato = document.querySelector('#risultato-1-1');
|
||||
risultato.textContent = '✅ Elemento selezionato: ' + elemento.textContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ESERCIZIO 1.2: Selettori per Classe
|
||||
* Passi:
|
||||
* 1. Seleziona il PRIMO elemento con classe "testo-blu" usando document.querySelector
|
||||
*/
|
||||
function esercizio_1_2() {
|
||||
const elemento = document.querySelector('');
|
||||
|
||||
if (elemento) {
|
||||
const risultato = document.querySelector('#risultato-1-2');
|
||||
risultato.textContent = '✅ Prima classe trovata: ' + elemento.textContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ESERCIZIO 1.3: Selettori per Tag
|
||||
* Passi:
|
||||
* 1. Seleziona il PRIMO elemento <span> usando document.querySelector
|
||||
*/
|
||||
function esercizio_1_3() {
|
||||
const elemento = document.querySelector('');
|
||||
|
||||
if (elemento) {
|
||||
const risultato = document.querySelector('#risultato-1-3');
|
||||
risultato.textContent = '✅ Span trovato: ' + elemento.textContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Eseguire gli esercizi 1.x
|
||||
esercizio_1_1();
|
||||
esercizio_1_2();
|
||||
esercizio_1_3();
|
||||
|
||||
|
||||
// ============ STEP 2: MANIPOLAZIONE TESTO ============
|
||||
|
||||
/**
|
||||
* ESERCIZIO 2.1: Cambia il testo in un paragrafo
|
||||
* Passi:
|
||||
* 1. Seleziona il bottone con id="btn-cambiaP"
|
||||
* 2. Seleziona il paragrafo con id="paragrafo-da-cambiare"
|
||||
* 3. Aggiungi un event listener al bottone che, al click:
|
||||
* - Cambia il textContent del paragrafo a "Ho cambiato! ✨"
|
||||
*/
|
||||
function esercizio_2_1() {
|
||||
const btn = document.querySelector('');
|
||||
const paragrafo = document.querySelector('');
|
||||
|
||||
if (btn && paragrafo) {
|
||||
btn.addEventListener('click', () => {
|
||||
paragrafo.textContent
|
||||
});
|
||||
|
||||
const risultato = document.querySelector('#risultato-2-1');
|
||||
risultato.textContent = "✅ Testo cambato"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ESERCIZIO 2.2: Scrivi nel DOM
|
||||
* Passi:
|
||||
* 1. Seleziona il bottone con id="btn-scrivi"
|
||||
* 2. Seleziona il div con id="area-scrittura"
|
||||
* 3. Aggiungi un event listener che, al click:
|
||||
* - Aggiungi un nuovo <p> con il testo "Riga aggiunta al DOM!"
|
||||
* - Usa append() per aggiungere il paragrafo al div
|
||||
*/
|
||||
function esercizio_2_2() {
|
||||
const btn = document.querySelector('');
|
||||
const area = document.querySelector('');
|
||||
|
||||
if (btn && area) {
|
||||
btn.addEventListener('click', () => {
|
||||
const nuovoParagrafo = document.createElement('');
|
||||
nuovoParagrafo.textContent
|
||||
});
|
||||
|
||||
const risultato = document.querySelector('#risultato-2-2');
|
||||
risultato.textContent = "✅ Elemento aggiunto"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ESERCIZIO 2.3: Testo Dinamico da Input
|
||||
* Passi:
|
||||
* 1. Seleziona l'input con id="input-nome"
|
||||
* 2. Seleziona il bottone con id="btn-saluta"
|
||||
* 3. Seleziona il div con id="area-saluto"
|
||||
* 4. Aggiungi un event listener al bottone che:
|
||||
* - Leggi il valore dell'input (input.value)
|
||||
* - Scrivi nel area-saluto: "Ciao [NOME]! 👋"
|
||||
*/
|
||||
function esercizio_2_3() {
|
||||
const input = document.querySelector('');
|
||||
const btn = document.querySelector('');
|
||||
const area = document.querySelector('');
|
||||
|
||||
if (input && btn && area) {
|
||||
btn.addEventListener('click', () => {
|
||||
const nome = '';
|
||||
area.textContent
|
||||
});
|
||||
|
||||
const risultato = document.querySelector('#risultato-2-3');
|
||||
risultato.textContent = "✅ Saluto inviato"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Eseguire gli esercizi 2.x
|
||||
esercizio_2_1();
|
||||
esercizio_2_2();
|
||||
esercizio_2_3();
|
||||
|
||||
|
||||
// ============ STEP 3: EVENTI ============
|
||||
|
||||
/**
|
||||
* ESERCIZIO 3.1: Click Semplice - Contatore
|
||||
* Passi:
|
||||
* 1. Seleziona il bottone con id="btn-click"
|
||||
* 2. Seleziona l'elemento con id="contatore-click"
|
||||
* 3. Aggiungi un event listener che, al click:
|
||||
* - Incrementa count (count++)
|
||||
* - Aggiorna il testo mostrando "Click: " + count
|
||||
*/
|
||||
let count = 0; // NOTA: Variabile globale
|
||||
|
||||
function esercizio_3_1() {
|
||||
const btn = document.querySelector('');
|
||||
const contatore = document.querySelector('');
|
||||
|
||||
if (btn && contatore) {
|
||||
btn.addEventListener('click', () => {
|
||||
|
||||
});
|
||||
const risultato = document.querySelector('#risultato-3-1');
|
||||
risultato.textContent = "✅ Contatore attivo";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ESERCIZIO 3.2: Input Event - Echo Tempo Reale
|
||||
* Passi:
|
||||
* 1. Seleziona l'input con id="input-tempo-reale"
|
||||
* 2. Seleziona il paragrafo con id="echo"
|
||||
* 3. Aggiungi un event listener su 'input' (NON click!) che:
|
||||
* - Leggi il valore dell'input (event.target.value o input.value)
|
||||
* - Scrivi nel echo lo stesso testo in tempo reale
|
||||
* - Se input vuoto, mostra "Scrivi qualcosa..."
|
||||
*
|
||||
* Nota: 'input' è l'evento che si scatta mentre l'utente digita
|
||||
* 'click' è l'evento che si scatta quando l'utente clicca
|
||||
* 'change' è l'evento che si scatta quando l'utente finisce di modificare
|
||||
*/
|
||||
function esercizio_3_2() {
|
||||
const input = document.querySelector('');
|
||||
const echo = document.querySelector('');
|
||||
|
||||
if (input && echo) {
|
||||
input.addEventListener('input', (event) => {
|
||||
|
||||
});
|
||||
|
||||
const risultato = document.querySelector('#risultato-3-2');
|
||||
risultato.textContent = "✅ Echo attivo";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ESERCIZIO 3.3: Click su Elementi Specifici
|
||||
* Passi:
|
||||
* 1. Seleziona tutti gli elementi con classe "box-click" usando querySelectorAll
|
||||
* 2. Seleziona il paragrafo con id="log-click"
|
||||
* 3. Per ogni box, aggiungi un event listener al click che:
|
||||
* - Leggi l'id del box (event.target.id)
|
||||
* - Crea un nuovo elemento <p>
|
||||
* - Imposta il testo del paragrafo a "[id del box] cliccato"
|
||||
* - Aggiungi il paragrafo al log usando append()
|
||||
*
|
||||
* Nota: Devi usare un loop (for o forEach) per aggiungere il listener a tutti i box
|
||||
*/
|
||||
function esercizio_3_3() {
|
||||
const boxes = document.querySelectorAll('');
|
||||
const log = document.querySelector('');
|
||||
|
||||
if (boxes.length > 0) {
|
||||
boxes.forEach((box) => {
|
||||
box.addEventListener('click', (event) => {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
const risultato = document.querySelector('#risultato-3-3');
|
||||
risultato.textContent = "✅ Log attivo";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ESERCIZIO 3.4 (BONUS): Toggle Classe CSS
|
||||
* Passi:
|
||||
* 1. Seleziona l'elemento con id="elemento-toggle"
|
||||
* 2. Aggiungi un event listener al click che:
|
||||
* - Usa classList.toggle('elemento-attivo') per aggiungere/rimuovere la classe
|
||||
*
|
||||
* Nota: Assicurati che in style.css esista una classe .elemento-attivo
|
||||
*/
|
||||
function esercizio_3_4() {
|
||||
const elemento = document.querySelector('');
|
||||
|
||||
if (elemento) {
|
||||
elemento.addEventListener('click', () => {
|
||||
|
||||
});
|
||||
|
||||
const risultato = document.querySelector('#risultato-3-4');
|
||||
risultato.textContent = "✅ Toggle attivo";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Eseguire gli esercizi 3.x
|
||||
esercizio_3_1();
|
||||
esercizio_3_2();
|
||||
esercizio_3_3();
|
||||
esercizio_3_4();
|
||||
232
javascript/08_DOM+/00_ripasso/style.css
Normal file
232
javascript/08_DOM+/00_ripasso/style.css
Normal file
@@ -0,0 +1,232 @@
|
||||
/* ============================================================
|
||||
RIPASSO DOM - STILI
|
||||
============================================================ */
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Stesso font dashboard */
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); /* Stesso sfondo dashboard */
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: white;
|
||||
width: 100%;
|
||||
max-width: 650px;
|
||||
margin: 0 auto;
|
||||
padding: 30px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #34495e;
|
||||
margin: 0 0 10px 0;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: center;
|
||||
color: #7f8c8d;
|
||||
font-size: 1rem;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
/* ============ STEP ============ */
|
||||
|
||||
.step {
|
||||
margin-bottom: 30px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.step:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.step h2 {
|
||||
color: #2980b9;
|
||||
margin-top: 0;
|
||||
margin-bottom: 5px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.step-description {
|
||||
color: #7f8c8d;
|
||||
margin-bottom: 15px;
|
||||
font-size: 0.95rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* ============ EXERCISE ============ */
|
||||
|
||||
.exercise {
|
||||
background: white;
|
||||
margin-bottom: 15px;
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-radius: 6px;
|
||||
transition: box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.exercise:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.exercise:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.exercise h3 {
|
||||
color: #2c3e50;
|
||||
margin: 15px 0 10px 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.exercise p {
|
||||
margin: 5px 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.testo-blu {
|
||||
color: #3498db;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
/* ============ INPUT & BUTTON ============ */
|
||||
|
||||
input[type="text"],
|
||||
input[type="number"],
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
margin: 8px 0;
|
||||
border: 1px solid #bdc3c7;
|
||||
border-radius: 5px;
|
||||
font-size: 0.95rem;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="number"]:focus,
|
||||
textarea:focus {
|
||||
outline: none;
|
||||
border-color: #3498db;
|
||||
box-shadow: 0 0 5px rgba(52, 152, 219, 0.2);
|
||||
}
|
||||
|
||||
button {
|
||||
background: #3498db;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
margin: 8px 5px 8px 0;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 0.9rem;
|
||||
box-shadow: 0 2px 6px rgba(52, 152, 219, 0.2);
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #2980b9;
|
||||
box-shadow: 0 4px 12px rgba(52, 152, 219, 0.3);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
button:active {
|
||||
border-radius: 5px;
|
||||
color: #2c3e50;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
/* ============ RISULTATO & AREA OUTPUT ============ */
|
||||
|
||||
.risultato {
|
||||
background: #f8fafb;
|
||||
border: 1px solid #d5d8dc;
|
||||
padding: 8px;
|
||||
border-radius: 5px;
|
||||
margin-top: 8px;
|
||||
color: #34495e;
|
||||
font-size: 0.85rem;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
.area-output {
|
||||
background: #f8fafb;
|
||||
border: 1px solid #d5d8dc;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
margin-top: 8px;
|
||||
color: #34495e;
|
||||
font-size: 0.9rem;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.03);
|
||||
min-height: 20px;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
/* ============ BOX CLICK ============ */
|
||||
|
||||
.box-click {
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
background: #f0f3f4;
|
||||
color: #2c3e50;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
font-weight: bold;
|
||||
font-size: 0.9rem;
|
||||
border: 1px solid #d5d8dc;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.box-click:hover {
|
||||
background: #e8ecef;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.box-click:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* ============ ELEMENTO TOGGLE ============ */
|
||||
|
||||
.elemento-normale {
|
||||
padding: 15px;
|
||||
border: 2px solid #3498db;
|
||||
border-radius: 8px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.elemento-normale:hover {
|
||||
background: #ecf0f1;
|
||||
box-shadow: 0 2px 8px rgba(52, 152, 219, 0.2);
|
||||
}
|
||||
|
||||
.elemento-attivo {
|
||||
background: #3498db;
|
||||
color: white;
|
||||
border-color: #2980b9;
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 4px 12px rgba(52, 152, 219, 0.4);
|
||||
}
|
||||
48
javascript/08_DOM+/01_profilo/index.html
Normal file
48
javascript/08_DOM+/01_profilo/index.html
Normal file
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Profilo Utente</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold; font-size: 14px;">← Dashboard</a>
|
||||
<div class="card-container">
|
||||
<div class="card-header">
|
||||
<img id="img-profilo" src="https://placehold.co/150" alt="Foto Profilo">
|
||||
|
||||
<h2 id="nome-completo">Nome Cognome</h2>
|
||||
|
||||
<p id="ruolo" class="ruolo-badge">Ruolo</p>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dettaglio">
|
||||
<strong>Email:</strong>
|
||||
<span id="email">...</span>
|
||||
</div>
|
||||
|
||||
<div class="dettaglio">
|
||||
<strong>Telefono:</strong>
|
||||
<span id="telefono">...</span>
|
||||
</div>
|
||||
|
||||
<div class="dettaglio">
|
||||
<strong>Indirizzo:</strong>
|
||||
<span id="indirizzo">...</span>
|
||||
</div>
|
||||
|
||||
<div id="box-verifica" class="verifica nascosto">
|
||||
✅ Utente Verificato
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<button id="btn-stampa">Stampa Profilo</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
53
javascript/08_DOM+/01_profilo/script.js
Normal file
53
javascript/08_DOM+/01_profilo/script.js
Normal file
@@ -0,0 +1,53 @@
|
||||
// DATI (Oggetto Singolo)
|
||||
// Immagina che questi dati arrivino da un server o da un database.
|
||||
const utente = {
|
||||
nome: "Giulia",
|
||||
cognome: "Verdi",
|
||||
eta: 30,
|
||||
email: "giulia.verdi@example.com",
|
||||
telefono: "+39 333 1234567",
|
||||
indirizzo: "Via Roma 10, Milano",
|
||||
professione: "Graphic Designer",
|
||||
fotoUrl: "https://randomuser.me/api/portraits/women/44.jpg", // Url di una foto vera
|
||||
verificato: true // Prova a mettere false per vedere cosa succede
|
||||
};
|
||||
|
||||
|
||||
// 1. SELEZIONE ELEMENTI DOM
|
||||
// Esercizio: Completa i querySelector abbinando gli ID corretti presi dall'HTML
|
||||
const elNomeCompleto = document.querySelector(''); // es. #nome-completo
|
||||
const elRuolo = document.querySelector('');
|
||||
const elEmail = document.querySelector('');
|
||||
const elTelefono = document.querySelector('');
|
||||
const elIndirizzo = document.querySelector('');
|
||||
const elImmagine = document.querySelector('');
|
||||
const boxVerifica = document.querySelector('');
|
||||
|
||||
|
||||
/**
|
||||
* 2. RIEMPIMENTO DATI
|
||||
* Ora devi prendere i dati dall'oggetto 'utente' e metterli dentro gli elementi HTML.
|
||||
*/
|
||||
|
||||
// A. Testo Semplice (textContent)
|
||||
// elNomeCompleto.textContent = ...
|
||||
// ...
|
||||
|
||||
// B. Attributi (src)
|
||||
// elImmagine.src = ...
|
||||
// ...
|
||||
|
||||
|
||||
// C. Logica Condizionale
|
||||
// Se l'utente è "verificato" (true), mostriamo il box verde.
|
||||
// Altrimenti lo lasciamo nascosto (o lo nascondiamo esplicitamente).
|
||||
|
||||
|
||||
/**
|
||||
* 3. EVENTI
|
||||
* Fai funzionare il bottone "Stampa Profilo"
|
||||
* Quando cliccato, deve lanciare un alert() con scritto: "Sto stampando il profilo di [NOME]"
|
||||
* Alert permette di mostrare un messaggio all'utente e bloccare l'esecuzione finché non preme "OK".
|
||||
* Il suo utilizzo è semplice: alert("Messaggio da mostrare");
|
||||
*/
|
||||
const btnStampa = document.querySelector('#btn-stampa');
|
||||
105
javascript/08_DOM+/01_profilo/style.css
Normal file
105
javascript/08_DOM+/01_profilo/style.css
Normal file
@@ -0,0 +1,105 @@
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Stesso font dashboard */
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); /* Stesso sfondo dashboard */
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.card-container {
|
||||
background: white;
|
||||
width: 320px;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 15px 35px rgba(0,0,0,0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 30px 20px;
|
||||
}
|
||||
|
||||
#img-profilo {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%; /* Cerchio perfetto */
|
||||
border: 4px solid white;
|
||||
object-fit: cover;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 10px 0 5px 0;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.ruolo-badge {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
display: inline-block;
|
||||
padding: 5px 15px;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dettaglio {
|
||||
margin-bottom: 15px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 5px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: #333;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.verifica {
|
||||
text-align: center;
|
||||
color: #27ae60;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
background-color: #e8f8f5;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.nascosto {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
button {
|
||||
background: linear-gradient(to right, #667eea, #764ba2); /* Riprende l'header */
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 25px;
|
||||
border-radius: 30px; /* Bottone a pillola moderno */
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 4px 15px rgba(118, 75, 162, 0.4);
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 6px 20px rgba(118, 75, 162, 0.6);
|
||||
}
|
||||
50
javascript/08_DOM+/02_tabella_utenti/index.html
Normal file
50
javascript/08_DOM+/02_tabella_utenti/index.html
Normal file
@@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Gestione Utenti</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold; font-size: 14px;">← Dashboard</a>
|
||||
|
||||
<div class="container">
|
||||
<form id="profile-form" class="profile-form">
|
||||
<h1>Aggiungi un Utente</h1>
|
||||
<div class="form-group">
|
||||
<label for="nome">Nome Completo:</label>
|
||||
<input type="text" id="nome" placeholder="Es. Marco Rossi" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="eta">Età:</label>
|
||||
<input type="number" id="eta" placeholder="Es. 25" min="1" max="120" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="professione">Professione:</label>
|
||||
<input type="text" id="professione" placeholder="Es. Sviluppatore" required>
|
||||
</div>
|
||||
<button type="button" id="btn-crea-card" class="btn-primary">+ Aggiungi Utente</button>
|
||||
</form>
|
||||
|
||||
<div class="table-wrapper">
|
||||
<h2>Utenti Registrati</h2>
|
||||
<table id="users-table" class="users-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nome</th>
|
||||
<th>Età</th>
|
||||
<th>Professione</th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody">
|
||||
<!-- Le righe verranno inserite qui -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
58
javascript/08_DOM+/02_tabella_utenti/script.js
Normal file
58
javascript/08_DOM+/02_tabella_utenti/script.js
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* ESERCIZIO 2: Tabella Utenti Interattiva
|
||||
* Selezionare gli elementi principali dal DOM
|
||||
*/
|
||||
const inputNome = document.querySelector('');
|
||||
const inputEta = document.querySelector('');
|
||||
const inputProfessione = document.querySelector('');
|
||||
const btnCreaUtente = document.querySelector('');
|
||||
const tbodyUtenti = document.querySelector('');
|
||||
|
||||
/**
|
||||
* EVENTO: Clic sul pulsante "Aggiungi Utente"
|
||||
*
|
||||
* Completa la funzione: Manca qualcosa?
|
||||
*
|
||||
* Passi:
|
||||
* 1. Prevenire il comportamento di default del form
|
||||
* 2. Leggere i valori dagli input
|
||||
* 3. Se i dati non sono vuoti:
|
||||
* - Chiamare creaRigaUtente(nome, eta, professione), passando i dati letti dagli input
|
||||
* - Chiamare cancellaDatiInput() per pulire i campi
|
||||
*/
|
||||
|
||||
btnCreaUtente.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const nome = inputNome.value;
|
||||
const eta = inputEta.value;
|
||||
const professione = inputProfessione.value;
|
||||
|
||||
creaRigaUtente(nome, eta, professione);
|
||||
cancellaDatiInput();
|
||||
});
|
||||
|
||||
/**
|
||||
* FUNZIONE: Crea una riga della tabella con i dati dell'utente
|
||||
*
|
||||
* Passi:
|
||||
* 1. Creare un elemento <tr> (classe "user-row")
|
||||
* 2. Creare tre elementi <td> per nome, età e professione
|
||||
* 3. Popolare i <td> con i dati passati dai parametri
|
||||
* 4. Aggiungere tutti i <td> al <tr>
|
||||
* 5. Aggiungere il <tr> nel <tbody> della tabella
|
||||
*/
|
||||
function creaRigaUtente(nome, eta, professione) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FUNZIONE: Cancella i dati dagli input e rimette il focus sul primo campo
|
||||
*
|
||||
* Passi:
|
||||
* 1. Impostare il valore di inputNome a stringa vuota
|
||||
* 2. Impostare il valore di inputEta a stringa vuota
|
||||
* 3. Impostare il valore di inputProfessione a stringa vuota
|
||||
*/
|
||||
function cancellaDatiInput() {
|
||||
}
|
||||
223
javascript/08_DOM+/02_tabella_utenti/style.css
Normal file
223
javascript/08_DOM+/02_tabella_utenti/style.css
Normal file
@@ -0,0 +1,223 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════ */
|
||||
/* FORM STYLES */
|
||||
/* ═══════════════════════════════════════════════════════════════ */
|
||||
|
||||
.profile-form {
|
||||
margin-bottom: 40px;
|
||||
padding-bottom: 30px;
|
||||
border-bottom: 2px solid #ecf0f1;
|
||||
}
|
||||
|
||||
.profile-form h1 {
|
||||
color: #2c3e50;
|
||||
margin-top: 0;
|
||||
margin-bottom: 25px;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 18px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
color: #34495e;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-group input,
|
||||
.form-group textarea {
|
||||
padding: 12px 15px;
|
||||
border: 2px solid #ecf0f1;
|
||||
border-radius: 6px;
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.form-group input:focus,
|
||||
.form-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: #3498db;
|
||||
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
|
||||
}
|
||||
|
||||
.form-group textarea {
|
||||
resize: vertical;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 14px 32px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
align-self: flex-start;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
.btn-primary:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════ */
|
||||
/* TABLE STYLES */
|
||||
/* ═══════════════════════════════════════════════════════════════ */
|
||||
|
||||
.table-wrapper h2 {
|
||||
color: #2c3e50;
|
||||
margin: 0 0 20px 0;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.empty-message {
|
||||
text-align: center;
|
||||
color: #7f8c8d;
|
||||
font-style: italic;
|
||||
padding: 30px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
border-left: 4px solid #3498db;
|
||||
}
|
||||
|
||||
.empty-message.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.users-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.users-table thead {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.users-table thead th {
|
||||
padding: 16px;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.users-table tbody tr {
|
||||
border-bottom: 1px solid #ecf0f1;
|
||||
transition: background-color 0.2s ease, transform 0.2s ease;
|
||||
animation: slideIn 0.3s ease-out;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.users-table tbody tr:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.users-table tbody td {
|
||||
padding: 16px;
|
||||
color: #34495e;
|
||||
word-break: break-word;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.users-table tbody td:first-child {
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.users-table tbody td.azioni {
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════ */
|
||||
/* BUTTON STYLES */
|
||||
/* ═══════════════════════════════════════════════════════════════ */
|
||||
|
||||
.btn-elimina {
|
||||
background: #e74c3c;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 14px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
transition: background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-elimina:hover {
|
||||
background: #c0392b;
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 4px 12px rgba(231, 76, 60, 0.3);
|
||||
}
|
||||
|
||||
.btn-elimina:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════ */
|
||||
/* RESPONSIVE */
|
||||
/* ═══════════════════════════════════════════════════════════════ */
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.users-table tbody th,
|
||||
.users-table tbody td {
|
||||
padding: 12px 8px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.profile-form {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
37
javascript/08_DOM+/03_lista_semplice/index.html
Normal file
37
javascript/08_DOM+/03_lista_semplice/index.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lista Semplice</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold; font-size: 14px;">← Dashboard</a>
|
||||
|
||||
<div class="container">
|
||||
<h1>Lista Semplice</h1>
|
||||
<p class="subtitle">Crea liste dinamicamente usando cicli e DOM</p>
|
||||
|
||||
<div class="esercizio">
|
||||
<h2>Frutti</h2>
|
||||
<ul id="lista-frutti" class="lista-items">
|
||||
<!-- Gli elementi della lista saranno creati via JavaScript -->
|
||||
</ul>
|
||||
</div>
|
||||
<div class="esercizio">
|
||||
<h2>Libri</h2>
|
||||
<ul id="lista-libri" class="lista-items">
|
||||
<!-- Gli elementi della lista saranno creati via JavaScript -->
|
||||
</ul>
|
||||
</div>
|
||||
<div class="esercizio">
|
||||
<h2>Cose da Fare</h2>
|
||||
<ul id="lista-todo" class="lista-items">
|
||||
<!-- Gli elementi della lista saranno creati via JavaScript -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
62
javascript/08_DOM+/03_lista_semplice/script.js
Normal file
62
javascript/08_DOM+/03_lista_semplice/script.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* ESERCIZIO 1: Popola Lista di Frutti
|
||||
* Questa funzione si occupa di creare gli elementi della lista
|
||||
* seguendo questi passi:
|
||||
* 1. Cicla l'array 'frutti'
|
||||
* 2. Per ogni frutto, crea un elemento <li>
|
||||
* 3. Imposta il textContent dell'li al nome del frutto
|
||||
* 4. Aggiungi l'li alla lista nel DOM
|
||||
*/
|
||||
const frutti = ['🍎 Mela', '🍌 Banana', '🍊 Arancia', '🍐 Pera', '🍇 Uva', '🥝 Kiwi'];
|
||||
function popolaFrutti() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ESERCIZIO 2: Popola Lista di Libri
|
||||
* Questa funzione si occupa di creare gli elementi della lista
|
||||
* seguendo questi passi:
|
||||
* 1. Cicla l'array 'libri'
|
||||
* 2. Per ogni libro, crea un elemento <li>
|
||||
* 3. Imposta il textContent dell'li a: "TITOLO - di AUTORE"
|
||||
* 4. Aggiungi l'li alla lista nel DOM
|
||||
*/
|
||||
const libri = [
|
||||
{ titolo: 'Il Signore degli Anelli', autore: 'J.R.R. Tolkien' },
|
||||
{ titolo: '1984', autore: 'George Orwell' },
|
||||
{ titolo: 'Il Grande Gatsby', autore: 'F. Scott Fitzgerald' },
|
||||
{ titolo: 'Harry Potter e la Pietra Filosofale', autore: 'J.K. Rowling' }
|
||||
];
|
||||
function popolaLibri() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ESERCIZIO 3: Lista di cose da fare (TODO)
|
||||
* Questa funzione si occupa di creare gli elementi della lista
|
||||
* seguendo questi passi:
|
||||
* 1. Cicla l'array 'todo'
|
||||
* 2. Per ogni attività, crea un elemento <li>
|
||||
* 3. Imposta il textContent dell'li al testo dell'attività
|
||||
* 4. Se l'attività è completata (completato: true), aggiungi la classe 'completato' all'li
|
||||
* 5. Aggiungi un evento click che:
|
||||
* - Modifica la proprietà 'completato' dell'oggetto invertendo il suo valore (true/false)
|
||||
* - Fai il toggle della classe 'completato' sull'elemento <li> per riflettere lo stato di completamento
|
||||
* 6. Aggiungi l'li alla lista nel DOM
|
||||
*/
|
||||
const todo = [
|
||||
{ testo: 'Studiare JavaScript', completato: true },
|
||||
{ testo: 'Fare esercizi sul DOM', completato: false },
|
||||
{ testo: 'Creare un progetto', completato: false },
|
||||
{ testo: 'Rivedere il codice', completato: false }
|
||||
];
|
||||
function popolaTodo() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// NON MODIFICARE: Chiamate iniziali
|
||||
popolaFrutti();
|
||||
popolaLibri();
|
||||
popolaTodo();
|
||||
76
javascript/08_DOM+/03_lista_semplice/style.css
Normal file
76
javascript/08_DOM+/03_lista_semplice/style.css
Normal file
@@ -0,0 +1,76 @@
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Stesso font dashboard */
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); /* Stesso sfondo dashboard */
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: white;
|
||||
width: 450px;
|
||||
padding: 30px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #34495e;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: center;
|
||||
color: #7f8c8d;
|
||||
font-size: 1rem;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.esercizio {
|
||||
margin-bottom: 25px;
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
.esercizio:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.esercizio h2 {
|
||||
color: #2980b9;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding-left: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 8px;
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
margin-right: 10px;
|
||||
background: #ecf0f1;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #b2b2b2;
|
||||
}
|
||||
|
||||
li:hover {
|
||||
background: #e0e0e0;
|
||||
cursor: pointer;
|
||||
transform: scale(1.05);
|
||||
transition: all 0.05s ease-in-out;
|
||||
}
|
||||
|
||||
.completato {
|
||||
text-decoration: line-through;
|
||||
color: #95a5a6;
|
||||
}
|
||||
29
javascript/08_DOM+/04_lista_spesa/index.html
Normal file
29
javascript/08_DOM+/04_lista_spesa/index.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lista della Spesa</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold; font-size: 14px;">← Dashboard</a>
|
||||
<div class="container">
|
||||
<h1>🛒 Lista della Spesa</h1>
|
||||
|
||||
<div class="input-group">
|
||||
</div>
|
||||
|
||||
<div class="totale-container">
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<ul id="lista-spesa">
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
86
javascript/08_DOM+/04_lista_spesa/script.js
Normal file
86
javascript/08_DOM+/04_lista_spesa/script.js
Normal file
@@ -0,0 +1,86 @@
|
||||
// DATI INIZIALI
|
||||
// Questa lista funge da "Database" locale. Tutto ciò che vedi a schermo DEVE derivare da qui.
|
||||
// Inizialmente contiene due prodotti di esempio (rimuovete se volete)
|
||||
let lista = [
|
||||
{ prodotto: 'Pane', prezzo: 1.50, sbarrato: false },
|
||||
{ prodotto: 'Latte', prezzo: 1.20, sbarrato: false },
|
||||
{ prodotto: 'Uova', prezzo: 2.30, sbarrato: false },
|
||||
{ prodotto: 'Mele', prezzo: 0.80, sbarrato: true },
|
||||
{ prodotto: 'Caffè', prezzo: 3.50, sbarrato: false }
|
||||
];
|
||||
|
||||
// ESERCIZIO: Assicurati di avere questi elementi nel tuo HTML
|
||||
// poi selezionali qui con querySelector.
|
||||
// Gli ID potranno essere a tua scelta, ma devono essere univoci e chiari.
|
||||
// Se l'elemento non esiste nell'HTML, aggiungilo tu. Es. <input id="prodotto" type="text">
|
||||
const inputProdotto = document.querySelector('');
|
||||
const inputPrezzo = document.querySelector('');
|
||||
const btnAggiungi = document.querySelector('');
|
||||
const ulSpesa = document.querySelector('');
|
||||
const divTotale = document.querySelector('');
|
||||
|
||||
|
||||
/**
|
||||
* FUNZIONE 1: Visualizza/Aggiorna Lista
|
||||
* Questa funzione è il "motore" grafico. Deve:
|
||||
* 1. Pulire la lista attuale nel DOM (per evitare duplicati)
|
||||
* 2. Ciclare l'array 'lista'
|
||||
* 3. Per ogni elemento, chiamare la funzione 'creaRigaElemento'
|
||||
* 4. Chiamare la funzione 'aggiornaTotale' alla fine per calcolare il conto
|
||||
*/
|
||||
function aggiornaLista() {
|
||||
ulSpesa.innerHTML = '';
|
||||
lista.forEach(elemento => {
|
||||
creaRigaElemento(elemento);
|
||||
});
|
||||
aggiornaTotale();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FUNZIONE 2: Crea Elemento HTML (li)
|
||||
* Questa funzione si occupa di creare il singolo pezzetto di HTML.
|
||||
* Deve:
|
||||
* 1. Creare un tag <li>
|
||||
* 2. Impostare il testo (es. "Pane - 1.50 €")
|
||||
* 3. Se l'elemento ha la proprietà .sbarrato === true, aggiungere la classe CSS 'preso'
|
||||
* 4. Gestire il click se clicco sull'li:
|
||||
* - Invertire la proprietà .sbarrato dell'oggetto (true/false)
|
||||
* - Aggiornare la classe CSS 'preso' sull'li (toggle)
|
||||
* - Aggiornare il totale chiamando aggiornaTotale()
|
||||
* 5. Aggiungere l'li al <ul> della lista
|
||||
*/
|
||||
function creaRigaElemento(elemento) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FUNZIONE 4: Calcola Totale
|
||||
* Deve:
|
||||
* 1. Creare una variabile somma = 0
|
||||
* 2. Ciclare l'array 'lista'
|
||||
* 3. Sommare i prezzi (Attenzione: farlo solo per quelli che NON sono sbarrati, cioè sbarrato: false)
|
||||
* 4. Scrivere il risultato nel divTotale
|
||||
*/
|
||||
function aggiornaTotale() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* EVENTO PRINCIPALE: Click su Aggiungi
|
||||
* 1. Leggere i valori degli input (value)
|
||||
* Nota che il prezzo deve essere convertito in numero.
|
||||
* Per farlo usa parseFloat(valore) o Number(valore)
|
||||
* 2. Validazione: se i campi sono pieni e il prezzo > 0
|
||||
* 3. Creare un nuovo oggetto { prodotto: ..., prezzo: ..., sbarrato: false }
|
||||
* 4. Aggiungerlo all'array 'lista' (push)
|
||||
* 5. Richiamare aggiornaLista()
|
||||
* 6. Svuotare gli input
|
||||
*/
|
||||
btnAggiungi.addEventListener('click', function () {
|
||||
});
|
||||
|
||||
|
||||
// AVVIO
|
||||
// Chiamata iniziale per mostrare i dati di esempio (Pane e Latte)
|
||||
aggiornaLista();
|
||||
112
javascript/08_DOM+/04_lista_spesa/style.css
Normal file
112
javascript/08_DOM+/04_lista_spesa/style.css
Normal file
@@ -0,0 +1,112 @@
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Stesso font dashboard */
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); /* Stesso sfondo dashboard */
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: white;
|
||||
width: 450px;
|
||||
padding: 30px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.input-group {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 12px;
|
||||
border: 2px solid #eee;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 10px;
|
||||
flex: 1;
|
||||
font-size: 1rem;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
border-color: #007bff;
|
||||
background-color: #fff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Facciamo l'input del prezzo un po' più piccolo */
|
||||
input[type="number"] {
|
||||
flex: 0 0 80px;
|
||||
}
|
||||
|
||||
|
||||
button {
|
||||
padding: 12px 25px;
|
||||
background: linear-gradient(135deg, #28a745 0%, #218838 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 4px 10px rgba(40, 167, 69, 0.3);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
background: #fff;
|
||||
border: 1px solid #eee;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
transition: all 0.2s;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.02);
|
||||
}
|
||||
|
||||
li:hover {
|
||||
background-color: #f8f9fa;
|
||||
transform: translateX(5px);
|
||||
border-color: #007bff;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.totale-container {
|
||||
text-align: right;
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Stili per la lista */
|
||||
|
||||
/* ESERCIZIO CSS:
|
||||
Aggiungi qui sotto la classe .preso
|
||||
Deve avere:
|
||||
- testo sbarrato (text-decoration: line-through)
|
||||
- colore grigino
|
||||
- sfondo un po' scuro
|
||||
*/
|
||||
43
javascript/08_DOM+/05_gestionale/index.html
Normal file
43
javascript/08_DOM+/05_gestionale/index.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Gestionale Dipendenti</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold; font-size: 14px;">← Dashboard</a>
|
||||
<h1>Gestione Dipendenti</h1>
|
||||
|
||||
<div class="controls">
|
||||
<div>
|
||||
<h3>Aggiungi Nuovo</h3>
|
||||
<input type="text" id="input-nome" placeholder="Nome">
|
||||
<input type="text" id="input-ruolo" placeholder="Ruolo">
|
||||
<button id="btn-aggiungi">Aggiungi</button>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Cerca</h3>
|
||||
<input type="text" id="input-ricerca" placeholder="Cerca per nome...">
|
||||
</div>
|
||||
<div>
|
||||
<!-- <h3>Azioni</h3> -->
|
||||
<!-- Zona per extra bottoni futuri -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nome</th>
|
||||
<th>Ruolo</th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tabella-corpo">
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
137
javascript/08_DOM+/05_gestionale/script.js
Normal file
137
javascript/08_DOM+/05_gestionale/script.js
Normal file
@@ -0,0 +1,137 @@
|
||||
// DATI INIZIALI
|
||||
const dipendenti = [
|
||||
{ nome: "Mario Rossi", ruolo: "Sviluppatore" },
|
||||
{ nome: "Luigi Bianchi", ruolo: "Sviluppatore" },
|
||||
{ nome: "Paolo Gialli", ruolo: "Sviluppatore" },
|
||||
{ nome: "Anna Neri", ruolo: "Sviluppatore" },
|
||||
{ nome: "Carlo Verdi", ruolo: "Project Manager" },
|
||||
{ nome: "Luca Bianchi", ruolo: "Designer" },
|
||||
];
|
||||
|
||||
// RIFERIMENTI DOM
|
||||
const tbody = document.querySelector('#tabella-corpo');
|
||||
const btnAggiungi = document.querySelector('#btn-aggiungi');
|
||||
const inputNome = document.querySelector('#input-nome');
|
||||
const inputRuolo = document.querySelector('#input-ruolo');
|
||||
const inputRicerca = document.querySelector('#input-ricerca');
|
||||
|
||||
|
||||
/**
|
||||
* FUNZIONE PRINCIPALE: Visualizza Tabella
|
||||
* Questa funzione deve:
|
||||
* - Pulire il contenuto del tbody
|
||||
* - Per ogni dipendente nell'array passato come argomento:
|
||||
* - Creare una riga (usando la funzione creaRiga)
|
||||
* - Aggiungere la riga al tbody
|
||||
*/
|
||||
function visualizzaTabella(lista) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FUNZIONE 1: Crea Riga
|
||||
* Questa funzione deve:
|
||||
* - Creare una riga (tr)
|
||||
* - Creare 3 celle (td): Nome, Ruolo, Azioni
|
||||
* - Popolare le celle Nome e Ruolo con i dati corretti
|
||||
* - Nella cella Azioni, aggiungere un bottone "Elimina"
|
||||
* - Aggiungere un event listener al bottone "Elimina" per rimuovere il dipendente dall'array e visualizzare la tabella
|
||||
* - Aggiungere le tre celle alla riga
|
||||
* - Aggiungere la riga al tbody
|
||||
*
|
||||
* Nota: Usare il metodo dipendenti.splice(i, 1) per rimuovere l'elemento dall'array
|
||||
* e poi richiamare visualizzaTabella(dipendenti) per mostrare la tabella aggiornata.
|
||||
*/
|
||||
function creaRiga(dipendente, indice) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FUNZIONE 2: Aggiungi Dipendente
|
||||
* 1. Leggere i valori degli input
|
||||
* 2. SE non sono vuoti:
|
||||
* - Creare un oggetto { nome: ..., ruolo: ... }
|
||||
* - Aggiungerlo all'array 'dipendenti'
|
||||
* - Richiamare visualizzaTabella() per aggiornare la vista
|
||||
* - Pulire gli input (settarli a stringa vuota)
|
||||
*/
|
||||
btnAggiungi.addEventListener('click', () => {
|
||||
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* FUNZIONE 3: Ricerca
|
||||
* 1. Leggere il testo nel campo ricerca
|
||||
* 2. Filtrare l'array 'dipendenti' usando:
|
||||
* - array.filter()
|
||||
* - dipendente.nome.includes(testoRicerca)
|
||||
* 3. Passare l'array filtrato a visualizzaTabella()
|
||||
*/
|
||||
inputRicerca.addEventListener('input', () => {
|
||||
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* FUNZIONE 4: Emoji per Ruolo
|
||||
* Aggiungere automaticamente un'emoji accanto al nome in base al ruolo.
|
||||
*
|
||||
* Passi:
|
||||
* 1. Sviluppa la funzione getEmojiPerRuolo(ruolo) che ritorna:
|
||||
* - "💻" per "Sviluppatore"
|
||||
* - "🎨" per "Designer"
|
||||
* - "👤" per altri ruoli
|
||||
* 2. Modifica la funzione creaRiga per usare getEmojiPerRuolo
|
||||
* 3. Usare la concatenazione stringhe per la cellaNome.textContent = emoji + " " + dipendente.nome;
|
||||
*/
|
||||
function getEmojiPerRuolo(ruolo) {
|
||||
// Implementa la logica qui
|
||||
}
|
||||
|
||||
|
||||
// AVVIO
|
||||
// Chiamare visualizzaTabella(dipendenti) all'inizio per mostrare i dati iniziali
|
||||
visualizzaTabella(dipendenti);
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************* ESERCIZI EXTRA *******************************/
|
||||
/************************************************************************/
|
||||
|
||||
/** ESERCIZIO EXTRA:
|
||||
* Migliorare la funzione creaRiga per aggiungere una classe CSS speciale
|
||||
* alle righe dei dipendenti che sono "Project Manager".
|
||||
*
|
||||
* Passi:
|
||||
* 1. Aggiungi una classe .manager (o .evidenziato) che evidenzi la riga (es. background-color: #feffae;)
|
||||
* 2. Modificare la funzione creaRiga:
|
||||
* - Controllare se dipendente.ruolo === "Project Manager"
|
||||
* - Se vero, aggiungere una classe CSS speciale alla riga (es. riga.classList.add('manager'))
|
||||
*/
|
||||
|
||||
/** ESERCIZIO EXTRA 2:
|
||||
* Aggiungere nel file index.html un bottone "Elimina Tutti" sopra la tabella.
|
||||
*
|
||||
* Passi:
|
||||
* 1. Aggiungere il bottone con un id specifico (es. id="btn-elimina-tutti")
|
||||
* 2. Stilizzare il bottone con CSS se necessario (colore rosso per esempio)
|
||||
* 3. Aggiungere un event listener al bottone nel file script.js
|
||||
* 4. Nell'event listener, svuotare l'array dipendenti (es. dipendenti.length = 0)
|
||||
* 5. Richiamare visualizzaTabella(dipendenti) per aggiornare la vista
|
||||
*/
|
||||
|
||||
/**
|
||||
* ESERCIZIO EXTRA 3:
|
||||
* Aggiungere un contatore sopra la tabella che mostra il numero totale di dipendenti.
|
||||
*
|
||||
* Passi:
|
||||
* 1. Aggiungere un elemento HTML (es. un div o span) con un id specifico (es. id="contatore-dipendenti")
|
||||
* 2. Mettere questo elemento sopra la tabella e stilizzarlo con CSS (metterlo almeno a destra)
|
||||
* 3. Creare una funzione aggiornaContatore()
|
||||
* - Questa funzione deve aggiornare il contenuto dell'elemento contatore con il numero di dipendenti (es. dipendenti.length)
|
||||
* 4. Chiamare aggiornaContatore() ogni volta che la tabella viene aggiornata (dopo aggiungere, eliminare, o filtrare dipendenti)
|
||||
*/
|
||||
114
javascript/08_DOM+/05_gestionale/style.css
Normal file
114
javascript/08_DOM+/05_gestionale/style.css
Normal file
@@ -0,0 +1,114 @@
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Stesso font dashboard */
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); /* Stesso sfondo dashboard */
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #2c3e50;
|
||||
display: block;
|
||||
padding: 40px;
|
||||
}
|
||||
.controls {
|
||||
background: white;
|
||||
padding: 25px;
|
||||
border-radius: 15px;
|
||||
border: none;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
/* Esempio di combinatore figlio diretto (>) */
|
||||
.controls > div {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.controls > div:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
background-color: #007bff; /* Blu base */
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate; /* Necessario per border-radius sulla tabella */
|
||||
border-spacing: 0;
|
||||
margin-top: 20px;
|
||||
background: white;
|
||||
border-radius: 15px;
|
||||
overflow: hidden; /* Taglia gli angoli */
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
th {
|
||||
background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
|
||||
color: white;
|
||||
padding: 15px;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.85rem;
|
||||
letter-spacing: 1px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
td {
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 15px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/************************************************************/
|
||||
/* ESERCIZI CSS: "RECUPERA GLI STILI PERSI" */
|
||||
/* Usa solo selettori di TAG, ID (#), CLASSI (.) */
|
||||
/* e combinatori di SPAZIO (discendente) */
|
||||
/************************************************************/
|
||||
|
||||
/* LIVELLO 1: Il bottone Elimina (Discendenza)
|
||||
Il bottone "Elimina" non ha classi, ma sappiamo che sta DENTRO il tbody.
|
||||
Seleziona tutti i button che sono dentro il #tabella-corpo.
|
||||
|
||||
Obiettivo: Sfondo rosso (#ff4444), testo bianco, nessun bordo.
|
||||
*/
|
||||
|
||||
|
||||
/* LIVELLO 2: Interattività (Hover su discendente)
|
||||
Vogliamo che il bottone elimina diventi più scuro quando ci passi sopra.
|
||||
|
||||
Obiettivo: Cambia il background-color in #cc0000 al passaggio del mouse.
|
||||
Suggerimento: usa lo stesso selettore di prima + :hover
|
||||
*/
|
||||
|
||||
|
||||
/* LIVELLO 3: Leggibilità Riga (Hover su riga)
|
||||
Vogliamo evidenziare tutta la riga (tr) della tabella quando il mouse ci passa sopra.
|
||||
ATTENZIONE: Deve succedere solo nel corpo della tabella, non nell'intestazione!
|
||||
|
||||
Obiettivo: Background-color grigio chiaro (#f1f1f1) al passaggio del mouse sulla riga.
|
||||
*/
|
||||
|
||||
|
||||
/* LIVELLO 4 (Extra): Focus sugli Input
|
||||
Vogliamo evidenziare gli input di testo quando l'utente ci clicca dentro (:focus).
|
||||
Ma solo quelli dentro la zona .controls!
|
||||
|
||||
Obiettivo: Bordo blu (2px solid blue) e sfondo giallo chiaro (#ffffe0).
|
||||
*/
|
||||
|
||||
231
javascript/08_DOM+/index.html
Normal file
231
javascript/08_DOM+/index.html
Normal file
@@ -0,0 +1,231 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Esercizi DOM</title>
|
||||
<style>
|
||||
/* RESET & BASE */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
margin: 0;
|
||||
padding: 40px;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* CONTENITORE PRINCIPALE */
|
||||
.hub-container {
|
||||
background: white;
|
||||
width: 100%;
|
||||
max-width: 750px;
|
||||
padding: 40px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
p.subtitle {
|
||||
text-align: center;
|
||||
color: #666;
|
||||
margin-bottom: 40px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* TITOLI SEZIONI */
|
||||
h2 {
|
||||
color: #333;
|
||||
font-size: 1.3rem;
|
||||
margin-top: 35px;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #007bff;
|
||||
}
|
||||
|
||||
h2:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* LISTA CARD */
|
||||
.exercise-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
/* CARD ESERCIZIO */
|
||||
.card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
background: #fff;
|
||||
border: 2px solid #f0f0f0;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-3px);
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 5px 15px rgba(0, 123, 255, 0.1);
|
||||
}
|
||||
|
||||
/* ICONA E TESTI */
|
||||
.icon {
|
||||
font-size: 2rem;
|
||||
margin-right: 20px;
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.info h3 {
|
||||
margin: 0 0 5px 0;
|
||||
color: #2c3e50;
|
||||
font-size: 1.1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.info p {
|
||||
margin: 0;
|
||||
color: #7f8c8d;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* TAG DIFFICOLTA' */
|
||||
.difficulty {
|
||||
display: inline-block;
|
||||
padding: 4px 10px;
|
||||
border-radius: 6px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.difficulty.tutorial {
|
||||
background: #e3f2fd;
|
||||
color: #1565c0;
|
||||
}
|
||||
|
||||
.difficulty.easy {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.difficulty.medium {
|
||||
background: #fff3cd;
|
||||
color: #856404;
|
||||
}
|
||||
|
||||
.difficulty.hard {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
/* NOTA IMPORTANTE */
|
||||
.important-note {
|
||||
background: #fff3cd;
|
||||
border-left: 4px solid #ffc107;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-top: 30px;
|
||||
font-size: 0.95rem;
|
||||
color: #856404;
|
||||
}
|
||||
|
||||
.important-note strong {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.important-note code {
|
||||
background: white;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="hub-container">
|
||||
<h1>DOM e Interattività</h1>
|
||||
<p class="subtitle">Manipolazione del DOM e Gestione degli Eventi</p>
|
||||
|
||||
<h2>Tutorial</h2>
|
||||
<div class="exercise-list">
|
||||
<a href="00_ripasso/index.html" class="card">
|
||||
<div class="icon">🔄</div>
|
||||
<div class="info">
|
||||
<h3>Ripasso DOM <span class="difficulty tutorial">Tutorial</span></h3>
|
||||
<p>Selettori, manipolazione base del DOM</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h2>Esercizi</h2>
|
||||
<div class="exercise-list">
|
||||
|
||||
<a href="01_profilo/index.html" class="card">
|
||||
<div class="icon">👤</div>
|
||||
<div class="info">
|
||||
<h3>Profilo Utente <span class="difficulty easy">Facile</span></h3>
|
||||
<p>Manipolazione statica, Oggetti e attributi</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="02_tabella_utenti/index.html" class="card">
|
||||
<div class="icon">📊</div>
|
||||
<div class="info">
|
||||
<h3>Tabella Utenti <span class="difficulty easy">Facile</span></h3>
|
||||
<p>Form, append Child, Tabella dinamica</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="03_lista_semplice/index.html" class="card">
|
||||
<div class="icon">📝</div>
|
||||
<div class="info">
|
||||
<h3>Lista Semplice <span class="difficulty medium">Medio</span></h3>
|
||||
<p>Cicli, Array, Creazione elementi in loop</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="04_lista_spesa/index.html" class="card">
|
||||
<div class="icon">🛒</div>
|
||||
<div class="info">
|
||||
<h3>Lista Spesa <span class="difficulty medium">Medio</span></h3>
|
||||
<p>Array, Cicli, Add/Remove, Totali</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="05_gestionale/index.html" class="card">
|
||||
<div class="icon">💼</div>
|
||||
<div class="info">
|
||||
<h3>Gestionale <span class="difficulty hard">Difficile</span></h3>
|
||||
<p>Tabelle, Filtri di ricerca, aggiunta/rimozione</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user