├── 02-eventos ├── app.js ├── index.html └── estilos.css ├── 03-clases ├── app.js ├── index.html ├── estilos.css └── celebration.svg ├── 01-traversing ├── app.js ├── estilos.css └── index.html ├── 04-estilos ├── estilos.css ├── index.html └── app.js ├── 05-todo-list ├── index.html ├── estilos.css └── app.js └── 06-tic-tac-toe ├── index.html ├── estilos.css └── app.js /02-eventos/app.js: -------------------------------------------------------------------------------- 1 | 2 | const section = document.querySelector('.section'); 3 | 4 | function eventDelegation(e){ 5 | if(e.target.matches('.button-color')){ 6 | const getColor = e.target.getAttribute('data-color'); 7 | 8 | e.currentTarget.style.backgroundColor = getColor; 9 | } 10 | } 11 | 12 | section.addEventListener('click', eventDelegation); -------------------------------------------------------------------------------- /03-clases/app.js: -------------------------------------------------------------------------------- 1 | const button = document.querySelector('.button'); 2 | const modal = document.querySelector('.modal'); 3 | const closeModal = document.querySelector('.modal__close'); 4 | 5 | button.addEventListener('click', function(){ 6 | console.log(modal.classList); 7 | 8 | modal.classList.add('show'); 9 | 10 | console.log(modal.classList); 11 | }); 12 | 13 | closeModal.addEventListener('click', function(){ 14 | 15 | modal.classList.remove('show', 'clase2'); 16 | 17 | }); 18 | 19 | 20 | -------------------------------------------------------------------------------- /01-traversing/app.js: -------------------------------------------------------------------------------- 1 | const wrapper = document.querySelector('#wrapper'); 2 | const title = document.querySelector('.title'); 3 | const link = document.querySelector('.link.bold'); 4 | const inputNumber = document.querySelector('[type="number"]'); 5 | 6 | const img = document.querySelector('[data-identificador="img"]'); 7 | const figcaption = document.querySelector('figcaption'); 8 | 9 | img.src = "https://upload.wikimedia.org/wikipedia/commons/5/52/Spider-Man.jpg"; 10 | 11 | figcaption.textContent = img.dataset.textoMostrar; -------------------------------------------------------------------------------- /04-estilos/estilos.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | box-sizing: border-box; 4 | } 5 | 6 | body{ 7 | font-family: Arial, Helvetica, sans-serif; 8 | } 9 | 10 | .wrapper{ 11 | width: 90%; 12 | max-width: 1200px; 13 | margin: 0 auto; 14 | padding: 60px 0; 15 | 16 | display: grid; 17 | gap: 2rem; 18 | } 19 | 20 | .title{ 21 | font-size: 3rem; 22 | text-align: center; 23 | margin-bottom: 2rem; 24 | 25 | color: steelblue; 26 | 27 | } 28 | 29 | .title::after{ 30 | content: "Soy un psuedoelemento"; 31 | font-size: 1rem; 32 | margin-top: 1rem; 33 | } -------------------------------------------------------------------------------- /01-traversing/estilos.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | box-sizing: border-box; 4 | } 5 | 6 | body{ 7 | font-family: Arial, Helvetica, sans-serif; 8 | } 9 | 10 | .wrapper{ 11 | margin: 0 auto; 12 | width: 90%; 13 | max-width: 500px; 14 | padding: 3rem 0; 15 | } 16 | 17 | .title{ 18 | text-align: center; 19 | font-size: 3rem; 20 | margin-bottom: 2rem; 21 | } 22 | 23 | .link{ 24 | background-color: rebeccapurple; 25 | color: white; 26 | display: block; 27 | width: max-content; 28 | padding: 1rem 2rem; 29 | margin-top: 1rem; 30 | text-decoration: none; 31 | } 32 | 33 | .bold{ 34 | font-weight: bold; 35 | } 36 | 37 | form{ 38 | margin-top: 3rem; 39 | } 40 | 41 | img{ 42 | width: 100%; 43 | } -------------------------------------------------------------------------------- /04-estilos/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | DOM 7 | 8 | 9 | 10 | 11 |
12 | 13 |

¡Cambia los estilos dinámicamente!

14 | 15 |
16 |

Cambia el color del texto

17 | 18 |
19 | 20 |
21 |

Cambia el tamaño del texto

22 | 23 |
24 | 25 |
26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /05-todo-list/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Tareas 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |

¡Agrega una tarea!

15 | 16 |
17 | 18 | 19 |
20 |
21 | 22 | 23 | 26 | 27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /04-estilos/app.js: -------------------------------------------------------------------------------- 1 | const title = document.querySelector('.title'); 2 | const inputColor = document.querySelector('[type="color"]'); 3 | const inputRange = document.querySelector('[type="range"]'); 4 | 5 | title.style.fontFamily = "cursive"; 6 | 7 | const estilosTitle = getComputedStyle(title, '::after'); 8 | console.log( 9 | estilosTitle.getPropertyValue('margin') 10 | ); 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | inputColor.addEventListener('change', function(e){ 19 | const newColor = e.target.value; 20 | 21 | title.style.color = newColor; 22 | }); 23 | 24 | inputRange.addEventListener('change', function(e){ 25 | const newFontSize = e.target.value; 26 | 27 | title.style.setProperty('font-size', newFontSize+'px', 'important'); 28 | 29 | console.log(title.style.getPropertyPriority('font-family')); 30 | 31 | console.log(title.style.getPropertyPriority('font-size')); 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /05-todo-list/estilos.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | box-sizing: border-box; 4 | } 5 | 6 | body{ 7 | font-family: Arial, Helvetica, sans-serif; 8 | } 9 | 10 | .wrapper{ 11 | width: 90%; 12 | max-width: 1200px; 13 | margin: 0 auto; 14 | padding: 60px 0; 15 | 16 | display: grid; 17 | gap: 3rem; 18 | } 19 | 20 | .form{ 21 | display: grid; 22 | gap: 1.5rem; 23 | } 24 | 25 | .title{ 26 | font-size: 2.5rem; 27 | text-align: center; 28 | } 29 | 30 | .list{ 31 | display: flex; 32 | gap: 1rem; 33 | } 34 | 35 | .input{ 36 | flex: 1; 37 | border-radius: 10px; 38 | border: #ccc 2px solid; 39 | } 40 | 41 | .button{ 42 | background-color: slateblue; 43 | width: max-content; 44 | border: none; 45 | padding: 1rem 2rem; 46 | color: white; 47 | font-weight: bold; 48 | border-radius: 10px; 49 | } 50 | 51 | .list-container{ 52 | display: grid; 53 | gap: 1.5rem; 54 | } -------------------------------------------------------------------------------- /06-tic-tac-toe/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Tic Tac Toe 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |

El turno es para 15 | 16 |

17 |
18 | 19 | 20 |
21 |

Hola

22 |
23 |
24 | 25 |
26 |
27 |

28 |

¿Quieres volver a jugar?

29 | 30 |
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /02-eventos/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | DOM 7 | 8 | 9 | 10 | 11 |
12 | 13 |

¡Bienvenido 👋, 14 | Usuario 15 | ! 16 |

17 | 18 |
19 | 20 | 21 |
22 | 23 |
24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /02-eventos/estilos.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | box-sizing: border-box; 4 | } 5 | 6 | body{ 7 | font-family: Arial, Helvetica, sans-serif; 8 | } 9 | 10 | [data-id="wrapper"]{ 11 | width: 90%; 12 | max-width: 1200px; 13 | margin: 0 auto; 14 | padding: 60px 0; 15 | transition: transform .5s; 16 | } 17 | 18 | .title{ 19 | font-size: 3rem; 20 | text-align: center; 21 | padding-bottom: 1rem; 22 | margin-bottom: 1.5rem; 23 | border-bottom: 6px solid #ff5e00; 24 | } 25 | 26 | .show{ 27 | transform: scale(1); 28 | } 29 | 30 | .hide{ 31 | transform: scale(0); 32 | } 33 | 34 | form{ 35 | padding-top: 2rem; 36 | } 37 | 38 | .section{ 39 | background-color: rebeccapurple; 40 | padding: 2rem 0; 41 | width: 90%; 42 | margin: 0 auto; 43 | display: grid; 44 | grid-template-columns: 50%; 45 | place-content: center; 46 | gap: 1rem; 47 | } 48 | 49 | button, a{ 50 | text-align: center; 51 | text-decoration: none; 52 | color: black; 53 | border: none; 54 | background-color: wheat; 55 | padding: 1rem 2rem; 56 | border-radius: 30px; 57 | cursor: pointer; 58 | } -------------------------------------------------------------------------------- /01-traversing/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | DOM 8 | 9 | 10 | 11 |
12 | 13 |
14 |
15 |
16 | 17 |

DOM (Document Object Model)

18 |
19 | 20 | Primer Hijo 21 | Segundo Hijo 22 | Tercer Hijo 23 | 24 |
25 | 26 | Cuarto Hijo 27 | 28 |
29 | 30 | 31 | 32 | 33 |
34 | 35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /03-clases/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | DOM 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /03-clases/estilos.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | box-sizing: border-box; 4 | } 5 | 6 | body{ 7 | font-family: Arial, Helvetica, sans-serif; 8 | } 9 | 10 | .wrapper{ 11 | width: 90%; 12 | max-width: 1200px; 13 | margin: 0 auto; 14 | padding: 60px 0; 15 | } 16 | 17 | 18 | button, .modal__cta{ 19 | display: block; 20 | width: max-content; 21 | margin: 0 auto; 22 | 23 | border: none; 24 | background-color: royalblue; 25 | color: white; 26 | 27 | font-weight: bold; 28 | padding: 1rem 2rem; 29 | border-radius: 30px; 30 | cursor: pointer; 31 | } 32 | 33 | .red{ 34 | background-color: darkred; 35 | } 36 | 37 | .modal{ 38 | position: fixed; 39 | display: grid; 40 | place-items: center; 41 | inset: 0; 42 | background-color: #0000008d; 43 | 44 | transition: opacity .3s; 45 | 46 | pointer-events: none; 47 | opacity: 0; 48 | } 49 | 50 | .show{ 51 | pointer-events: unset; 52 | opacity: 1; 53 | } 54 | 55 | .modal__container{ 56 | border-radius: 10px; 57 | position: relative; 58 | display: grid; 59 | gap: 1rem; 60 | background-color: #fff; 61 | width: 90%; 62 | max-width: 600px; 63 | margin: auto; 64 | padding: 2rem; 65 | text-align: center; 66 | } 67 | 68 | .modal__close{ 69 | background-color: darkred; 70 | color: white; 71 | width: 30px; 72 | height: 30px; 73 | font-size: 23px; 74 | border-radius: 50%; 75 | position: absolute; 76 | top: -15px; 77 | right: -15px; 78 | cursor: pointer; 79 | } 80 | 81 | .modal__figure{ 82 | width: 90%; 83 | 84 | } 85 | 86 | .modal__img{ 87 | width: 100%; 88 | display: block; 89 | } 90 | 91 | .modal__title{ 92 | font-size: 2rem; 93 | } 94 | 95 | .modal__cta{ 96 | text-decoration: none; 97 | margin-top: 1rem; 98 | } -------------------------------------------------------------------------------- /05-todo-list/app.js: -------------------------------------------------------------------------------- 1 | const button = document.querySelector('.button'); 2 | const form = document.querySelector('.form'); 3 | const input = form.querySelector('.input'); 4 | const listContainer = document.querySelector('.list-container'); 5 | 6 | form.addEventListener('submit', handleSubmit); 7 | 8 | message(); 9 | 10 | function message(){ 11 | const h3 = document.createElement('h3'); 12 | h3.classList.add('task-message'); 13 | 14 | h3.textContent = listContainer.firstElementChild ? 'Tareas por hacer' : 'No hay tareas aún'; 15 | 16 | const prevMessage = document.querySelector('.task-message'); 17 | 18 | if(prevMessage){ 19 | 20 | prevMessage.replaceWith(h3); 21 | 22 | return; 23 | } 24 | 25 | listContainer.before(h3); 26 | 27 | 28 | } 29 | 30 | function handleSubmit(e){ 31 | e.preventDefault(); 32 | 33 | const inputValue = input.value; 34 | 35 | 36 | createTask(inputValue); 37 | 38 | this.reset(); 39 | message(); 40 | } 41 | 42 | function createTask(value){ 43 | const newTask = document.createElement("li"); 44 | newTask.textContent = value; 45 | 46 | listContainer.prepend(newTask); 47 | 48 | addEvents(newTask); 49 | } 50 | 51 | function addEvents(element){ 52 | element.addEventListener('dblclick', function(){ 53 | // eliminar 54 | element.remove(); 55 | message(); 56 | }); 57 | } 58 | 59 | const wrapper = document.querySelector('.wrapper'); 60 | 61 | const copiaWrapper = wrapper.cloneNode(true);+ 62 | 63 | wrapper.before(copiaWrapper); 64 | 65 | /* 66 | 67 | - `beforebegin` ← El HTML se inserta antes del elemento de referencia, como hermano anterior. 68 | 69 | - `afterbegin` ← El HTML se inserta como primer hijo del elemento. 70 | 71 | - `beforeend` ← El HTML se inserta como último hijo del elemento. 72 | 73 | - `afterend` ← El HTML se inserta después del elemento de referencia, como hermano siguiente. 74 | 75 | */ -------------------------------------------------------------------------------- /06-tic-tac-toe/estilos.css: -------------------------------------------------------------------------------- 1 | *, ::before, ::after{ 2 | margin: 0; 3 | box-sizing: border-box; 4 | } 5 | 6 | body{ 7 | background-color: #ec4989; 8 | font-family: Arial; 9 | color: white; 10 | } 11 | 12 | .game{ 13 | width: 100%; 14 | height: 100vh; 15 | display: grid; 16 | gap: 1rem; 17 | place-content: center; 18 | } 19 | 20 | .game__board{ 21 | width: 300px; 22 | height: 300px; 23 | display: grid; 24 | grid-template-columns: 1fr 1fr 1fr; 25 | grid-template-rows: 1fr 1fr 1fr; 26 | } 27 | 28 | .cell{ 29 | width: 100%; 30 | height: 100%; 31 | border: 2px solid #fff; 32 | display: grid; 33 | place-items: center; 34 | grid-template-areas: "draw"; 35 | cursor: pointer; 36 | } 37 | 38 | .circle::after{ 39 | content: ""; 40 | grid-area: draw; 41 | display: block; 42 | width: 50px; 43 | height: 50px; 44 | border-radius: 50%; 45 | border: 10px solid white; 46 | animation: show .3s; 47 | } 48 | 49 | .cross::after{ 50 | content: ""; 51 | grid-area: draw; 52 | display: block; 53 | width: 10px; 54 | height: 70px; 55 | background-color: white; 56 | transform: rotate(45deg); 57 | border-radius: 10px; 58 | animation: show-reverse .3s; 59 | } 60 | 61 | .cross::before{ 62 | content: ""; 63 | grid-area: draw; 64 | display: block; 65 | width: 10px; 66 | height: 70px; 67 | background-color: white; 68 | transform: rotate(-45deg); 69 | border-radius: 10px; 70 | animation: show .3s; 71 | } 72 | 73 | @keyframes show { 74 | 0%{ 75 | transform: scale(0) rotate(-45deg); 76 | } 77 | 100%{ 78 | transform: scale(1) rotate(-45deg); 79 | } 80 | } 81 | 82 | @keyframes show-reverse { 83 | 0%{ 84 | transform: scale(0) rotate(45deg); 85 | } 86 | 100%{ 87 | transform: scale(1) rotate(45deg); 88 | } 89 | } 90 | 91 | 92 | 93 | .endgame{ 94 | background-color: #000000bc; 95 | position: absolute; 96 | inset: 0; 97 | opacity: 0; 98 | pointer-events: none; 99 | transition: opacity .3s; 100 | 101 | display: grid; 102 | place-content: center; 103 | } 104 | 105 | .endgame__show{ 106 | display: grid; 107 | gap: 1rem; 108 | text-align: center; 109 | } 110 | 111 | .endgame__button{ 112 | background-color: dodgerblue; 113 | font-weight: bold; 114 | color: white; 115 | padding: 1rem 2rem; 116 | margin: 0 auto; 117 | width: max-content; 118 | border: none; 119 | border-radius: 100px; 120 | } 121 | 122 | .show{ 123 | opacity: 1; 124 | pointer-events: unset; 125 | } -------------------------------------------------------------------------------- /06-tic-tac-toe/app.js: -------------------------------------------------------------------------------- 1 | const gameBoard = document.querySelector('.game__board'); 2 | const messageTurn = document.querySelector('.game__turn'); 3 | const endGame = document.querySelector('.endgame'); 4 | const endGameResult = document.querySelector('.endgame__result'); 5 | const buttonReset = document.querySelector('.endgame__button'); 6 | 7 | let isTurnX = true; 8 | let turn = 0; 9 | let maxTurn = 9; 10 | let players = { 11 | x: 'cross', 12 | o: 'circle' 13 | } 14 | const winningPosition = [ 15 | [0,1,2], [3,4,5], [6,7,8], 16 | [0,3,6], [1,4,7], [2,5,8], 17 | [0,4,8], [2,4,6] 18 | ] 19 | 20 | startGame(); 21 | 22 | 23 | function startGame(){ 24 | createBoard(); 25 | messageTurn.textContent = isTurnX ? 'X' : 'O'; 26 | isTurnX = true; 27 | turn = 0; 28 | endGame.classList.remove('show'); 29 | } 30 | 31 | function createBoard(){ 32 | const cells = 9; 33 | 34 | while(gameBoard.firstElementChild){ 35 | gameBoard.firstElementChild.remove(); 36 | } 37 | 38 | for (let i = 0; i < cells; i++) { 39 | const div = document.createElement('div'); 40 | 41 | div.classList.add('cell'); 42 | div.addEventListener('click', handleGame , {once:true}); 43 | 44 | gameBoard.append(div); 45 | } 46 | } 47 | 48 | function handleGame(e){ 49 | const currentCell = e.currentTarget; 50 | const currentTurn = isTurnX ? players.x : players.o; 51 | 52 | turn++; 53 | drawShape(currentCell, currentTurn); 54 | 55 | if(checkWinner(currentTurn)){ 56 | return; 57 | } 58 | 59 | if(turn === maxTurn){ 60 | showEndGame(false); 61 | } 62 | 63 | changeTurn(); 64 | } 65 | 66 | function drawShape(element, newClass){ 67 | element.classList.add(newClass); 68 | } 69 | 70 | function changeTurn(){ 71 | isTurnX = !isTurnX; 72 | messageTurn.textContent = isTurnX ? 'X' : 'O'; 73 | } 74 | 75 | function checkWinner(currentPlayer){ 76 | const cells = document.querySelectorAll('.cell'); 77 | 78 | const winner = winningPosition.some(array =>{ 79 | 80 | return array.every(position =>{ 81 | 82 | return cells[position].classList.contains(currentPlayer); 83 | 84 | }); 85 | 86 | }); 87 | 88 | if(!winner){ 89 | return; 90 | } 91 | 92 | showEndGame(true); 93 | return true; 94 | } 95 | 96 | function showEndGame(winner){ 97 | endGame.classList.add('show'); 98 | 99 | if(winner){ 100 | endGameResult.textContent = `¡${isTurnX ? "X" : "O"} ha ganado el juego!`; 101 | }else{ 102 | endGameResult.textContent = `¡El juego se ha empatado!`; 103 | } 104 | } 105 | 106 | buttonReset.addEventListener('click', startGame); -------------------------------------------------------------------------------- /03-clases/celebration.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------