├── .gitignore ├── .vscode └── settings.json ├── APIs ├── datos.json ├── estilos.css ├── fechas.js ├── fetchAPI.js ├── index.html ├── introduccion.js ├── json.js └── localstorage.js ├── BOM ├── alerts.js ├── cookies.js ├── estilos.css ├── index.html ├── location.js ├── navigator.js ├── timers.js └── window.js ├── DOM ├── creandoElementos.js ├── delegacionDeEventos.js ├── eliminandoElementos.js ├── eliminarEventos.js ├── estilos.css ├── eventos.js ├── index.html ├── introduccion.js ├── modificandoElementos.js ├── modificandoEstilosMedianteClases.js ├── modificandoEstilosMedianteJs.js ├── obtenerElementos.js ├── propagacionDeEventos.js └── tiposDePropagacion.js ├── Extras ├── debugging.js ├── estilos.css ├── index.html ├── maps.js ├── sets.js └── this.js ├── Formularios ├── estilos.css ├── eventosFormulario.js ├── expresionesRegulares.js ├── formularios.js ├── index.html └── validarFormularios.js ├── Introducción ├── arreglos.js ├── asyncAwait.js ├── breakContinue.js ├── callbacks.js ├── cicloFor.js ├── cicloForEach.js ├── cicloWhile.js ├── clases.js ├── condicionales.js ├── estilos.css ├── funciones.js ├── herencia.js ├── holaMundo.html ├── holaMundo.js ├── index.html ├── metodosEstaticos.js ├── metodosParaArreglos.js ├── metodosParaArreglos2.js ├── metodosParaNumeros.js ├── metodosParaObjetos.js ├── metodosParaStrings.js ├── objetos.js ├── operadorSpread.js ├── operadorTernario.js ├── operadores.js ├── parametros.js ├── promesas.js ├── promesas2.js ├── return.js ├── scope.js ├── switch.js ├── templateStrings.js ├── tiposDeDatos.js └── variables.js ├── Modulos ├── package-lock.json ├── package.json ├── public │ └── bundle.js ├── rollup.config.js └── src │ ├── defaultExport.js │ ├── emptyExport.js │ ├── index.js │ └── namedExports.js └── Proyectos ├── App_gastos ├── index.html ├── package-lock.json ├── package.json ├── public │ ├── bundle.css │ ├── bundle.css.map │ ├── bundle.js │ └── bundle.js.map ├── rollup.config.js ├── sass │ ├── _fondo.scss │ ├── _footer.scss │ ├── _formulario-gasto.scss │ ├── _gastos.scss │ ├── _generales.scss │ ├── _header.scss │ ├── _main.scss │ ├── _variables.scss │ └── index.scss └── src │ ├── agregarGasto.js │ ├── cargarGastos.js │ ├── cargarTotalGastado.js │ ├── eventoBtnFormularioGasto.js │ ├── eventosGasto.js │ └── index.js ├── Formulario ├── index.html ├── package-lock.json ├── package.json ├── public │ ├── bundle.css │ ├── bundle.css.map │ ├── bundle.js │ └── bundle.js.map ├── rollup.config.js ├── sass │ ├── _formulario.scss │ ├── _generales.scss │ ├── _variables.scss │ ├── alerta.scss │ ├── index.scss │ └── linea-pasos.scss └── src │ ├── formulario.js │ ├── index.js │ ├── lineaPasos.js │ ├── marcarPaso.js │ ├── siguientePaso.js │ └── validaciones │ ├── validarCantidad.js │ ├── validarCorreo.js │ └── validarNombre.js ├── Galeria ├── img │ ├── africa.jpg │ ├── africa │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ ├── america.jpg │ ├── america │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ ├── antartida.jpg │ ├── antartida │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ ├── asia.jpg │ ├── asia │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ ├── bg.jpg │ ├── europa.jpg │ ├── europa │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ ├── oceania.jpg │ └── oceania │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg ├── index.html ├── package-lock.json ├── package.json ├── public │ ├── bundle.css │ ├── bundle.css.map │ └── bundle.js ├── rollup.config.js ├── sass │ ├── _categorias.scss │ ├── _footer.scss │ ├── _galeria.scss │ ├── _generales.scss │ ├── _hero.scss │ ├── _variables.scss │ └── index.scss └── src │ ├── cargarCategorias.js │ ├── data │ ├── categorias.js │ └── fotos.js │ ├── eventoCategorias.js │ ├── galeria │ ├── cargarImagen.js │ ├── carousel.js │ ├── cerrarGaleria.js │ ├── eventosGaleria.js │ └── slideClick.js │ └── index.js ├── Peliculas ├── img │ ├── 1.png │ ├── 10.png │ ├── 11.png │ ├── 12.png │ ├── 13.png │ ├── 14.png │ ├── 15.png │ ├── 16.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ ├── 9.png │ └── logo.png ├── index.html ├── package-lock.json ├── package.json ├── public │ ├── bundle.css │ ├── bundle.css.map │ ├── bundle.js │ └── bundle.js.map ├── rollup.config.js ├── sass │ ├── _btn.scss │ ├── _generales.scss │ ├── _main.scss │ ├── _media.scss │ ├── _sidebar.scss │ ├── _variables.scss │ └── index.scss └── src │ ├── cargarGeneros.js │ ├── cargarTitulos.js │ ├── fetchBusqueda.js │ ├── fetchGeneros.js │ ├── fetchItem.js │ ├── fetchPopulares.js │ ├── index.js │ ├── listenerBuscar.js │ ├── listenerFiltroGeneros.js │ ├── listenerFiltroTipo.js │ ├── listenerItems.js │ ├── listenerPopup.js │ ├── obtenerGenero.js │ └── paginacion.js ├── Portafolio ├── img │ ├── hero.jpg │ ├── info.png │ ├── review-1.jpg │ ├── review-2.jpg │ ├── review-3.jpg │ ├── review-4.jpg │ ├── trabajo-1.jpg │ ├── trabajo-2.jpg │ ├── trabajo-3.jpg │ ├── trabajo-4.jpg │ ├── trabajo-5.jpg │ └── trabajo-6.jpg ├── index.html ├── package-lock.json ├── package.json ├── public │ ├── bundle.css │ ├── bundle.css.map │ ├── bundle.js │ └── bundle.js.map ├── rollup.config.js ├── sass │ ├── _comentarios.scss │ ├── _footer.scss │ ├── _generales.scss │ ├── _header.scss │ ├── _hero.scss │ ├── _trabajos.scss │ ├── _variables.scss │ ├── _ventana.scss │ └── index.scss └── src │ ├── animarGaleria.js │ ├── animarTexto.js │ ├── galeria.js │ ├── index.js │ ├── slider.js │ └── ventanaCorreo.js └── Tienda ├── css └── estilos.css ├── img ├── raw │ ├── ayo-ogunseinde-6W4F62sN_yI-unsplash.jpg │ ├── ayo-ogunseinde-sibVwORYqs0-unsplash.jpg │ ├── camila-damasio-mWYhrOiAgmA-unsplash.jpg │ ├── darklabs-india-g9JTq14wBQM-unsplash.jpg │ ├── douglas-bagg-Yb_pvbQc0mc-unsplash.jpg │ ├── jaizer-capangpangan-2Xhv5zrTLN0-unsplash.jpg │ ├── kris-gerhard-0BKZfcamvGg-unsplash.jpg │ ├── mitchel-lensink-1BI-ar91C7U-unsplash.jpg │ ├── rachael-ren-Ueu_6ZrVb80-unsplash.jpg │ ├── thamara-maura-rniFdQKztF8-unsplash.jpg │ ├── thuan-pham-tvl2Pa98K_g-unsplash.jpg │ └── vince-fleming-j3lf-Jn6deo-unsplash.jpg ├── tennis │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── amarillo.jpg │ ├── negro.jpg │ └── rojo.jpg ├── thumbs │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── amarillo.jpg │ ├── negro.jpg │ └── rojo.jpg └── users │ ├── 1.jpg │ ├── 2.jpg │ └── 3.jpg ├── index.html ├── package-lock.json ├── package.json ├── public ├── bundle.css ├── bundle.css.map └── bundle.js ├── rollup.config.js ├── sass ├── _generales.scss ├── _header.scss ├── _variables.scss ├── componentes │ ├── _breadcrumbs.scss │ ├── _carrito.scss │ ├── _notificacion.scss │ ├── _producto.scss │ └── _tabs.scss └── index.scss └── src ├── carrito.js ├── data └── productos.js ├── index.js ├── producto.js └── tabs.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "sqltools.connections": [ 3 | { 4 | "previewLimit": 50, 5 | "server": "localhost", 6 | "port": 5432, 7 | "askForPassword": true, 8 | "driver": "PostgreSQL", 9 | "name": "PostgreSQL", 10 | "database": "test", 11 | "username": "postgres" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /APIs/datos.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "nombre": "Carlos Arturo", 4 | "suscriptor_activo": true, 5 | "posts": [ 6 | { 7 | "id": 1, 8 | "titulo": "Titulo del primer post", 9 | "texto": "texto del primer post ..." 10 | }, 11 | { 12 | "id": 2, 13 | "titulo": "Titulo del segundo post", 14 | "texto": "texto del segundo post ..." 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /APIs/estilos.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: 'Poppins', sans-serif; 11 | min-height: 100vh; 12 | width: 100%; 13 | background: #eaeaea; 14 | color: #000; 15 | display: flex; 16 | flex-direction: column; 17 | align-items: center; 18 | justify-content: center; 19 | } 20 | 21 | h1 { 22 | font-size: 80px; 23 | } 24 | 25 | h2 { 26 | font-size: 40px; 27 | font-weight: normal; 28 | margin-bottom: 40px; 29 | color: #848484; 30 | } 31 | 32 | button { 33 | border: none; 34 | background: #2553df; 35 | font-family: 'Poppins', sans-serif; 36 | font-size: 22px; 37 | cursor: pointer; 38 | border-radius: 10px; 39 | color: #fff; 40 | padding: 14px 28px; 41 | margin-bottom: 20px; 42 | } 43 | 44 | button:hover { 45 | background: #1942be; 46 | } 47 | -------------------------------------------------------------------------------- /APIs/fechas.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 API para trabajar con fechas 3 | Javascript expone su API para que podamos trabajar con fechas. 4 | 5 | https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date 6 | */ 7 | 8 | /* 9 | 📌 Crear un objeto de fecha 10 | Para poder trabajar con fechas primero tenemos que crear un objeto de fecha. 11 | */ 12 | // Fecha actual 13 | const fechaActual = new Date(); 14 | 15 | // Con una cadena de texto 16 | // año-mes-diaThoras:minutos:segundos 17 | const cumpleaños = new Date('1995-09-07T12:00:00'); 18 | console.log(cumpleaños); 19 | 20 | /* 21 | 📌 Metodos para trabajar con fechas 22 | */ 23 | // Convertir objeto de fecha a cadena de texto 24 | console.log(fechaActual.toString()); 25 | console.log(fechaActual.toDateString()); 26 | console.log(fechaActual.toTimeString()); 27 | 28 | // Obtener mes 29 | console.log(fechaActual.getMonth()); 30 | 31 | // Obtener día 32 | console.log(fechaActual.getDate()); 33 | 34 | // Obtener año 35 | console.log(fechaActual.getFullYear()); 36 | 37 | /* 38 | Si queremos hacer cosas más complejas con fechas podemos usar librerias como date-fns 39 | https://date-fns.org/ 40 | */ 41 | -------------------------------------------------------------------------------- /APIs/fetchAPI.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Fetch API 3 | Es una API del navegador que nos permite hacer peticiones a servidores. 4 | Esta api nos devuelve una promesa, por lo que podemos trabajar con async await 5 | */ 6 | 7 | /* 8 | Nota: existen muchas paginas que nos permiten subir un pequeño archivo JSON 9 | durante unos minutos para hacer pruebas. 10 | 11 | Despues de unos minutos o varias peticiones puede que deje de funcionar 12 | y tengamos que volver a subir el json. 13 | 14 | https://www.npoint.io/ 15 | */ 16 | 17 | const endpoint = 'https://api.npoint.io/28eb8a275f10ea60b175'; 18 | 19 | const respuesta = fetch(endpoint) 20 | .then((respuesta) => { 21 | console.log('El servidor respondio'); 22 | console.log(respuesta); 23 | 24 | // Extraemos el body 25 | const promesa = respuesta.json(); 26 | promesa 27 | .then((datos) => { 28 | console.log(datos); 29 | }) 30 | .catch((error) => { 31 | console.log(error); 32 | }); 33 | }) 34 | .catch((error) => { 35 | console.log(error); 36 | }); 37 | 38 | /* 39 | 📌 Ejemplo con Async/Await 40 | */ 41 | const obtenerDatos = async () => { 42 | const respuesta = await fetch(endpoint); 43 | const datos = await respuesta.json(); 44 | console.log(datos); 45 | }; 46 | obtenerDatos(); 47 | -------------------------------------------------------------------------------- /APIs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso de Javascript 8 | 9 | 10 | 11 | 12 |

Curso de Javascript

13 |

Completo, Práctico y desde Cero

14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /APIs/introduccion.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Que son las API 3 | Application Programming Interface 4 | */ 5 | 6 | /* 7 | 📌 Las API son una forma en la que el navegador web o un servidor externo nos dan acceso a funciones adicionales para hacer cosas que normalmente serian dificiles. 8 | */ 9 | 10 | /* 11 | 📌 APIs del navegador web 12 | Los navegadores nos dan acceso a diferentes API con las que podemos: 13 | - Local Storage API - Trabajar con almacenamiento local 14 | - Fetch API - Hacer peticiones a servidores 15 | - History API - Para poder acceder al historial de la página. 16 | - Validation API - Para hacer uso de las funciones del navegador para validar fomrularios 17 | - Más 18 | */ 19 | 20 | /* 21 | 📌 APIs Externas 22 | Tambien puede haber APIs externas que nos permiten acceder a recursos de otra página web. 23 | Ejemplo con la API de youtube: 24 | - Nos permite obtener información de videos y canales 25 | - Nos permite subir videos 26 | 27 | Estas son cosas que no podriamos hacer desde nuestra página si no existiera una API. 28 | Gracias a que existe una API, podemos hablarle y pedirle obtener datos u hacer operaciones. 29 | */ 30 | -------------------------------------------------------------------------------- /APIs/json.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 JSON 3 | Javascript Object Notation 4 | */ 5 | 6 | /* 7 | - Es un formato que se utiliza para mandar información de un sitio a otro. 8 | - Por ejemplo cuando mandamos obtener informacion de un servidor este nos respondera con un objeto JSON. 9 | - Son muy similares a un objeto de javascript. 10 | - Todos los lenguajes de programación tienen funciones para leer json. 11 | - Es una de las formas mas comunes de pasar información porque es muy fácil de usar. 12 | */ 13 | 14 | /* 15 | 📌 Tipos de datos que podemos usar en JSON: 16 | - cadena de texto 17 | - numeros 18 | - objetos (en formato JSON) 19 | - arreglos 20 | - booleanos 21 | - null 22 | 23 | Tipos de datos que NO podemos usar en JSON: 24 | - funciones 25 | - objetos de fecha 26 | - undefined 27 | */ 28 | 29 | // datos.json 30 | const datos = ` 31 | { 32 | "id": 1, 33 | "nombre": "Carlos Arturo", 34 | "suscriptor_activo": true, 35 | "posts": [ 36 | { 37 | "id": 1, 38 | "titulo": "Titulo del primer post", 39 | "texto": "texto del primer post ..." 40 | }, 41 | { 42 | "id": 2, 43 | "titulo": "Titulo del segundo post", 44 | "texto": "texto del segundo post ..." 45 | } 46 | ] 47 | } 48 | `; 49 | 50 | /* 51 | 📌 parse() 52 | Le pasamos una cadena de texto con formato JSON y nos devuelve objeto de javascript. 53 | */ 54 | console.log(JSON.parse(datos)); 55 | 56 | /* 57 | 📌 stringify() 58 | Nos permite pasarle un objeto de javascript y nos devuelve una cadena de texto con objeto en formato JSON 59 | */ 60 | const usuario = { 61 | nombre: 'Carlos', 62 | correo: 'correo@correo.com', 63 | coloresFavoritos: ['azul', 'rojo', 'negro'], 64 | }; 65 | 66 | console.log(JSON.stringify(usuario)); 67 | -------------------------------------------------------------------------------- /APIs/localstorage.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Localstorage 3 | Localstorage es una API del navegador que nos va a permitir poder 4 | guardar información de forma local, asi como las cookies. 5 | */ 6 | 7 | document.getElementById('boton1').addEventListener('click', () => { 8 | const nombre = prompt('Escribe tu nombre:'); 9 | window.localStorage.setItem('nombre', nombre); 10 | }); 11 | 12 | document.getElementById('boton2').addEventListener('click', () => { 13 | window.localStorage.removeItem('nombre'); 14 | }); 15 | 16 | // Comprobamos si hay un nombre guardado 17 | if (window.localStorage.nombre) { 18 | console.log('Hola', window.localStorage.nombre); 19 | } else { 20 | console.log('Hola usuario anonimo'); 21 | } 22 | 23 | /* 24 | 📌 Local Storage vs cookies 25 | 26 | Local Storage: 27 | - Se utilizan para guardar información de forma local. 28 | - Tiene un limite de 5mb por dominio. 29 | - La información de localstorage no tiene expiración. (se puede borrar con ccleaner por ejemplo) 30 | Cookies: 31 | - Se utilizan para mandar informacion entre el cliente (navegador web) y el servidor 32 | - Tienen un limite de 4kb. 33 | - Pueden tener fecha de expiración. 34 | */ 35 | -------------------------------------------------------------------------------- /BOM/alerts.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Ventanas de Alerta 3 | El navegador web puede mostrar 3 ventanas de alerta mediante javascript 4 | */ 5 | 6 | /* 7 | 📌 Alerta 8 | Para informarle al usuario de algo. 9 | */ 10 | // window.alert('Hola usuario!'); 11 | 12 | /* 13 | 📌 Ventana de confirmación 14 | Una ventana donde el usuario puede aceptar o cancelar. 15 | Retorna verdadero o falso dependiendo de la respuesta del usuario. 16 | */ 17 | 18 | const ingresar = () => { 19 | const accesoPermitido = confirm('¿Eres mayor de edad?'); 20 | if (accesoPermitido) { 21 | alert('Bienvenido!'); 22 | } else { 23 | alert('Le vamos a decir a tus padres!'); 24 | } 25 | }; 26 | 27 | /* 28 | 📌 Ventana con input 29 | Una ventana donde el usuario puede introducir un valor 30 | Retorna una cadena de texto con la respuesta del usuario. 31 | */ 32 | 33 | const saludo = () => { 34 | const nombre = prompt('Escribe tu nombre'); 35 | alert(`Bienvenido ${nombre}`); 36 | }; 37 | -------------------------------------------------------------------------------- /BOM/estilos.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: 'Poppins', sans-serif; 11 | min-height: 100vh; 12 | width: 100%; 13 | background: #eaeaea; 14 | color: #000; 15 | display: flex; 16 | flex-direction: column; 17 | align-items: center; 18 | justify-content: center; 19 | } 20 | 21 | h1 { 22 | font-size: 80px; 23 | } 24 | 25 | h2 { 26 | font-size: 40px; 27 | font-weight: normal; 28 | margin-bottom: 40px; 29 | color: #848484; 30 | } 31 | 32 | button { 33 | border: none; 34 | background: #2553df; 35 | font-family: 'Poppins', sans-serif; 36 | font-size: 22px; 37 | cursor: pointer; 38 | border-radius: 10px; 39 | color: #fff; 40 | padding: 14px 28px; 41 | margin-bottom: 20px; 42 | } 43 | 44 | button:hover { 45 | background: #1942be; 46 | } 47 | -------------------------------------------------------------------------------- /BOM/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso de Javascript 8 | 9 | 10 | 11 | 12 |

Curso de Javascript

13 |

Completo, Práctico y desde Cero

14 | 15 | 16 | -------------------------------------------------------------------------------- /BOM/location.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 window.location 3 | Nos permite obtener la url de la barra de direcciones y cargar nuevos documentos. 4 | Recordar que podemos acceder a location directamente. 5 | */ 6 | 7 | // href - Retorna la URL de la página actual 8 | console.log(location.href); 9 | 10 | // hostname - Retorna el host de la página actual 11 | // Abriendo el archivo local nos retorna undefined pero podemos probar desde la consola en otra pagina. 12 | console.log(location.hostname); 13 | 14 | // pathname - Retorna la ruta y archivo de la pagina actual 15 | console.log(location.pathname); 16 | 17 | // procotol - Retorna el protocolo utilizado 18 | console.log(location.protocol); 19 | 20 | // assign - Nos permite cargar un nuevo documento 21 | const cargarDocumento = () => { 22 | location.assign('https://google.com'); 23 | }; 24 | 25 | /* 26 | 📌 window.history 27 | Contiene el historial de la pestaña de nuestro navegador. 28 | Nos permite regresar o ir adelante. 29 | */ 30 | 31 | const regresar = () => { 32 | history.back(); 33 | // history.forward(); 34 | }; 35 | -------------------------------------------------------------------------------- /BOM/navigator.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 window.navigator 3 | Contiene informacion del navegador web del usuario 4 | */ 5 | 6 | // Comprobar si las cookies estan activadas 7 | console.log('Cookies activadas:', navigator.cookieEnabled); 8 | 9 | //Obtener el encabezado que el navegador envia. 10 | /* 11 | Nota: No utilizarlo para detectar el navegador del usuario: 12 | - Ya que varios navegadores pueden usar el mismo encabezado 13 | - Y se puede editar manualmente 14 | */ 15 | console.log(navigator.userAgent); 16 | 17 | // Obtener el lenguaje del navegador web del usuario 18 | console.log(navigator.language); 19 | 20 | // Obtener si el navegador web esta conectado a internet 21 | console.log(navigator.onLine); 22 | -------------------------------------------------------------------------------- /BOM/timers.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Eventos de Tiempo 3 | El Browser Object Model tambien nos da acceso a eventos de tiempo que nos permitiran 4 | ejecutar código cada cierto tiempo. 5 | 6 | Tenemos 2 metodos disponibles para trabajar con tiempo: 7 | - setTimeOut 8 | - setInterval 9 | */ 10 | 11 | /* 12 | 📌 window.setTimeOut() 13 | Nos permite ejecutar una funcion despues de cierto tiempo. 14 | */ 15 | 16 | // const saludo = () => { 17 | // console.log('Hola!'); 18 | // }; 19 | 20 | // const iniciar = () => { 21 | // console.log('Iniciando Timer'); 22 | // setTimeout(saludo, 5000); 23 | // }; 24 | 25 | /* 26 | setTimeout nos devuelve un un id para identificar el temporizador. 27 | Podemos guardar ese id y luego utilizarlo para limpiar el temporizador. 28 | */ 29 | // let id; 30 | // const iniciar = () => { 31 | // console.log('Iniciamos el timeout'); 32 | // id = setTimeout(() => { 33 | // console.log('Hola!'); 34 | // }, 5000); 35 | 36 | // // Podemos acortarlo: 37 | // // setTimeout(() => console.log('Saludos Carlos!'), 1000); 38 | // }; 39 | 40 | // const parar = () => { 41 | // console.log('Paramos la ejecución del timeout'); 42 | // clearTimeout(id); 43 | // }; 44 | 45 | /* 46 | 📌 window.setInterval() 47 | Nos permite ejecutar una funcion cada cierto tiempo. 48 | */ 49 | let cuenta = 0; 50 | let id; 51 | 52 | const iniciar = () => { 53 | id = setInterval(() => { 54 | cuenta++; 55 | console.log(cuenta); 56 | }, 1000); 57 | }; 58 | 59 | const parar = () => { 60 | console.log('Paramos la cuenta'); 61 | clearInterval(id); 62 | }; 63 | -------------------------------------------------------------------------------- /BOM/window.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 El Browser Object Model nos permite poder acceder a propiedades y metodos del navegador web. 3 | Ejemplos de cosas que nos permite hacer: 4 | - Acceder a la ventana para conocer su tamaño 5 | - Trabajar con la barra de direcciones 6 | - Mostrar alertas 7 | - etc 8 | */ 9 | 10 | /* 11 | 📌 Window Object 12 | Representa la ventana del navegador. 13 | Las variables y funciones globales son parte del objeto de window 14 | */ 15 | 16 | // Accediendo al metodo alerta de Window 17 | // window.alert(); 18 | 19 | // Funcion global 20 | // alert(); 21 | 22 | // Podemos conocer todas las propiedades y metodos 23 | // console.log(window); 24 | 25 | // Esto no incluye las barras de herramientas, marcadores, barras de scroll 26 | console.log(`La ventana de tu navegador mide ${window.innerWidth}px de ancho.`); 27 | console.log(`La ventana de tu navegador mide ${window.innerHeight}px de alto.`); 28 | 29 | /* 30 | 📌 Trabajar con ventanas 31 | Con el BOM podemos: 32 | - Abrir y cerrar ventanas. 33 | - Mover ventanas. 34 | - Cambiar el tamaño de ventanas. 35 | */ 36 | 37 | /* 38 | 📌 window.open() 39 | Nos permite abrir ventanas del navegador 40 | Nota: Es posible que el navegador te pida permisos para abrir una nueva ventana. 41 | 42 | - 1er parametro: Dirección de la nueva ventana 43 | - 2do parametro: Nombre de la ventana 44 | - 3er parametro: Cadena de texto de opciones 45 | 46 | Nos devuelve un objeto para aceder a esa ventana 47 | */ 48 | let ventana; 49 | const abrirVentana = () => { 50 | ventana = window.open('', '', 'width=500,height=500'); 51 | ventana.document.write('Hola, escribiendo en la nueva ventana!'); 52 | 53 | /* 📌 Podemos abrir pestañas */ 54 | // window.open('https://google.com'); 55 | }; 56 | 57 | /* 58 | 📌 Cerramos una ventana 59 | Nota: Solo podemos cerrar ventanas que hayan sido abriertas por un script. 60 | */ 61 | const cerrarVentana = () => { 62 | ventana.close(); 63 | }; 64 | 65 | /* 66 | 📌 Screen Object 67 | Representa la pantalla del usuario. 68 | */ 69 | 70 | // Alto y ancho de pantalla 71 | console.log('Ancho de pantalla:', window.screen.width); 72 | console.log('Alto de pantalla:', window.screen.height); 73 | 74 | // Alto y ancho de pantalla sin contar la barra de windows 75 | console.log('Ancho de pantalla sin barra de Windows:', window.screen.availWidth); 76 | console.log('Alto de pantalla sin barra de windows:', window.screen.availHeight); 77 | -------------------------------------------------------------------------------- /DOM/creandoElementos.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Agregando elementos al DOM 3 | 4 | Pasos a seguir: 5 | 1. Crear un elemento del DOM 6 | 2. Agregarle texto y atributos 7 | 3. Insertar el elemento dentro del DOM 8 | */ 9 | 10 | const agregarCaja = () => { 11 | /* 12 | 📌 1. Creamos el elemento 13 | createElement - Recibe como parametro una cadena de texto con la etiqueta que queremos crear. 14 | */ 15 | const nuevaCaja = document.createElement('div'); 16 | 17 | /* 18 | 📌 2. Agregamos texto y atributos 19 | */ 20 | // nuevaCaja.innerHTML = 'Nuevo texto!'; 21 | nuevaCaja.innerText = 'Nueva caja!'; 22 | nuevaCaja.setAttribute('id', 'nuevo-id'); 23 | nuevaCaja.setAttribute('class', 'caja activa'); 24 | 25 | /* 26 | 📌 3. Agregamos el elemento al DOM 27 | */ 28 | const contenedor = document.getElementById('contenedor1'); 29 | 30 | // .appendChild() - Agrega un elemento al final 31 | // contenedor.appendChild(nuevaCaja); 32 | 33 | /* .insertAdjacentElement() - Nos permite agregar un elemento 34 | Valores: 35 | afterbegin - como primer elemento 36 | beforebegin - antes del elemento padre 37 | beforeend - como ultimo elemento 38 | afterend - despues del elemento padre 39 | */ 40 | // contenedor.insertAdjacentElement('beforeend', nuevaCaja); 41 | 42 | // .replaceWith() - Nos permite remplazar el elemento por otro 43 | document.querySelector('#contenedor1 .caja').replaceWith(nuevaCaja); 44 | }; 45 | -------------------------------------------------------------------------------- /DOM/delegacionDeEventos.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Delegación de Eventos 3 | Gracias a la propagacion de eventos podemos evitar agregar un eventListener por cada elemento que tengamos, 4 | y agregar solamente un eventListener al elemento padre y que decida ejecutar código o no. 5 | */ 6 | 7 | /* 8 | 📌 Ejemplo sin delegación de eventos. 9 | Tenemos que agregar un evento por cada caja. 10 | Si tenemos muchas cajas esto puede ser un problema de rendimiento. 11 | 12 | Ademas de que tendremos problemas si hay elementos que son agregados o eliminados de forma dinamica. 13 | */ 14 | // const cajas = document.querySelectorAll('.caja'); 15 | // cajas.forEach((caja) => { 16 | // caja.addEventListener('click', (e) => { 17 | // console.log(`Click en la caja ${e.target.innerText}`); 18 | // }); 19 | // }); 20 | 21 | /* 22 | 📌 Ejemplo con delegación de eventos. 23 | Agregamos solo un evento al contenedor padre. 24 | Al ser solo un evento es más optimo. 25 | 26 | Al trabajar con delegación de eventos no nos preocupamos 27 | si hay elementos que son agregados o eliminados de forma dinamica 28 | */ 29 | const contenedorPadre = document.getElementById('contenedor1'); 30 | contenedorPadre.addEventListener('click', (e) => { 31 | // console.log('Ejecuta!'); 32 | // Ejecuta si hacemos click en el contenedor o en los elementos hijos. 33 | 34 | // if (e.target.classList.contains('caja')) { 35 | // // Ejecuta solo si el elemento que fue clickeado tiene la clase caja. 36 | // console.log(`Hiciste click en la caja ${e.target.innerText}`); 37 | // } 38 | 39 | /* 40 | 📌 .matches() 41 | Con matches tambien podemos comprobar que el elemento tenga la clase caja. 42 | Con matches tenemos mas flexibilidad. 43 | */ 44 | if (e.target.matches('div.caja')) { 45 | // Ejecuta solo si el elemento que fue clickeado tiene la clase caja. 46 | console.log(`Hiciste click en la caja ${e.target.innerText}`); 47 | } 48 | }); 49 | -------------------------------------------------------------------------------- /DOM/eliminandoElementos.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Eliminar elementos del DOM 3 | */ 4 | 5 | const eliminarCaja = () => { 6 | const cajaAEliminar = document.querySelector('#contenedor1 .caja'); 7 | 8 | if (cajaAEliminar) { 9 | const padre = cajaAEliminar.parentElement; 10 | padre.removeChild(cajaAEliminar); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /DOM/eliminarEventos.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Eliminar eventos de un elemento 3 | */ 4 | 5 | const boton1 = document.getElementById('boton1'); 6 | const boton2 = document.getElementById('boton2'); 7 | const primeraCaja = document.querySelector('.caja'); 8 | 9 | const toggleClase = () => { 10 | primeraCaja.classList.toggle('activa'); 11 | }; 12 | 13 | // Click boton 1 14 | boton1.addEventListener('click', () => { 15 | // Agregamos el evento 16 | primeraCaja.addEventListener('click', toggleClase); 17 | }); 18 | 19 | // Click boton 2 20 | boton2.addEventListener('click', () => { 21 | // Eliminamos el evento 22 | primeraCaja.removeEventListener('click', toggleClase); 23 | }); 24 | -------------------------------------------------------------------------------- /DOM/estilos.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: 'Poppins', sans-serif; 11 | min-height: 100vh; 12 | width: 100%; 13 | background: #eaeaea; 14 | color: #000; 15 | display: flex; 16 | flex-direction: column; 17 | align-items: center; 18 | justify-content: center; 19 | } 20 | 21 | .contenedor-principal { 22 | width: 90%; 23 | max-width: 1000px; 24 | display: grid; 25 | grid-template-columns: 1fr 1fr; 26 | gap: 40px; 27 | } 28 | 29 | .contenedor { 30 | display: grid; 31 | gap: 40px; 32 | padding: 40px; 33 | border: 2px solid #000; 34 | } 35 | 36 | .caja { 37 | background: #fcfcfc; 38 | padding: 40px; 39 | font-size: 24px; 40 | box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px; 41 | display: flex; 42 | align-items: center; 43 | justify-content: center; 44 | } 45 | 46 | .caja.activa { 47 | background: #2553df; 48 | color: #fff; 49 | } 50 | 51 | button { 52 | border: none; 53 | background: #2553df; 54 | font-family: 'Poppins', sans-serif; 55 | font-size: 22px; 56 | cursor: pointer; 57 | border-radius: 10px; 58 | color: #fff; 59 | padding: 14px 28px; 60 | margin-bottom: 20px; 61 | } 62 | 63 | button:hover { 64 | background: #1942be; 65 | } 66 | -------------------------------------------------------------------------------- /DOM/eventos.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Eventos 3 | Los eventos en Javascript nos permiten reaccionar a cosas que ocurren en la página web 4 | Como por ejemplo reaccionar cuando: 5 | - la página termina de cargar 6 | - el usuario da click a un boton 7 | - pasa el mouse arriba de un elemento 8 | - escribe en un campo de texto 9 | - envia un formulario 10 | - etc. 11 | 12 | Hay cientos de eventos a los que podemos reaccionar: 13 | https://developer.mozilla.org/en-US/docs/Web/Events#event_listing 14 | */ 15 | 16 | /* 17 | 📌 Eventos como atributo de elementos HTML 18 | Podemos agregar algunos eventos como atributo de un elemento HTML 19 | Ejemplo: 20 | 21 | 22 | */ 23 | // const toggleClase = () => { 24 | // const caja = document.querySelector('.caja'); 25 | // caja.classList.toggle('activa'); 26 | // }; 27 | 28 | /* 29 | 📌 Event Listener 30 | Una mejor forma de trabajar con eventos es agregando un listener. 31 | Un listener nos permitira vigilar cuando se ejecute un evento sin tener que ensuciar el código HTML. 32 | */ 33 | const boton1 = document.getElementById('boton1'); 34 | const primeraCaja = document.querySelector('.caja'); 35 | boton1.addEventListener('click', () => { 36 | primeraCaja.classList.toggle('activa'); 37 | }); 38 | 39 | /* 40 | 📌 Agregando el evento a multiples elementos 41 | Podemos agregar el evento a multiples elementos recorriendolos mediante un ciclo. 42 | Nota: Esta no es la forma mas optima, en la proxima clase veremos una mejor forma. 43 | */ 44 | // const cajas = document.querySelectorAll('.caja'); 45 | // cajas.forEach((caja) => { 46 | // caja.addEventListener('click', () => { 47 | // console.log('Haz hecho click en una caja'); 48 | // }); 49 | // }); 50 | 51 | /* 52 | 📌 Accediendo a información del evento 53 | Cuando trabajamos con eventListener, la funcion que le pasamos puede recibir como parametro el propio evento 54 | Este objeto contendra mucha informacion del evento. 55 | */ 56 | // const segundaCaja = document.querySelectorAll('.caja')[1]; 57 | // segundaCaja.addEventListener('click', (evento) => { 58 | // console.log(evento); 59 | // console.log(evento.target.innerText); 60 | // }); 61 | 62 | // Ejemplo con todas las cajas 63 | // const cajas = document.querySelectorAll('.caja'); 64 | // cajas.forEach((caja) => { 65 | // caja.addEventListener('click', (e) => { 66 | // console.log(`Haz hecho click en ${e.target.innerText}`); 67 | // }); 68 | // }); 69 | -------------------------------------------------------------------------------- /DOM/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Document Object Model 10 | 11 | 12 |
13 |
14 |
Caja 1
15 |
Caja 2
16 |
Caja 3
17 |
18 |
19 |
Caja 1
20 |
Caja 2
21 |
Caja 3
22 |
23 | 24 | 25 | 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /DOM/introduccion.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Document Object Model 3 | El DOM es un objeto que el navegador web hace cuando carga una página. 4 | El DOM contiene toda la estructura de una página web. 5 | 6 | Con el DOM podemos: 7 | • Agregar, Eliminar y Editar todos los elementos de la página junto con sus atributos. 8 | • Cambiar los estilos CSS de la página. 9 | • Reaccionar a eventos que ocurran en la página. 10 | 11 | El DOM ademas agrega propiedades, metodos y eventos a los elementos HTML. 12 | 13 | Gracias al DOM podemos trabajar con los elementos de una página web de forma dinamica. 14 | */ 15 | -------------------------------------------------------------------------------- /DOM/modificandoElementos.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 A los elementos del DOM que obtenemos, Javascript les 3 | agrega metodos y propiedades que nos permitiran modificarlos. 4 | */ 5 | 6 | /* 📌 elemento.innerHTML 7 | Nos permite cambiar el contenido HTML de un elemento 8 | */ 9 | const primeraCaja = document.querySelectorAll('.caja')[0]; 10 | primeraCaja.innerHTML = 'Hola!'; 11 | 12 | /* 📌 elemento.attribute 13 | Nos permite acceder y cambiar atributos del elemento. 14 | */ 15 | primeraCaja.id = 'nuevoId'; 16 | 17 | /* 📌 elemento.setAttribute() 18 | Nos permite agregar o establecer el valor de un atributo del elemento 19 | */ 20 | primeraCaja.setAttribute('class', 'caja activa'); 21 | primeraCaja.setAttribute('data-id', 1); 22 | console.log(primeraCaja); 23 | 24 | /* 📌 elemento.style.property 25 | Nos permite cambiar los estilos css de un elemento 26 | */ 27 | const contenedor2Caja1 = document.querySelector('#contenedor2 .caja'); 28 | contenedor2Caja1.style.background = '#000'; 29 | contenedor2Caja1.style.color = '#fff'; 30 | contenedor2Caja1.style.textTransform = 'uppercase'; 31 | -------------------------------------------------------------------------------- /DOM/modificandoEstilosMedianteClases.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Podemos modificar los estilos CSS de un elemento de dos formas: 3 | - Agregando y quitando clases CSS 4 | - Modificando los estilos "inline" de cada elemento. 5 | */ 6 | 7 | /* 8 | 📌 Modificar estilos CSS mediante clases 9 | */ 10 | const primeraCaja = document.querySelector('#contenedor1 .caja'); 11 | 12 | // classList - Nos permite obtener una lista de las clases del elemento 13 | console.log(primeraCaja.classList); 14 | 15 | // classList.add() - Nos permite agregar clases a un elemento. 16 | const agregarClase = () => { 17 | primeraCaja.classList.add('activa'); 18 | }; 19 | 20 | // classList.remove() - Nos permite eliminar clases de un elemento 21 | const eliminarClase = () => { 22 | primeraCaja.classList.remove('activa'); 23 | }; 24 | 25 | // classList.toggle() - Nos permite alternar clases de un elemento 26 | const toggleClase = () => { 27 | primeraCaja.classList.toggle('activa'); 28 | }; 29 | 30 | // classList.contains() - Nos permite comprobar si el elemento contiene una clase 31 | const comprobarClase = () => { 32 | if (primeraCaja.classList.contains('activa')) { 33 | console.log('La caja tiene la clase "activa"'); 34 | } else { 35 | console.log('La caja no tiene la clase "activa"'); 36 | } 37 | 38 | console.log('y contiene las siguientes clases:'); 39 | // classList.forEach() - Nos permite iterar sobre cada clase 40 | primeraCaja.classList.forEach((clase) => { 41 | console.log(clase); 42 | }); 43 | }; 44 | -------------------------------------------------------------------------------- /DOM/modificandoEstilosMedianteJs.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Podemos modificar los estilos CSS de un elemento de dos formas: 3 | - Agregando y quitando clases CSS 4 | - Modificando los estilos "inline" de cada elemento. 5 | */ 6 | 7 | /* 8 | 📌 Modificar estilos CSS mediante "inline styles". 9 | */ 10 | /* 11 | Los estilos inline se aplican arriba de los estilos que podamos tener en archivos CSS. 12 | Estos estilos se agregan en el atributo style del elemento. 13 | */ 14 | const ultimaCaja = document.querySelector('#contenedor2 .caja:last-child'); 15 | 16 | ultimaCaja.style.background = '#000'; 17 | ultimaCaja.style.color = '#fff'; 18 | 19 | /* 20 | 📌 La ventaja de trabajar con estilos inline es que podemos modificar los estilos de forma dinamica. 21 | */ 22 | const cajas = document.querySelectorAll('.caja'); 23 | let tamaño = 24; 24 | const incrementarFuente = () => { 25 | cajas.forEach((caja) => { 26 | caja.style.fontSize = `${tamaño + 1}px`; 27 | tamaño++; 28 | }); 29 | }; 30 | 31 | const disminuirFuente = () => { 32 | cajas.forEach((caja) => { 33 | if (tamaño > 8) { 34 | caja.style.fontSize = `${tamaño - 1}px`; 35 | tamaño--; 36 | } 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /DOM/propagacionDeEventos.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Propagación de eventos 3 | Nota importante: 4 | Cuando agregamos un evento a un elemento, todos los elementos que esten dentro del que recibio el evento 5 | tambien recibiran el mismo evento. 6 | 7 | Es decir que si le aplicamos un evento a un contenedor padre, todos los hijos tendran tambien el evento. 8 | */ 9 | const contenedor = document.getElementById('contenedor1'); 10 | contenedor.addEventListener('click', (e) => { 11 | console.log('Hiciste click en el contenedor'); 12 | }); 13 | 14 | primeraCaja.addEventListener('click', (e) => { 15 | // Podemos evitar la propagación: 16 | e.stopPropagation(); 17 | 18 | console.log('Hiciste click en la caja1'); 19 | }); 20 | -------------------------------------------------------------------------------- /DOM/tiposDePropagacion.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Cuando agregamos un evento a un elemento ese evento se propaga a los elementos hijo. 3 | */ 4 | /* 5 | 📌 Bubbling (false, por defecto) 6 | En bubbling el evento del elemento hijo reacciona primero y despues el evento del elemento padre. 7 | 8 | 📌 Capturing (true) 9 | En capturing el elemento padre reacciona primero y despues el elemento hijo. 10 | */ 11 | document.querySelector('.contenedor').addEventListener( 12 | 'click', 13 | () => { 14 | console.log('Click en el contenedor'); 15 | }, 16 | false // Solo es necesario ponerlo en el elemento padre. 17 | ); 18 | 19 | document.querySelector('.caja').addEventListener('click', () => { 20 | console.log('Click en la caja'); 21 | }); 22 | 23 | /* 24 | 📌 Capturing 25 | En capturing el elemento padre reacciona primero y despues el elemento hijo. 26 | */ 27 | document.querySelector('.contenedor').addEventListener( 28 | 'click', 29 | () => { 30 | console.log('Click en el contenedor'); 31 | }, 32 | true 33 | ); 34 | 35 | document.querySelector('.caja').addEventListener('click', () => { 36 | console.log('Click en la caja'); 37 | }); 38 | -------------------------------------------------------------------------------- /Extras/debugging.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Debugging con javascript 3 | 4 | Hacer debugging significa encontrar errores que podamos tener en nuestra aplicación. 5 | Existen varias formas de hacerlo: 6 | 7 | - mediante mensajes de consola como console.log(), 8 | - mediante las herramientas de desarrollador del navegador web 9 | - breakpoints 10 | - palabra "debugger" 11 | */ 12 | 13 | const usuario = { 14 | nombre: '', 15 | edad: 0, 16 | acceso_permitido: true, 17 | }; 18 | 19 | // Registramos los datos del usuario 20 | document.getElementById('boton1').addEventListener('click', () => { 21 | usuario.nombre = prompt('Ingresa tu nombre'); 22 | 23 | /* 24 | 📌 Mediante consola 25 | */ 26 | console.log(usuario); 27 | 28 | /* 29 | 📌 Mediante palabra debugger 30 | */ 31 | // debugger; 32 | 33 | /* 34 | 📌 Mediante breakpoint 35 | */ 36 | 37 | usuario.edad = prompt('Ingresa tu edad'); 38 | 39 | if (usuario.edad >= 18) { 40 | acceso_permitido = true; 41 | } else { 42 | acceso_permitido = false; 43 | } 44 | }); 45 | -------------------------------------------------------------------------------- /Extras/estilos.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: 'Poppins', sans-serif; 11 | min-height: 100vh; 12 | width: 100%; 13 | background: #eaeaea; 14 | color: #000; 15 | display: flex; 16 | flex-direction: column; 17 | align-items: center; 18 | justify-content: center; 19 | } 20 | 21 | h1 { 22 | font-size: 80px; 23 | } 24 | 25 | h2 { 26 | font-size: 40px; 27 | font-weight: normal; 28 | margin-bottom: 40px; 29 | color: #848484; 30 | } 31 | 32 | button { 33 | border: none; 34 | background: #2553df; 35 | font-family: 'Poppins', sans-serif; 36 | font-size: 22px; 37 | cursor: pointer; 38 | border-radius: 10px; 39 | color: #fff; 40 | padding: 14px 28px; 41 | margin-bottom: 20px; 42 | } 43 | 44 | button:hover { 45 | background: #1942be; 46 | } 47 | -------------------------------------------------------------------------------- /Extras/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso de Javascript 8 | 9 | 10 | 11 | 12 |

Curso de Javascript

13 |

Completo, Práctico y desde Cero

14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Extras/maps.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Maps 3 | Los mapas en javascript son como los objetos pero en donde 4 | las llaves (propiedades) pueden ser de cualquier tipo, incluyendo objetos. 5 | */ 6 | 7 | const correo = { 8 | correo: 'correo@correo.com', 9 | }; 10 | 11 | const mapa = new Map([ 12 | ['nombre', 'Carlos'], 13 | [true, 'verdadero'], 14 | [ 15 | correo, 16 | { 17 | password: '123', 18 | }, 19 | ], 20 | ]); 21 | 22 | // console.log(mapa); 23 | 24 | // Obtener un valor 25 | // console.log(mapa.get('nombre')); 26 | // console.log(mapa.get(true)); 27 | // console.log(mapa.get(correo)); 28 | 29 | // Los mapas tambien tienen un metodo foreach 30 | // En los mapas primero va el valor y luego la propiedad 31 | mapa.forEach((valor, propiedad) => console.log(valor, propiedad)); 32 | -------------------------------------------------------------------------------- /Extras/sets.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Sets 3 | Los sets son una especie de arreglo que pero solo puede contener valores unicos. 4 | */ 5 | 6 | // Crear un set 7 | const colores = new Set(['rojo', 'verde', 'azul']); 8 | 9 | // Agregar valores al set 10 | colores.add('amarillo'); 11 | 12 | // Si intentamos agregar un valor repetido al set, este no se agregara 13 | colores.add('amarillo'); 14 | console.log(colores); 15 | 16 | // Set tambien tiene el metodo forEach para recorrer los elementos 17 | colores.forEach((color) => console.log(color)); 18 | 19 | // Los set pueden contener cualquier tipo de dato. 20 | const numeros = new Set([1, 2, 3, 4, 4, 4, 5]); 21 | console.log(numeros); 22 | -------------------------------------------------------------------------------- /Extras/this.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Palabra reservada "this" 3 | La palabra "this" representa algo diferente dependiendo de donde se utiliza. 4 | */ 5 | 6 | /* 7 | 📌 Fuera de cualquier bloque, representa el objeto global (window) 8 | */ 9 | console.log(this); 10 | 11 | /* 12 | 📌 Dentro de una funcion se, representa el objeto global. 13 | */ 14 | const miFuncion = () => { 15 | console.log(this); 16 | }; 17 | miFuncion(); 18 | 19 | /* 20 | 📌 En un evento se refiere al elemento que recibio el evento 21 | 22 | Nota: Solo cuando la función no es de tipo flecha 23 | Si es una funcion de tipo flecha se referira al objeto global. 24 | */ 25 | document.getElementById('boton1').addEventListener('click', function () { 26 | console.log(this); 27 | }); 28 | 29 | /* 30 | 📌 En un metodo, representa el objeto 31 | */ 32 | class Usuario { 33 | constructor(nombre) { 34 | this.nombre = nombre; 35 | console.log(this); 36 | } 37 | 38 | miMetodo() { 39 | console.log(this); 40 | } 41 | } 42 | 43 | const nuevoUsuario = new Usuario('carlos'); 44 | nuevoUsuario.miMetodo(); 45 | -------------------------------------------------------------------------------- /Formularios/estilos.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: 'Poppins', sans-serif; 11 | min-height: 100vh; 12 | width: 100%; 13 | background: #eaeaea; 14 | color: #000; 15 | display: flex; 16 | flex-direction: column; 17 | align-items: center; 18 | justify-content: center; 19 | } 20 | 21 | .contenedor { 22 | width: 90%; 23 | max-width: 1000px; 24 | } 25 | 26 | form { 27 | display: flex; 28 | flex-direction: column; 29 | align-items: center; 30 | gap: 20px; 31 | } 32 | 33 | form { 34 | font-size: 20px; 35 | } 36 | 37 | input { 38 | font-size: 18px; 39 | padding: 10px; 40 | } 41 | 42 | select { 43 | padding: 10px; 44 | font-size: 18px; 45 | } 46 | 47 | button { 48 | border: none; 49 | background: #2553df; 50 | font-family: 'Poppins', sans-serif; 51 | font-size: 22px; 52 | cursor: pointer; 53 | border-radius: 10px; 54 | color: #fff; 55 | padding: 14px 28px; 56 | margin-bottom: 20px; 57 | } 58 | 59 | button:hover { 60 | background: #1942be; 61 | } 62 | -------------------------------------------------------------------------------- /Formularios/expresionesRegulares.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Expresiones Regulares dentro de formularios 3 | Podemos usar expresiones regulares para validar los campos de una forma más precisa. 4 | 5 | Guía de expresiones regulares: 6 | https://www.youtube.com/watch?v=wfogZfIS03U 7 | 8 | Ejemplo: 9 | https://regexr.com/71ua4 10 | */ 11 | const formulario = document.forms['formulario-donacion']; 12 | formulario.addEventListener('submit', (e) => { 13 | e.preventDefault(); 14 | 15 | const correo = formulario.correo.value; 16 | const expresionRegular = /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/; 17 | 18 | /* 19 | El metodo test lo podemos aplicar sobre una expresion regular 20 | Nos devuelve true o false dependiendo de si paso la prueba 21 | */ 22 | 23 | if (!expresionRegular.test(correo)) { 24 | console.log('El correo es invalido'); 25 | return; 26 | } 27 | 28 | console.log('Enviando datos'); 29 | console.log(correo); 30 | }); 31 | -------------------------------------------------------------------------------- /Formularios/formularios.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Formularios 3 | 4 | Tenemos dos formas de acceder a los formularios. 5 | - Mediante el objeto forms 6 | - Mediante métodos del DOM 7 | */ 8 | 9 | /* 10 | 📌 Mediante el objeto forms 11 | */ 12 | /* 13 | El objeto forms contiene los formularios del documento. 14 | Podemos acceder a cada uno mediante su id 15 | Tambien podemos acceder a los inputs mediante su id o name 16 | console.log(document.forms['formulario-donacion']['correo']); 17 | 18 | /* 19 | 📌 Mediante métodos del DOM 20 | */ 21 | const correo = document.querySelector('#formulario-donacion [name="correo"]'); 22 | 23 | /* 24 | 📌 Cada input tiene propiedades a las que podemos acceder 25 | para obtener sus atributos, valores, etc. 26 | */ 27 | const botonEnviar = document.getElementById('btnEnviar').addEventListener('click', (e) => { 28 | // Prevenimos el comportamiento por defecto del boton. 29 | // Por defecto los botones dentro de una etiqueta
intentaran enviar los datos 30 | // mediante una petición POST a la propia página y como parametros en la barra de direcciones. 31 | // e.preventDefault(); 32 | 33 | // Obtener el valor de un input 34 | console.log(correo.value); 35 | console.log(document.forms['formulario-donacion']['pais'].value); 36 | 37 | // Podemos ahorrarnos codigo 38 | const formulario = document.forms['formulario-donacion']; 39 | 40 | console.log(formulario['donacion'].value); 41 | 42 | // formulario es un objeto asi que podemos acceder tambien de esta forma: 43 | console.log(formulario.fecha.value); 44 | 45 | // Para elementos que tengan un guion si tenemos que usar brackets 46 | console.log(formulario['terminos-y-condiciones'].checked); 47 | }); 48 | -------------------------------------------------------------------------------- /Formularios/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Trabajando con Formularios 10 | 11 | 12 |
13 | 14 | 15 | 21 | 25 | 29 | 30 | 34 | 35 | 36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /Formularios/validarFormularios.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Validación de formularios 3 | */ 4 | const formulario = document.getElementById('formulario-donacion'); 5 | 6 | formulario.addEventListener('submit', (e) => { 7 | e.preventDefault(); 8 | 9 | const datos = { 10 | correo: formulario.correo.value, 11 | pais: formulario.pais.value, 12 | donacion: formulario.donacion.value, 13 | fecha: formulario.fecha.value, 14 | terminos: formulario['terminos-y-condiciones'].checked, 15 | }; 16 | 17 | // Comprobamos correo 18 | if (datos.correo.length <= 2) { 19 | console.log('Correo invalido'); 20 | return; 21 | } 22 | 23 | // Comprobamos el país 24 | if (datos.pais === '') { 25 | console.log('País invalido'); 26 | return; 27 | } 28 | 29 | // Comprobamos la cantidad de donación 30 | if (datos.donacion === '') { 31 | console.log('Selecciona una cantidad a donar'); 32 | return; 33 | } 34 | 35 | if (datos.fecha === '') { 36 | console.log('Selecciona una fecha'); 37 | return; 38 | } 39 | 40 | if (!datos.terminos) { 41 | console.log('Acepta los terminos y condiciones'); 42 | return; 43 | } 44 | 45 | console.log('Enviando datos...'); 46 | console.log(datos); 47 | }); 48 | -------------------------------------------------------------------------------- /Introducción/arreglos.js: -------------------------------------------------------------------------------- 1 | /* 📌 Los arreglos son variables que nos permiten guardar multiples valores 2 | Cada valor puede ser de cualquier tipo. 3 | */ 4 | const arreglo = ['Texto', 456, true, { propiedad: 'valor' }, [0, 1, 2, 3]]; 5 | console.log(arreglo); 6 | 7 | // Podemos acceder a los elementos del arreglo en base a su posicion. 8 | // Empezando por el 0 (index) 9 | const amigos = ['Alejandro', 'Manuel', 'Cesar']; 10 | console.log(amigos[0]); 11 | 12 | /* 📌 Otra forma de trabajar con arreglos es definirlo y luego llenarlo */ 13 | const colores = []; 14 | colores[0] = 'Rojo'; 15 | colores[1] = 'Verde'; 16 | 17 | // Podemos saltarnos elementos 18 | colores[3] = 'Blanco'; 19 | 20 | // Podemos sobreescribir valores 21 | colores[3] = 'Amarillo'; 22 | 23 | /* Los arreglos dentro de javascript son objetos. 24 | Esto es porque javascript les agrega una capa de propiedades y metodos. 25 | */ 26 | // Propiedad length, nos permite conocer cuantos elementos tiene un arreglo. 27 | console.log('El arreglo colores tiene: ' + colores.length + ' colores'); 28 | 29 | // Metodo push, nos permite agregar elementos al final del arreglo. 30 | colores.push('Azul'); 31 | console.log(colores); 32 | -------------------------------------------------------------------------------- /Introducción/asyncAwait.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Async y Await 3 | Son sentencias que nos permitiran poder trabajar con codigo asíncrono 4 | de una forma mas sencilla. 5 | 6 | Async - nos permite definir que dentro de una funcion trabajaremos con codigo asyncrono. 7 | Await - nos permite detener la ejecución de codigo y esperar a que se resuelva una promesa. 8 | */ 9 | 10 | // Ejemplo anterior de una funcion que devuelve una promesa (Sin Async/Await) 11 | const fetchPosts = () => { 12 | return new Promise((resolve, reject) => { 13 | setTimeout(() => { 14 | const posts = ['Post 1', 'Post 2', 'Post 3']; 15 | const error = false; 16 | 17 | if (error) { 18 | reject('Hubo un error al intentar obtener los posts'); 19 | } else { 20 | resolve(posts); 21 | } 22 | }, 2000); 23 | }); 24 | }; 25 | 26 | // Obtentiendo los posts (con then y catch) 27 | // obtenerPosts() 28 | // .then((posts) => { 29 | // console.log(posts); 30 | // }) 31 | // .catch((error) => { 32 | // console.log(error); 33 | // }); 34 | 35 | // Obtentiendo los posts (con async y catch) 36 | const mostrarPosts = async () => { 37 | // Sin TRY / CATCH 38 | // const posts = await fetchPosts(); 39 | // console.log(posts); 40 | 41 | // CON TRY / CATCH 42 | // Si la promesa se rechazo y queremos obtener el error podemos trabajar con try catch. 43 | try { 44 | const posts = await fetchPosts(); 45 | console.log(posts); 46 | } catch (error) { 47 | console.log(error); 48 | } 49 | }; 50 | 51 | obtenerPosts(); 52 | -------------------------------------------------------------------------------- /Introducción/breakContinue.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Break 3 | La sentencia break nos sirve para salir de bloques de tipo Switch. 4 | Pero tambien nos sirve para forzar la salida de un ciclo. 5 | */ 6 | 7 | // Lista de nombres que empieza por la A 8 | const nombres = ['Arturo', 'Andres', 'Alejandro', 'Roberto', 'Adrian', 'Antonio', 'Angel']; 9 | 10 | // Comprobamos que todos los nombres empiecen por A 11 | for (let i = 1; i < nombres.length; i++) { 12 | // console.log(nombres[i][0]); // Accedemos a la primera letra de cada nombre. 13 | // console.log(); 14 | 15 | // Detectamos si alguna letra es diferente a A 16 | if (nombres[i][0] !== 'A') { 17 | // Cortamos la ejecución del ciclo 18 | console.log('ALTO! Hay un nombre que no empieza por la letra A'); 19 | // console.log(nombres[i] + ' no empieza por la letra A'); 20 | break; 21 | } 22 | 23 | console.log(nombres[i]); 24 | } 25 | 26 | /* 27 | 📌 Continue 28 | La sentencia continue nos sirve para saltar a la siguiente iteración. 29 | */ 30 | 31 | const invitados = ['Carlos', 'Christian', 'Christoher', 'Jorge', 'Estefania', 'Erika', 'Manuel']; 32 | // Recorremos el arreglo de invitados 33 | console.log('Lista de personas aceptadas:'); 34 | for (let i = 0; i < invitados.length; i++) { 35 | // Detectamos si hay algun invitado que no queremos 36 | if (invitados[i] === 'Jorge') { 37 | continue; 38 | } 39 | 40 | console.log(invitados[i]); 41 | } 42 | -------------------------------------------------------------------------------- /Introducción/callbacks.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Callbacks 3 | Las callbacks son funciones que podemos pasar como parametro a una función. 4 | Esto con el fin de que una función puede ejecutar otra función. 5 | */ 6 | 7 | const obtenerPostsDeUsuario = (usuario, callback) => { 8 | console.log(`Obteniendo los post de ${usuario} ...`); 9 | 10 | // Simulamos que tarda 2 segundos en obtener los posts. 11 | setTimeout(() => { 12 | // Una vez que obtiene los posts ejecuta el callback para devolverlos. 13 | let posts = ['Post1', 'Post2', 'Post3']; 14 | callback(posts); 15 | }, 2000); 16 | }; 17 | 18 | // A la funcion de obtenerPosts le podemos pasar un callback que se ejecutara cuando termine de obtener los posts. 19 | obtenerPostsDeUsuario('Carlos', (posts) => { 20 | console.log(posts); 21 | }); 22 | -------------------------------------------------------------------------------- /Introducción/cicloFor.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Ciclos 3 | Los ciclos son estructuras que nos van a permitir repetir 4 | un bloque de código cuantas veces necesitemos. 5 | */ 6 | const nombres = ['Carlos', 'Christian', 'Christoher', 'Estefania', 'Erika', 'Manuel']; 7 | // console.log(`Hola ${nombres[0]}`); 8 | // console.log(`Hola ${nombres[1]}`); 9 | // console.log(`Hola ${nombres[2]}`); 10 | // Ahora imaginemos que tenemos 100 nombres, o 1000. 11 | 12 | /* 13 | 📌 Ciclo For 14 | Repite un bloque de código mientras se cumpla una condición. 15 | 16 | Expresión 1: Se ejecuta una sola vez antes de comenzar a repetir el bloque de código. 17 | Expresión 2: Una condicion, mientras se cumpla se ejecutara el bloque de código. 18 | Expresión 3: Esta expresion se ejecuta siempre y despues de que se ejecute el bloque de código. 19 | */ 20 | 21 | // for(expresion1 ; expresion2 ; expresion3){ 22 | // Bloque de código a repetir 23 | // } 24 | 25 | /* 26 | 📌 Ejemplo de bloque sencillo donde contamos del 1 al 10 27 | */ 28 | for (let numero = 1; numero < 11; numero++) { 29 | // console.log(numero); 30 | } 31 | 32 | /* 33 | 📌 Contar del 1 al 100 con incrementos de 5 34 | */ 35 | for (let numero = 5; numero <= 100; numero = numero + 5) { 36 | // console.log(numero); 37 | } 38 | 39 | /* 40 | 📌 Contar del 50 al 1 41 | */ 42 | for (let numero = 50; numero > 0; numero--) { 43 | console.log(numero); 44 | } 45 | 46 | /* 47 | 📌 Recorrer un arreglo con el ciclo for 48 | */ 49 | for (let i = 0; i < nombres.length; i++) { 50 | console.log(nombres[i]); 51 | } 52 | -------------------------------------------------------------------------------- /Introducción/cicloForEach.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Ciclo forEach 3 | Es un metodo de los arreglos que podemos usar para recorrer los elementos. 4 | */ 5 | const amigos = ['Alejandro', 'Cesar', 'Manuel']; 6 | amigos.forEach((amigo, index) => console.log(`El amigo #${index} es: ${amigo}`)); 7 | 8 | /* 9 | 📌 Ciclo for in 10 | Nos permite recorrer las propiedades de un objeto. 11 | */ 12 | const persona = { 13 | nombre: 'Carlos', 14 | edad: 27, 15 | correo: 'correo@correo.com', 16 | }; 17 | 18 | for (propiedad in persona) { 19 | console.log(propiedad); 20 | 21 | // Ejemplo para borrar los valores de todas las propiedades. 22 | persona[propiedad] = ''; 23 | } 24 | console.log(persona); 25 | 26 | /* 27 | 📌 Ciclo for of 28 | Nos permite recorrer los valores de un objeto iterable. 29 | Podemos recorrer: Arreglos, Cadenas de Texto, Mapas y Listas de Nodos, etc 30 | */ 31 | // Obtenemos una colección HTML de las etiquetas. 32 | const etiquetas = document.head.children; 33 | 34 | // Las mostramos en pantalla. 35 | for (elemento of etiquetas) { 36 | // console.log(elemento); 37 | } 38 | 39 | // Esto no funciona, porque etiquetas no tiene el metodo forEach. 40 | // etiquetas.forEach((e) => console.log(e)); 41 | 42 | // Un truco para seguir usando forEach y no for of es transformar la colección a un arreglo 43 | [...etiquetas].forEach((e) => console.log(e)); 44 | -------------------------------------------------------------------------------- /Introducción/cicloWhile.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Ciclo While 3 | Es similar a for, pero con la diferencia de que solo tenemos un condicional. 4 | Mientras se cumpla el condicional se ejecutara el ciclo. 5 | */ 6 | 7 | // Ciclo infinito! Cuidado! 8 | // while (true) { 9 | // console.log('Hola'); 10 | // } 11 | 12 | let contador = 0; 13 | while (contador <= 10) { 14 | // console.log(contador); 15 | contador++; 16 | } 17 | 18 | /* 19 | 📌 Ciclo Do While 20 | Es similar al ciclo while, con la diferencia de que ejecuta el bloque de código al menos una vez. 21 | */ 22 | let i = 0; 23 | do { 24 | console.log(i); 25 | i++; // Cuidado porque si no ponemos el incremento tendremos un loop infinito. 26 | } while (i <= 10); 27 | -------------------------------------------------------------------------------- /Introducción/clases.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Clases 3 | Las clases son plantillas que podemos usar para crear objetos. 4 | Sirven para encapsular código. 5 | */ 6 | 7 | /* 8 | 📌 Estructura de una clase: 9 | - Definición 10 | - Propiedades: La clase puede contener variables. Dentro de una clase se llaman propiedades. 11 | - Constructor: Es un metodo especial para inicializar un objeto creado a partir de una clase. 12 | - Métodos: La clase puede contener funciones. Dentro de una clase se llaman metodos. 13 | */ 14 | // class NombreDeLaClase { 15 | // constructor() { 16 | // //... Código del constructor 17 | // } 18 | // } 19 | 20 | class Usuario { 21 | /* Propiedades 22 | Son variables dentro de la clase. 23 | Sirven para guardar informacion relacionada y que la clase pueda utilizarla. 24 | */ 25 | tipo = 'usuario'; 26 | 27 | /* 📌 Metodo constructor 28 | Se ejecuta automaticamente cada vez que hacemos un nuevo objeto con la clase. 29 | Se usa para inicializar las propiedades. 30 | En este caso toma el nombre y apellido y establece los valores en las propiedades. 31 | */ 32 | constructor(nombre, apellido) { 33 | this.nombre = nombre; 34 | this.apellido = apellido; 35 | 36 | console.log('Nuevo usuario registrado!'); 37 | } 38 | 39 | // Metodos 40 | obtenerNombreCompleto() { 41 | console.log('Obteniendo datos...'); 42 | return `${this.nombre} ${this.apellido}`; 43 | } 44 | } 45 | 46 | // Con la clase podemos crear objetos: 47 | const usuario = new Usuario('Carlos Arturo', 'Esparza'); 48 | 49 | // Podemos crear varios objetos, uno por usuario: 50 | const usuario2 = new Usuario('Manuel', 'Garcia'); 51 | 52 | // Accedemos a las propiedades 53 | console.log(usuario.tipo); 54 | console.log(usuario.apellido); 55 | 56 | // Accedemos a los metodos 57 | console.log(usuario.obtenerNombreCompleto()); 58 | -------------------------------------------------------------------------------- /Introducción/condicionales.js: -------------------------------------------------------------------------------- 1 | /* 📌 Las condicionales son un tipo de bloque que nos permite ejecutar código dependiendo de si se cumple una condición o no 2 | Normalmente se utilizan operadores de comparación. 3 | */ 4 | 5 | /* 6 | 📌 Operadores de Comparación: 7 | == Igual que 8 | === Igual en valor y typo de valor 9 | != Diferente 10 | !== Diferente en valor y diferente en typo 11 | > Mayor que 12 | < Menor que 13 | >= Mayor o igual que 14 | <= Menor o igual que 15 | ? Operador ternario 16 | 17 | 📌 Operadores Lógicos 18 | && And 19 | || OR 20 | ! NOT 21 | */ 22 | 23 | // 📌 Estructura de una condicional 24 | /* Condición */ 25 | if (true) { 26 | // Código a ejecutar 27 | } 28 | 29 | // 📌 Ejemplo #1: 30 | // const usuario = { 31 | // edad: 27, 32 | // pais: 'mexico', 33 | // ticket: true, 34 | // }; 35 | 36 | // if (usuario.edad > 17) { 37 | // // edad >= 18 38 | // console.log('El usuario es mayor de edad, puede entrar al concierto.'); 39 | // } else { 40 | // console.log('El usuario es menor de edad, no puede entrar al concierto'); 41 | // } 42 | 43 | // 📌 Ejemplo #2 - combinando operadores 44 | // const usuario = { 45 | // edad: 27, 46 | // pais: 'mexico', 47 | // ticket: false, 48 | // }; 49 | // if (usuario.edad > 17 && usuario.ticket) { 50 | // // edad >= 18 51 | // console.log('El usuario es mayor de edad y tiene un ticket.'); 52 | // } else { 53 | // console.log('El usuario es menor de edad o no tiene un ticket.'); 54 | // } 55 | 56 | // 📌 Ejemplo #3 - Anindando condicionales 57 | // const usuario = { 58 | // edad: 27, 59 | // pais: 'mexico', 60 | // ticket: false, 61 | // }; 62 | 63 | // if (usuario.edad >= 18) { 64 | // if (usuario.ticket) { 65 | // console.log('El usuario es mayor de edad y tiene ticket.'); 66 | // } else { 67 | // console.log('El usuario es mayor de edad, pero no tiene ticket.'); 68 | // } 69 | // } else { 70 | // console.log('El usuario es menor de edad, no puede entrar al concierto.'); 71 | // } 72 | 73 | // 📌 Ejemplo #4 - elseif 74 | const usuario = { 75 | edad: 27, 76 | pais: 'colombia', 77 | ticket: false, 78 | }; 79 | 80 | if (usuario.pais === 'mexico') { 81 | console.log('El usuario es mexicano'); 82 | } else if (usuario.pais === 'españa') { 83 | console.log('El usuario es español'); 84 | } else if (usuario.pais === 'argentina') { 85 | console.log('El usuario es argentino'); 86 | } else { 87 | console.log('El usuario es de otro pais'); 88 | } 89 | -------------------------------------------------------------------------------- /Introducción/estilos.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: 'Poppins', sans-serif; 11 | min-height: 100vh; 12 | width: 100%; 13 | background: #eaeaea; 14 | color: #000; 15 | display: flex; 16 | flex-direction: column; 17 | align-items: center; 18 | justify-content: center; 19 | } 20 | 21 | h1 { 22 | font-size: 80px; 23 | } 24 | 25 | h2 { 26 | font-size: 40px; 27 | font-weight: normal; 28 | margin-bottom: 40px; 29 | color: #848484; 30 | } 31 | 32 | button { 33 | border: none; 34 | background: #2553df; 35 | font-family: 'Poppins', sans-serif; 36 | font-size: 22px; 37 | cursor: pointer; 38 | border-radius: 10px; 39 | color: #fff; 40 | padding: 14px 28px; 41 | margin-bottom: 20px; 42 | } 43 | 44 | button:hover { 45 | background: #1942be; 46 | } 47 | -------------------------------------------------------------------------------- /Introducción/funciones.js: -------------------------------------------------------------------------------- 1 | /* 2 | Las funciones son bloques de código que nos permiten repetir acciones sin tener que duplicar código. 3 | Un ejemplo muy común de donde se utilizan es cuando presionamos un boton, invocamos una funcion y ejecuta el codigo. 4 | */ 5 | 6 | // 📌 Forma #1 7 | // function saludo() { 8 | // console.log('Hola!'); 9 | // } 10 | 11 | /* 📌 Invocamos la funcion 12 | Podemos invocar las funciones dentro de nuestro código, o con diferentes eventos. 13 | Por ejemplo cuando el usuario de click en un boton. 14 | 15 | Nota: Los parentesis son lo que invoca la función. Si no usamos parentesis solo tenemos una referencia de la función. 16 | */ 17 | // saludo(); // Invocamos la funcion 18 | // const variable = saludo; // Guardamos la funcion en una variable 19 | 20 | // 📌 Forma #2 - Asignando una funcion a una variable. 21 | // const saludo = function () { 22 | // console.log('Hola!'); 23 | // }; 24 | // saludo(); 25 | 26 | // 📌 Forma #3 - Función de tipo flecha 27 | // const saludo = () => { 28 | // console.log('Hola!'); 29 | // }; 30 | // saludo(); 31 | -------------------------------------------------------------------------------- /Introducción/herencia.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Herencia 3 | La herencia nos permite crear clases tomando las propiedades y metodos de otras clases. 4 | */ 5 | 6 | class Usuario { 7 | constructor(usuario, password) { 8 | this.usuario = usuario; 9 | this.password = password; 10 | } 11 | 12 | obtenerPosts() { 13 | const posts = ['post1', 'post2']; 14 | return posts; 15 | } 16 | } 17 | 18 | class Moderador extends Usuario { 19 | constructor(usuario, password, permisos) { 20 | // Super nos permite copair todos los metodos y propiedades de la clase original. 21 | // Incluyendo el constructor, por eso le pasamos los parametros usuario y password. 22 | super(usuario, password); 23 | this.permisos = permisos; 24 | } 25 | 26 | borrarPost(id) { 27 | if (this.permisos.includes('borrar')) { 28 | console.log(`El post con el ${id} ha sido borrado`); 29 | } else { 30 | console.log('No tienes los suficientes permisos para borrar posts'); 31 | } 32 | } 33 | } 34 | 35 | const usuario1 = new Usuario('carlos', '123'); 36 | console.log(usuario1.permisos); 37 | console.log(usuario1.obtenerPosts()); 38 | 39 | // El usuario 2 es un moderador 40 | const usuario2 = new Moderador('arturo', '123', ['borrar', 'editar']); 41 | // Tambien puede acceder a los metodos y propiedades de la clase Usuario. 42 | console.log(usuario2.tipo); 43 | console.log(usuario2.obtenerPosts()); 44 | usuario2.borrarPost(1); 45 | -------------------------------------------------------------------------------- /Introducción/holaMundo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Mi primera página web con Javascript 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Introducción/holaMundo.js: -------------------------------------------------------------------------------- 1 | alert('Hola mundo, desde archivo externo'); 2 | -------------------------------------------------------------------------------- /Introducción/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso de Javascript 8 | 9 | 10 | 11 | 12 |

Curso de Javascript

13 |

Completo, Práctico y desde Cero

14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Introducción/metodosEstaticos.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Propiedades y Métodos Estaticos 3 | Para poder acceder a las propiedades y metodos de una clase, 4 | primero tenemos que crear un nuevo objeto apartir de una clase. 5 | 6 | Esto lo podemos cambiar utilizando propiedades y métodos estaticos. 7 | */ 8 | class Usuario { 9 | constructor(nombre, correo) { 10 | this.nombre = nombre; 11 | this.correo = correo; 12 | 13 | console.log('Se ha creado un usuario en la base de datos'); 14 | } 15 | 16 | static borrar(id_usuario) { 17 | console.log(`El usuario con el id: ${id_usuario} ha sido borrado de la base de datos`); 18 | 19 | /* Si usamos metodos estaticos, no vamos a poder acceder al nombre y correo, 20 | porque para eso necesitabamos el constructor */ 21 | // console.log(this.nombre); 22 | } 23 | 24 | // Tambien funciona con propiedades 25 | static registrados = 1000; 26 | } 27 | 28 | // Para poder borrar al usuario teniamos que crear un objeto primero: 29 | // const usuario = new Usuario('carlos', 'correo@correo.com'); 30 | 31 | // Si tenemos una propiedad o metodo estatico podemos acceder sin crear el objeto. 32 | Usuario.borrar(1); 33 | console.log(Usuario.registrados); 34 | -------------------------------------------------------------------------------- /Introducción/metodosParaObjetos.js: -------------------------------------------------------------------------------- 1 | const usuario = { 2 | nombre: 'Carlos', 3 | edad: 27, 4 | amigos: ['Alejandro', 'Cesar', 'Manuel'], 5 | saludo: () => { 6 | console.log('Hola!'); 7 | }, 8 | }; 9 | 10 | /* 11 | 📌 Métodos propios 12 | Los objetos pueden tener métodos personalizados. 13 | */ 14 | usuario.saludo(); 15 | 16 | /* 17 | 📌 Object.keys() 18 | Nos devuelve un arreglo con las llaves (keys) del objeto. 19 | */ 20 | const resultado = Object.keys(usuario); 21 | 22 | /* 23 | 📌 Object.values() 24 | Nos devuelve un arreglo con los valores (values) del objeto. 25 | */ 26 | // const resultado = Object.values(usuario); 27 | 28 | /* 29 | 📌 Object.entries() 30 | Nos devuelve un arreglo con las parejas de clave y valor del objeto. 31 | */ 32 | // const resultado = Object.entries(usuario); 33 | console.log(resultado); 34 | 35 | /* 36 | Con estos métodos se pueden hacer muchas cosas, 37 | como por ejemplo usarlos para contar el numero de propiedades. 38 | */ 39 | const entradas = Object.entries(usuario); 40 | console.log(`El objeto tiene ${entradas.length} propiedades`); 41 | -------------------------------------------------------------------------------- /Introducción/objetos.js: -------------------------------------------------------------------------------- 1 | /* 📌 Los objetos en Javascript son variables en las que podemos estructurar informacion mediante parejas de claves y valores. 2 | 3 | Igual que los arreglos podemos guardar multiples valores. 4 | La diferencia es que en los objetos tenemos propiedades con las que podemos identificar y llamar los valores. 5 | */ 6 | 7 | // Ejemplo de arreglo poco útil. 8 | // Nombre, edad, correo, suscripcion al sitio, suscripcion a los correos promocionales. 9 | // const persona = ['Carlos', 27, 'correo@correo.com', true, true]; 10 | // console.log(persona[0]); 11 | 12 | // Ejemplo con un objeto. 13 | const persona = { 14 | nombre: 'Carlos', 15 | edad: 27, 16 | correo: 'correo@correo.com', 17 | suscripciones: { 18 | suscripcionWeb: true, 19 | suscripcionCorreo: true, 20 | }, 21 | coloresFavoritos: ['Negro', 'Rojo'], 22 | saludo: function () { 23 | alert('Hola!'); 24 | }, 25 | }; 26 | 27 | console.log(persona.nombre); 28 | console.log(persona['edad']); 29 | 30 | // Esto es muy util para trabajar con variables 31 | const variable = 'correo'; 32 | console.log(persona[variable]); 33 | 34 | // Podemos agregar nuevos valores a un objeto 35 | persona.pais = 'Mexico'; 36 | console.log(persona); 37 | 38 | // Podemos sobreescribir valores 39 | persona.pais = 'España'; 40 | console.log(persona); 41 | 42 | // Los objetos tambien pueden tener metodos. 43 | persona.saludo(); 44 | -------------------------------------------------------------------------------- /Introducción/operadorSpread.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Operador Spread 3 | Permite tomar los elementos de un arreglo u objeto y expandirlos en otro sitio. 4 | */ 5 | const frutas = ['Manzana', 'Pera', 'Piña', 'Melon']; 6 | const comidaFavorita = ['Pizza', 'Sushi', ...frutas]; 7 | console.log(comidaFavorita); 8 | 9 | // Tambien funciona con objetos 10 | const datosLogin = { 11 | nombre: 'Arturo', 12 | correo: 'correo@correo.com', 13 | password: '123', 14 | }; 15 | 16 | const usuario = { 17 | nombre: 'Carlos', 18 | ...datosLogin, 19 | edad: 27, 20 | }; 21 | 22 | console.log(usuario); 23 | 24 | /* 25 | 📌 Parametro Rest 26 | Permite que una funcion contenga un numero indefinido de argumentos. 27 | Los argumentos extra que encuentre los convertira en un arreglo. 28 | */ 29 | const registrarUsuario = (nombre, correo, ...datosAdicionales) => { 30 | console.log(nombre, correo, datosAdicionales); 31 | }; 32 | 33 | registrarUsuario('Carlos', 'correo@correo.com'); 34 | registrarUsuario('Alejandro', 'alejandro@correo.com', 28, 'España'); 35 | 36 | /* 37 | 📌 Destructuración de objetos 38 | Nos permite obtener elementos o propiedades de un arreglo u objeto y guardarlos en una variable. 39 | */ 40 | const amigos = ['Alejandro', 'Cesar', 'Manuel']; 41 | const [primerAmigo, segundoAmigo, tercerAmigo] = amigos; 42 | 43 | // Sin destructuración: 44 | // const primerAmigo = amigos[0]; 45 | // const segundoAmigo = amigos[1]; 46 | 47 | console.log(primerAmigo); 48 | 49 | // Ejemplo con objetos 50 | const persona = { 51 | nombre: 'Carlos', 52 | edad: 27, 53 | pais: 'México', 54 | }; 55 | const { nombre, pais } = persona; 56 | console.log(nombre, pais); 57 | 58 | // Podemos destructurar los valores de una funcion 59 | const mostrarEdad = ({ nombre, edad }) => { 60 | console.log(`${nombre} tiene ${edad} años`); 61 | }; 62 | mostrarEdad(persona); 63 | -------------------------------------------------------------------------------- /Introducción/operadorTernario.js: -------------------------------------------------------------------------------- 1 | /* 2 | El operador ternario nos permite hacer condicionales abarcando menos codigo que si utilizaramos un condicional if. 3 | */ 4 | 5 | // Ejemplo de condicional sin operador ternario. 6 | // const boleto = 'vip'; 7 | // let codigoDeAcceso; 8 | 9 | // if (boleto === vip) { 10 | // codigoDeAcceso = 'VIP-123-456-789'; 11 | // } else { 12 | // codigoDeAcceso = 'Regular-123-456-789'; 13 | // } 14 | 15 | // Ejemplo con operador ternario 16 | const boleto = 'vip'; 17 | const codigoDeAcceso = boleto === 'VIP' ? 'VIP-123-456-789' : 'Regular-123-456-789'; 18 | 19 | // Ejemplo 2 - No siempre es necsario guardar el valor en una variable 20 | boleto === 'VIP' ? console.log('Tu boleto es VIP-123-456-789') : console.log('Tu boleto es Regular-123-456-789'); 21 | -------------------------------------------------------------------------------- /Introducción/parametros.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 En las funciones podemos definir parametros, que son valores que la funcion puede utilizar. 3 | */ 4 | /* 5 | - Parametros: los valores especificados en la definición 6 | - Argumentos: los valores que le pasamos a la función cuando la invocamos. 7 | */ 8 | 9 | // const saludo = (nombre = 'amigo') => { 10 | // console.log(`Hola, ${nombre}!`); 11 | // }; 12 | 13 | // saludo('Carlos'); 14 | // saludo(); 15 | 16 | /* 17 | 📌 Multiples parametros 18 | */ 19 | // const operacion = (tipo, numero1, numero2) => { 20 | // console.log(tipo); 21 | 22 | // if (tipo === 'suma') { 23 | // console.log(numero1 + numero2); 24 | // } else if (tipo === 'resta') { 25 | // console.log(numero1 - numero2); 26 | // } 27 | // }; 28 | 29 | // operacion('resta', 2, 5); 30 | 31 | // Las funciones de tipo flecha las podemos resumir en una linea de codigo 32 | const operacion2 = (tipo, numero1, numero2) => (tipo === 'suma' ? numero1 + numero2 : numero1 - numero2); 33 | console.log(operacion2('', 1, 1)); 34 | -------------------------------------------------------------------------------- /Introducción/promesas2.js: -------------------------------------------------------------------------------- 1 | // Ejemplo anterior de una funcion que devuelve una promesa (Sin Async/Await) 2 | const fetchPosts = () => { 3 | return new Promise((resolve, reject) => { 4 | setTimeout(() => { 5 | const posts = ['Post 1', 'Post 2', 'Post 3']; 6 | const error = false; 7 | 8 | if (error) { 9 | reject('Hubo un error al intentar obtener los posts'); 10 | } else { 11 | resolve(posts); 12 | } 13 | }, 2000); 14 | }); 15 | }; 16 | 17 | // Obtentiendo los posts (con then y catch) 18 | // obtenerPosts() 19 | // .then((posts) => { 20 | // console.log(posts); 21 | // }) 22 | // .catch((error) => { 23 | // console.log(error); 24 | // }); 25 | -------------------------------------------------------------------------------- /Introducción/return.js: -------------------------------------------------------------------------------- 1 | /* 2 | Una buena practica es que las funciones se encarguen de realizar una sola tarea. 3 | La funcion anterior hace la operacion y luego la publica. Podemos optimizar el codigo con un return. 4 | */ 5 | /* 6 | 📌 Sentencia Return 7 | La sentencia return nos permite que la funcion devuelva/retorne un valor. 8 | El return para la ejecucion del código dentro de la funcion. 9 | */ 10 | const operacion = (tipo, numero1, numero2) => { 11 | let resultado; 12 | 13 | if (tipo === 'suma') { 14 | resultado = numero1 + numero2; 15 | // return resultado; 16 | } else if (tipo === 'resta') { 17 | resultado = numero1 - numero2; 18 | // return resultado; 19 | } 20 | 21 | return resultado; 22 | console.log('Este codigo no se ejecuta'); 23 | }; 24 | 25 | console.log(operacion('resta', 10, 1)); 26 | console.log(operacion('suma', 100, 11)); 27 | 28 | const variable = operacion('suma', 5, 5); 29 | console.log(variable); 30 | -------------------------------------------------------------------------------- /Introducción/switch.js: -------------------------------------------------------------------------------- 1 | /* 📌 2 | Switch es un bloque de codigo similar a elseif 3 | que nos permite ejecutar código en base a una condición, en este caso cuando un valor sea igual a otro. 4 | */ 5 | 6 | const usuario = { 7 | edad: 27, 8 | pais: 'mexico', 9 | }; 10 | 11 | // Nota: no olvidarnos de la palabra break. 12 | 13 | switch (usuario.pais) { 14 | case 'mexico': 15 | console.log('El usuario es mexicano'); 16 | break; 17 | case 'españa' && edad >= 18: 18 | console.log('El usuario es español'); 19 | break; 20 | case 'argentina': 21 | console.log('El usuario es argentino'); 22 | break; 23 | default: 24 | console.log('El usuario es de otro pais'); 25 | } 26 | 27 | // Condicional elseif 28 | // if (usuario.pais === 'mexico') { 29 | // console.log('El usuario es mexicano'); 30 | // } else if (usuario.pais === 'españa') { 31 | // console.log('El usuario es español'); 32 | // } else if (usuario.pais === 'argentina') { 33 | // console.log('El usuario es argentino'); 34 | // } else { 35 | // console.log('El usuario es de otro pais'); 36 | // } 37 | 38 | /* 39 | Cuando usar else if y cuando switch. 40 | elseif nos permite tener condiciones mas complejas: 41 | } else if (usuario.pais === 'españa' && usuario.edad >= 18) { 42 | 43 | switch nos permite ejecutar codigo si una variable contiene X valor: 44 | case 'españa': 45 | */ 46 | -------------------------------------------------------------------------------- /Introducción/templateStrings.js: -------------------------------------------------------------------------------- 1 | /* 📌 Los template strings son una nueva forma que tenemos en Javascript (ES6) para trabajar con cadenas de texto y que estas puedan incluir expresiones de javascript. Como variables por ejemplo. 2 | 3 | También se les conoce como template literals. */ 4 | const nombre = 'Carlos'; 5 | 6 | // Formas de trabajar con variables y cadenas de texto. 7 | // console.log('Hola ' + nombre + ' buenos dias.'); 8 | 9 | // Con template strings. 10 | console.log(`Hola ${nombre} buenos dias`); 11 | 12 | // Podemos trabajar con variables y operadores. 13 | const amigos = ['Alejandro', 'Cesar', 'Manuel']; 14 | console.log(`${nombre} tiene ${amigos.length} amigos`); 15 | 16 | // Tambien son muy utiles para trabajar con HTML. 17 | const plantilla = ` 18 |

${nombre} tiene ${amigos.length} amigos

19 | `; 20 | 21 | // Accedemos al objeto del documento. 22 | // Luego a la propiedad body. 23 | // Luego a la propiead innerHTML y le establecemos la plantilla. 24 | document.body.innerHTML = plantilla; 25 | -------------------------------------------------------------------------------- /Introducción/tiposDeDatos.js: -------------------------------------------------------------------------------- 1 | /* 📌 Tipos de datos que podemos guardar en las variables: 2 | string - Cadena de Texto 3 | number - Numero 4 | boolean - Booleano (verdadero o falso) 5 | object - Objeto 6 | function - Funciones 7 | 8 | null - Valor nulo 9 | undefined - Valor sin definir 10 | */ 11 | 12 | // 📌 Cadena de Texto 13 | // Pueden llevar comillas simples, comillas dobles o backticks. 14 | // Regularmente se escriben con comillas simples o backticks. 15 | const nombre = 'Carlos Arturo'; 16 | const parrafo = "Este es un parrafo que usa 'comillas' simples"; 17 | const parrafo2 = 'Este es un parrafo que usa "comillas" dobles'; 18 | // const parrafo3 = 'Este es un parrafo que usa \'comillas\' simples'; 19 | console.log(parrafo2); 20 | 21 | // 📌 Numero 22 | // Cualquier numero positivo o negativo, entero o decimal. 23 | const numero = 4; 24 | const numero2 = 4.123; 25 | 26 | // 📌 Boleano 27 | const usuarioConectado = true; // true o false 28 | const mayorQue = 1 > 2; // False 29 | 30 | // 📌 Arrays - Arreglos 31 | // En javascript son un tipo de objeto. Esto es porque cuentan con propiedades y métodos. 32 | // Los arreglos nos permiten guardar varios valores y cada valor puede ser de cualquier tipo. 33 | const arreglo = ['Texto', 456, true, { propiedad: 'valor' }, [0, 1, 2, 3]]; 34 | 35 | // 📌 Objeto 36 | // Los objetos nos permiten guardar informacion mediante parejas de claves y valores. 37 | 38 | // En javascript existen 6 tipos de objetos: 39 | // Object, Date, Array, String, Number, Boolean. 40 | // Los objetos en javascript tienen propieades y valores. 41 | 42 | // A las propiedades de un objeto les podemos asignar cualquier tipo de dato. 43 | const persona = { 44 | // Propiedad: nombre 45 | // Valor: Carlos 46 | nombre: 'Carlos', 47 | edad: 27, 48 | carro: { 49 | marca: '...', 50 | color: 'Negro', 51 | }, 52 | }; 53 | 54 | // 📌 Function 55 | // Las funciones son bloques de codigo que podemos reutilizar. 56 | function hola() { 57 | console.log('Hola!'); 58 | } 59 | 60 | hola(); 61 | 62 | // 📌 Null 63 | // Normalmente lo usamos cuando queremos especificar que un valor sea nulo. 64 | 65 | // 📌 Undefined 66 | // Undefined se usa para indicarnos que un valor no esta definido. 67 | -------------------------------------------------------------------------------- /Modulos/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modulos", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "modulos", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "rollup": "^3.2.3" 13 | } 14 | }, 15 | "node_modules/fsevents": { 16 | "version": "2.3.2", 17 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 18 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 19 | "dev": true, 20 | "hasInstallScript": true, 21 | "optional": true, 22 | "os": [ 23 | "darwin" 24 | ], 25 | "engines": { 26 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 27 | } 28 | }, 29 | "node_modules/rollup": { 30 | "version": "3.2.3", 31 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.2.3.tgz", 32 | "integrity": "sha512-qfadtkY5kl0F5e4dXVdj2D+GtOdifasXHFMiL1SMf9ADQDv5Eti6xReef9FKj+iQPR2pvtqWna57s/PjARY4fg==", 33 | "dev": true, 34 | "bin": { 35 | "rollup": "dist/bin/rollup" 36 | }, 37 | "engines": { 38 | "node": ">=14.18.0", 39 | "npm": ">=8.0.0" 40 | }, 41 | "optionalDependencies": { 42 | "fsevents": "~2.3.2" 43 | } 44 | } 45 | }, 46 | "dependencies": { 47 | "fsevents": { 48 | "version": "2.3.2", 49 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 50 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 51 | "dev": true, 52 | "optional": true 53 | }, 54 | "rollup": { 55 | "version": "3.2.3", 56 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.2.3.tgz", 57 | "integrity": "sha512-qfadtkY5kl0F5e4dXVdj2D+GtOdifasXHFMiL1SMf9ADQDv5Eti6xReef9FKj+iQPR2pvtqWna57s/PjARY4fg==", 58 | "dev": true, 59 | "requires": { 60 | "fsevents": "~2.3.2" 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Modulos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modulos", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "build": "rollup --watch --config" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "rollup": "^3.2.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Modulos/public/bundle.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* 4 | 📌 Default Exports 5 | Cuando trabajamos con default exports solo podemos exportar una cosa del archivo. 6 | Con la ventaja de que podemos importarlo con el nombre que queramos 7 | 8 | Podemos exportar de dos formas: 9 | - Mediante las palabras export default antes de la variable. (No podemos usar var, const, let) 10 | - Al final de documento mediante las palabras export default 11 | */ 12 | 13 | // Forma 1 - mediante palabras export default 14 | // export default () => { 15 | // return { 16 | // nombre: 'Carlos', 17 | // correo: 'correo@correo.com', 18 | // }; 19 | // }; 20 | 21 | // Forma 2 - Final del documento 22 | const obtenerUsuario = () => { 23 | return { 24 | nombre: 'Carlos', 25 | correo: 'correo@correo.com', 26 | }; 27 | }; 28 | 29 | console.log('Soy codigo que se ejecuta desde el archivo emptyExport.js'); 30 | 31 | const correo = 'correo@correo.com'; 32 | 33 | /* 34 | 📌 Named Imports 35 | Podemos importar variables y funciones que han sido exportadas mediante la palabra "export". 36 | Podemos importarlas con el mismo nombre o podemos usar un alias usando la palabra "as". 37 | Normalmente todos los import se establecen al inicio del documento. 38 | */ 39 | console.log(obtenerUsuario()); 40 | console.log(correo); 41 | -------------------------------------------------------------------------------- /Modulos/rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | input: 'src/index.js', 3 | output: { 4 | file: 'public/bundle.js', 5 | format: 'cjs', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /Modulos/src/defaultExport.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Default Exports 3 | Cuando trabajamos con default exports solo podemos exportar una cosa del archivo. 4 | Con la ventaja de que podemos importarlo con el nombre que queramos 5 | 6 | Podemos exportar de dos formas: 7 | - Mediante las palabras export default antes de la variable. (No podemos usar var, const, let) 8 | - Al final de documento mediante las palabras export default 9 | */ 10 | 11 | // Forma 1 - mediante palabras export default 12 | // export default () => { 13 | // return { 14 | // nombre: 'Carlos', 15 | // correo: 'correo@correo.com', 16 | // }; 17 | // }; 18 | 19 | // Forma 2 - Final del documento 20 | const obtenerUsuario = () => { 21 | return { 22 | nombre: 'Carlos', 23 | correo: 'correo@correo.com', 24 | }; 25 | }; 26 | 27 | export default obtenerUsuario; 28 | -------------------------------------------------------------------------------- /Modulos/src/emptyExport.js: -------------------------------------------------------------------------------- 1 | console.log('Soy codigo que se ejecuta desde el archivo emptyExport.js'); 2 | 3 | export const correo = 'correo@correo.com'; 4 | -------------------------------------------------------------------------------- /Modulos/src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Named Imports 3 | */ 4 | /* 5 | 📌 Named Imports 6 | Podemos importar variables y funciones que han sido exportadas mediante la palabra "export". 7 | Podemos importarlas con el mismo nombre o podemos usar un alias usando la palabra "as". 8 | Normalmente todos los import se establecen al inicio del documento. 9 | */ 10 | // import { nombre as nombreImportado, obtenerPosts } from './namedExports'; 11 | // console.log('Mi nombre es ' + nombreImportado); 12 | // console.log(obtenerPosts()); 13 | 14 | /* 15 | 📌 Namespace Imports 16 | */ 17 | /* 18 | Podemos importar todas las variables y funciones que fueron exportadas 19 | con un named export dentro de un objeto. 20 | */ 21 | // import * as datos from './namedExports'; 22 | // console.log(datos.nombre); 23 | // console.log(datos.obtenerPosts()); 24 | 25 | /* 26 | 📌 Default Imports 27 | */ 28 | /* 29 | Los default imports no utilizan llaves y podemos ponerles el nombre que queramos. 30 | */ 31 | import obtenerUsuario from './defaultExport'; 32 | console.log(obtenerUsuario()); 33 | 34 | /* 35 | 📌 Empty Imports 36 | Carga todo el codigo pero sin hacer ningun objeto. 37 | */ 38 | import './emptyExport'; 39 | 40 | // No podemos acceder a las variables definidas en el archivo emptyExport. 41 | // Si las necesitamos tenemos que que exportarlas. 42 | import { correo } from './emptyExport'; 43 | console.log(correo); 44 | -------------------------------------------------------------------------------- /Modulos/src/namedExports.js: -------------------------------------------------------------------------------- 1 | /* 2 | 📌 Named Exports 3 | 4 | Podemos exportar variables y funciones utilizando named exports o default exports. 5 | Cuando trabajamos con named exports podemos exportar multiples cosas. 6 | Podemos exportar de dos formas: 7 | - Agregando la palabra export antes de la variable. 8 | - Al final de documento 9 | */ 10 | 11 | // Forma 1 - Palabra export 12 | export const nombre = 'Carlos Arturo'; 13 | 14 | export const obtenerPosts = () => { 15 | return ['Post1', 'Post2', 'Post3']; 16 | }; 17 | 18 | // Forma 2 - Final del documento 19 | // const nombre = 'Carlos Arturo'; 20 | 21 | // const obtenerPosts = () => { 22 | // return ['Post1', 'Post2', 'Post3']; 23 | // }; 24 | 25 | // export { nombre, obtenerPosts }; 26 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-gastos", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "sass": "sass --watch --style=compressed sass/index.scss public/bundle.css", 9 | "build": "rollup --watch --config --sourcemap" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@rollup/plugin-node-resolve": "^13.3.0", 16 | "rollup": "^2.77.2", 17 | "uuid": "^8.3.2" 18 | }, 19 | "dependencies": { 20 | "date-fns": "^2.29.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/public/bundle.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sourceRoot":"","sources":["../sass/_generales.scss","../sass/_variables.scss","../sass/_header.scss","../sass/_main.scss","../sass/_gastos.scss","../sass/_formulario-gasto.scss","../sass/_footer.scss","../sass/_fondo.scss"],"names":[],"mappings":"AAEA,EACC,SACA,UACA,sBAGD,KACC,WCRa,KDSb,YCViB,mBDWjB,eACA,iBACA,aACA,mBAGD,YACC,kBACA,UACA,UACA,gBACA,YACA,YACA,gBACA,mBAEA,aACA,iCE5BD,eACC,eACA,kBACA,WACA,wBACC,kBAED,yBACC,WACA,eACA,gBCVF,KACC,gBACA,kBACA,gBCDD,QACC,gBACA,4BACA,aACA,YACA,kBACA,WACA,cAEA,gBACC,gBACA,eACA,mBAGD,iBACC,WACA,YACA,kBACA,MACA,OACA,aACA,mBACA,uBACA,MHtBY,QGuBZ,yBACC,aAIF,eACC,aACA,eACA,SACA,gBACA,cACA,yBAIF,OACC,aACA,SACA,iBACA,gBACA,6BAEA,aACC,wBACA,eACA,aACA,qBACA,8BACA,sBACA,mBACA,aACA,eAGD,eACC,kBAGD,iBACC,eACA,MHjEe,QGoEhB,cACC,eACA,MHpEY,QGuEb,iBACC,wBACA,aACA,SAGD,YACC,YACA,eACA,WH/EiB,KGgFjB,WACA,aACA,sBACA,uBACA,mBACA,QACA,mBACA,wBACA,kBACC,WHxFsB,QG2FvB,kBACC,WH3FU,QG4FV,WACA,wBACC,WH7Fe,QINnB,kBACC,YACA,WACA,aACA,gBACA,kBACA,WACA,4BACA,+BACA,yBACA,cAEA,0BACC,4BAGD,0BACC,gBACA,eACA,mBAGD,wBACC,aACA,sBACA,SAGD,yBACC,eACA,mBACA,cAGD,2BACC,eACA,MJlCY,QImCZ,cACA,aAEA,mCACC,cAIF,yBACC,WACA,YACA,eACA,YJnDgB,mBIoDhB,YACA,kBACA,kBACA,eACA,mBACA,aACA,+BAEA,+BACC,sBAGD,gCACC,yBAIF,uBACC,aACA,mBACA,uBACA,YACA,WACA,eACA,YACA,WJ3Ee,QI4Ef,WACA,yBACA,YJhFgB,mBIiFhB,gBACA,eACA,kBACA,wBACA,gCAEA,6BACC,0BAGD,6BACC,WJzFoB,QKDvB,eACC,aACA,mBACA,uBACA,eAEA,oBACC,eACA,WACA,WACA,YACA,mBACA,YACA,WLbe,QKcf,wBAEA,0BACC,WLhBoB,QKmBrB,4BACC,WLlBgB,KKmBhB,WACA,wBACA,kCACC,WLrBqB,QK0BxB,0BACC,WACA,YClCF,OACC,eACA,WACA,YACA,UAEA,gBACC,cACA,kBAGD,qBACC,QACA,YACA,YACA,aACA,oBACA,mBAGD,qBACC,SACA,aACA,YACA,aACA,oBACA,mBAGD,qBACC,QACA,WACA,WACA,YACA,mBACA,mBAGD,qBACC,QACA,YACA,WACA,YACA,mBACA","file":"bundle.css"} -------------------------------------------------------------------------------- /Proyectos/App_gastos/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { nodeResolve } from '@rollup/plugin-node-resolve'; 2 | 3 | export default { 4 | input: 'src/index.js', 5 | output: { 6 | file: 'public/bundle.js', 7 | format: 'cjs', 8 | }, 9 | plugins: [nodeResolve()], 10 | }; 11 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/sass/_fondo.scss: -------------------------------------------------------------------------------- 1 | .fondo { 2 | position: fixed; 3 | width: 100%; 4 | height: 100%; 5 | z-index: 0; 6 | 7 | &__circulo { 8 | display: block; 9 | position: absolute; 10 | } 11 | 12 | :nth-child(1) { 13 | top: 50%; 14 | left: -100px; 15 | width: 385px; 16 | height: 385px; 17 | border-radius: 385px; 18 | background: #e3e8e9; 19 | } 20 | 21 | :nth-child(2) { 22 | top: -20%; 23 | right: -100px; 24 | width: 385px; 25 | height: 385px; 26 | border-radius: 385px; 27 | background: #e3e8e9; 28 | } 29 | 30 | :nth-child(3) { 31 | top: 20%; 32 | left: 100px; 33 | width: 42px; 34 | height: 42px; 35 | border-radius: 42px; 36 | background: #55baf3; 37 | } 38 | 39 | :nth-child(4) { 40 | top: 50%; 41 | right: 100px; 42 | width: 20px; 43 | height: 20px; 44 | border-radius: 20px; 45 | background: #59c647; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/sass/_footer.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .agregar-gasto { 4 | display: flex; 5 | align-items: center; 6 | justify-content: center; 7 | padding: 15px 0; 8 | 9 | &__btn { 10 | cursor: pointer; 11 | color: #fff; 12 | width: 60px; 13 | height: 60px; 14 | border-radius: 60px; 15 | border: none; 16 | background: variables.$color-primario; 17 | transition: 0.3s ease all; 18 | 19 | &:hover { 20 | background: variables.$color-primario-hover; 21 | } 22 | 23 | &--active { 24 | background: variables.$color-gris-claro; 25 | color: #000; 26 | transform: rotate(45deg); 27 | &:hover { 28 | background: variables.$color-gris-claro-hover; 29 | } 30 | } 31 | } 32 | 33 | &__btn-icono { 34 | width: 30px; 35 | height: 30px; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/sass/_formulario-gasto.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .formulario-gasto { 4 | height: 100%; 5 | width: 100%; 6 | padding: 20px; 7 | background: #fff; 8 | position: absolute; 9 | z-index: 11; 10 | border-radius: 25px 25px 0 0; 11 | transition: 0.3s ease-in-out all; 12 | transform: translateY(5%); 13 | overflow: auto; 14 | 15 | &--active { 16 | transform: translateY(-100%); 17 | } 18 | 19 | &__titulo { 20 | font-weight: 700; 21 | font-size: 22px; 22 | margin-bottom: 20px; 23 | } 24 | 25 | &__form { 26 | display: flex; 27 | flex-direction: column; 28 | gap: 20px; 29 | } 30 | 31 | &__label { 32 | font-size: 14px; 33 | margin-bottom: 10px; 34 | display: block; 35 | } 36 | 37 | &__leyenda { 38 | font-size: 12px; 39 | color: variables.$color-fecha; 40 | margin: 10px 0; 41 | display: none; 42 | 43 | &--active { 44 | display: block; 45 | } 46 | } 47 | 48 | &__input { 49 | width: 100%; 50 | border: none; 51 | font-size: 18px; 52 | font-family: variables.$fuente-primaria; 53 | height: 70px; 54 | border-radius: 5px; 55 | text-align: center; 56 | padding: 0 20px; 57 | background: #f8f8f8; 58 | outline: none; 59 | border: 2px solid transparent; 60 | 61 | &:focus { 62 | border: 2px solid variables.$color-gris-claro; 63 | } 64 | 65 | &--error { 66 | border: 2px solid variables.$color-rojo; 67 | } 68 | } 69 | 70 | &__btn { 71 | display: flex; 72 | align-items: center; 73 | justify-content: center; 74 | height: 70px; 75 | width: 100%; 76 | cursor: pointer; 77 | border: none; 78 | background: variables.$color-primario; 79 | color: #fff; 80 | text-transform: uppercase; 81 | font-family: variables.$fuente-primaria; 82 | font-weight: 700; 83 | font-size: 14px; 84 | border-radius: 5px; 85 | transition: 0.3s ease all; 86 | outline: 2px solid transparent; 87 | 88 | &:focus { 89 | outline: 2px solid variables.$color-primario-hover; 90 | } 91 | 92 | &:hover { 93 | background: variables.$color-primario-hover; 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/sass/_gastos.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .gastos { 4 | background: #fff; 5 | border-radius: 20px 20px 0 0; 6 | padding: 20px; 7 | height: 100%; 8 | position: relative; 9 | z-index: 10; 10 | overflow: auto; 11 | 12 | &__titulo { 13 | font-weight: 700; 14 | font-size: 22px; 15 | margin-bottom: 10px; 16 | } 17 | 18 | &__mensaje { 19 | width: 100%; 20 | height: 100%; 21 | position: absolute; 22 | top: 0; 23 | left: 0; 24 | display: none; 25 | align-items: center; 26 | justify-content: center; 27 | color: variables.$color-fecha; 28 | &--active { 29 | display: flex; 30 | } 31 | } 32 | 33 | &__lista { 34 | display: flex; 35 | flex-wrap: wrap; 36 | gap: 20px; 37 | max-height: 60vh; 38 | overflow: auto; 39 | align-content: flex-start; 40 | } 41 | } 42 | 43 | .gasto { 44 | display: flex; 45 | gap: 20px; 46 | flex-wrap: nowrap; 47 | overflow: hidden; 48 | scroll-snap-type: x mandatory; 49 | 50 | &__info { 51 | scroll-snap-align: start; 52 | min-width: 100%; 53 | display: flex; 54 | align-items: flex-end; 55 | justify-content: space-between; 56 | border: 1px solid variables.$color-gris-claro; 57 | border-radius: 10px; 58 | padding: 10px; 59 | cursor: pointer; 60 | } 61 | 62 | &__nombre { 63 | margin-bottom: 5px; 64 | } 65 | 66 | &__cantidad { 67 | font-size: 24px; 68 | color: variables.$color-primario; 69 | } 70 | 71 | &__fecha { 72 | font-size: 14px; 73 | color: variables.$color-fecha; 74 | } 75 | 76 | &__acciones { 77 | scroll-snap-align: start; 78 | display: flex; 79 | gap: 20px; 80 | } 81 | 82 | &__btn { 83 | border: none; 84 | cursor: pointer; 85 | background: variables.$color-gris-claro; 86 | width: 80px; 87 | display: flex; 88 | flex-direction: column; 89 | justify-content: center; 90 | align-items: center; 91 | gap: 5px; 92 | border-radius: 10px; 93 | transition: 0.3s ease all; 94 | &:hover { 95 | background: variables.$color-gris-claro-hover; 96 | } 97 | 98 | &--rojo { 99 | background: variables.$color-rojo; 100 | color: #fff; 101 | &:hover { 102 | background: variables.$color-rojo-hover; 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/sass/_generales.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | background: variables.$color-fondo; 11 | font-family: variables.$fuente-primaria; 12 | font-size: 16px; 13 | min-height: 100vh; 14 | display: flex; 15 | align-items: center; 16 | } 17 | 18 | .contenedor { 19 | position: relative; 20 | z-index: 1; 21 | width: 90%; 22 | max-width: 400px; 23 | height: 80vh; 24 | margin: auto; 25 | background: #000; 26 | border-radius: 20px; 27 | 28 | display: grid; 29 | grid-template-rows: auto 1fr auto; 30 | } 31 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/sass/_header.scss: -------------------------------------------------------------------------------- 1 | .total-gastado { 2 | padding: 20px 0; 3 | text-align: center; 4 | color: #fff; 5 | &__leyenda { 6 | margin-bottom: 5px; 7 | } 8 | &__cantidad { 9 | width: 100%; 10 | font-size: 24px; 11 | font-weight: 700; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/sass/_main.scss: -------------------------------------------------------------------------------- 1 | main { 2 | max-height: 100%; 3 | position: relative; 4 | overflow: hidden; 5 | } 6 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | $fuente-primaria: 'Inter', sans-serif; 2 | $color-fondo: #eeeeee; 3 | $color-primario: #92a55d; 4 | $color-primario-hover: #80934b; 5 | $color-fecha: #9a9a9a; 6 | $color-gris-claro: #eeeeee; 7 | $color-gris-claro-hover: #dfdfdf; 8 | $color-rojo: #f1441e; 9 | $color-rojo-hover: #d13715; 10 | $color-gris-oscuro: #3f3f3f; 11 | $color-gris-oscuro-hover: #313131; 12 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/sass/index.scss: -------------------------------------------------------------------------------- 1 | @use 'generales'; 2 | @use 'header'; 3 | @use 'main'; 4 | @use 'gastos'; 5 | @use 'formulario-gasto'; 6 | @use 'footer'; 7 | @use 'fondo'; 8 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/src/cargarTotalGastado.js: -------------------------------------------------------------------------------- 1 | import isThisMonth from 'date-fns/isThisMonth'; 2 | import { parseISO } from 'date-fns'; 3 | 4 | const cargarTotalGastado = () => { 5 | const contenedorTotalGastado = document.getElementById('total-gastado'); 6 | const gastos = JSON.parse(window.localStorage.getItem('gastos')); 7 | let total = 0; 8 | 9 | if (gastos) { 10 | const gastosDelMes = gastos.filter((gasto) => { 11 | if (isThisMonth(parseISO(gasto.fecha))) { 12 | return gasto; 13 | } 14 | }); 15 | 16 | if (gastosDelMes) { 17 | gastosDelMes.forEach((gasto) => { 18 | total += parseFloat(gasto.precio); 19 | }); 20 | } 21 | } 22 | // Formateamos el numero y lo agregamos al contenedor. 23 | const formatoMoneda = new Intl.NumberFormat('en-MX', { style: 'currency', currency: 'MXN' }); 24 | contenedorTotalGastado.innerText = formatoMoneda.format(total); 25 | }; 26 | 27 | export default cargarTotalGastado; 28 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/src/eventoBtnFormularioGasto.js: -------------------------------------------------------------------------------- 1 | const boton = document.getElementById('toggle-form-gasto'); 2 | const formularioGasto = document.getElementById('formulario-gasto'); 3 | 4 | // Funcion que cierra el formulario 5 | const cerrarFormularioGasto = () => { 6 | // Ponemos el boton de cerrar y ocultamos el formulario 7 | boton.classList.remove('agregar-gasto__btn--active'); 8 | formularioGasto.classList.remove('formulario-gasto--active'); 9 | }; 10 | 11 | // Funcion que abre el formulario 12 | const abrirFormularioGasto = (modo = 'agregarGasto') => { 13 | // Ponemos el boton de abrir y mostramos el formulario 14 | boton.classList.add('agregar-gasto__btn--active'); 15 | formularioGasto.classList.add('formulario-gasto--active'); 16 | 17 | // Si abrimos el formulario en modo editarGasto cambiamos los textos. 18 | if (modo === 'editarGasto') { 19 | // Agregamos un dataset al formulario para indicar el modo. 20 | document.getElementById('formulario-gasto').dataset.modo = 'editarGasto'; 21 | // Cambiamos los textos del titulo y boton. 22 | document.querySelector('.formulario-gasto__titulo').innerText = 'Editar Gasto'; 23 | document.querySelector('.formulario-gasto__btn').innerText = 'Editar Gasto'; 24 | // Salimos paramos la ejecución del resto de la funcion. 25 | return; 26 | } 27 | 28 | // Agregamos un dataset al formulario para indicar el modo. 29 | document.getElementById('formulario-gasto').dataset.modo = 'agregarGasto'; 30 | // Cambiamos los textos del titulo y boton. 31 | document.querySelector('.formulario-gasto__titulo').innerText = 'Agregar Gasto'; 32 | document.querySelector('.formulario-gasto__btn').innerText = 'Agregar Gasto'; 33 | }; 34 | 35 | boton.addEventListener('click', (e) => { 36 | e.preventDefault(); 37 | 38 | // Pasamos la lista de clases a un arreglo y comprobamos si tiene la clase active. 39 | if ([...formularioGasto.classList].includes('formulario-gasto--active')) { 40 | cerrarFormularioGasto(); 41 | } else { 42 | abrirFormularioGasto(); 43 | } 44 | }); 45 | 46 | export { cerrarFormularioGasto, abrirFormularioGasto }; 47 | -------------------------------------------------------------------------------- /Proyectos/App_gastos/src/index.js: -------------------------------------------------------------------------------- 1 | import './eventosGasto'; 2 | import './eventoBtnFormularioGasto'; 3 | import './agregarGasto'; 4 | import cargarGastos from './cargarGastos'; 5 | import cargarTotalGastado from './cargarTotalGastado'; 6 | 7 | cargarGastos(); 8 | cargarTotalGastado(); 9 | -------------------------------------------------------------------------------- /Proyectos/Formulario/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Formulario", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "fsevents": { 8 | "version": "2.3.2", 9 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 10 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 11 | "dev": true, 12 | "optional": true 13 | }, 14 | "rollup": { 15 | "version": "2.78.0", 16 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.0.tgz", 17 | "integrity": "sha512-4+YfbQC9QEVvKTanHhIAFVUFSRsezvQF8vFOJwtGfb9Bb+r014S+qryr9PSmw8x6sMnPkmFBGAvIFVQxvJxjtg==", 18 | "dev": true, 19 | "requires": { 20 | "fsevents": "~2.3.2" 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Proyectos/Formulario/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Formulario", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "sass": "sass --watch --style=compressed sass/index.scss public/bundle.css", 9 | "build": "rollup --watch --config --sourcemap" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "rollup": "^2.78.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Proyectos/Formulario/public/bundle.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sourceRoot":"","sources":["../sass/_generales.scss","../sass/_variables.scss","../sass/_formulario.scss","../sass/linea-pasos.scss","../sass/alerta.scss"],"names":[],"mappings":"AAEA,EACC,SACA,UACA,sBAGD,KACC,YCTiB,oBDUjB,eACA,iBACA,aACA,mBACA,WCba,QDcb,WACA,YChBiB,oBDmBlB,YACC,UACA,gBACA,YEpBD,uBACC,KACC,WAED,GACC,UAIF,YACC,WDVwB,QCWxB,yBACA,mBACA,aACA,iCACA,SACA,wBAEA,oBACC,aAGD,oBACC,aACA,sBACA,SACA,yBAGD,kBACC,wBACA,aACA,iBACA,gBACA,6BAGD,qBACC,eACA,wBACA,eACA,sBAEA,aACA,uBACA,6BACC,aAIF,oBACC,aACA,uBACA,oBAGD,oBACC,eACA,kBACA,gBAGD,uBACC,eACA,gBACA,kBACA,mBAGD,0BACC,aACA,uBACA,SAGD,yBACC,aACA,sBACA,mBACA,WAGD,mBACC,eACA,mBAGD,mBACC,YACA,WACA,gBACA,aACA,mBACA,kBACA,WD9FuB,QC+FvB,yBACA,aACA,YDnGgB,oBCoGhB,eACA,WACA,kBACA,yBACC,yBAGD,0BACC,qBACA,gCACC,qBAKH,+CACC,cAGD,qBACC,gBACA,eACA,aAGD,iBACC,WDzHe,QC0Hf,YACA,aACA,SACA,mBACA,8BACA,eACA,eACA,YDtIgB,oBCuIhB,eACA,gBACA,YACA,YACA,kBACA,gBAEA,2BACC,kBAWA,WDpJ4B,QC0I5B,kCACC,WACA,kBACA,OACA,SACA,WACA,WACA,gBACA,2CAMH,kCACC,aACA,mBACA,WACA,YACA,0CACC,aAIF,uBACC,WACA,YAGD,4BACC,aACA,SACA,uBAGD,yBACC,aAIA,iEACC,WACA,cACA,WACA,YACA,mBACA,WDzLc,QC0Ld,kBACA,UAIF,yBACC,YACA,WACA,aACA,mBACA,yBACA,kBACA,eACA,wBACA,kBACA,eACA,iCACC,WACA,cACA,kBACA,UACA,YACA,WACA,mBACA,yBAIF,sBACC,iBACA,kBC3NF,aACC,aACA,8BACA,kBACA,kBACA,eAEA,mBAEC,aACA,sBACA,mBACA,gCACC,uBAED,qCACC,qBAIF,yBACC,cACA,WFlB6B,QEmB7B,YACA,WACA,mBACA,mBACA,kBACA,UAEA,kCACC,eACA,WF7Bc,QE8Bd,4DACC,cAIF,iCACC,WFpCc,QEqCd,wCACC,WACA,cACA,WACA,YACA,mBACA,WF3Ca,QE4Cb,yBACA,kBACA,QACA,SACA,gCAKH,0BACC,aACA,kBACA,QACA,SACA,WAGD,uBACC,kBACA,SACA,WACA,WACA,UACA,WFnEe,QGHjB,QACC,aACA,WHFwB,QGGxB,yBACA,mBACA,sBACA,mBACA,uBACA,SACA,kBACA,aAEA,gBACC,aAGD,gBACC,eAGD,eACC,MHlBe,QGmBf,YACA","file":"bundle.css"} -------------------------------------------------------------------------------- /Proyectos/Formulario/rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | input: 'src/index.js', 3 | output: { 4 | file: 'public/bundle.js', 5 | format: 'cjs', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /Proyectos/Formulario/sass/_generales.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | font-family: variables.$fuente-primaria; 11 | font-size: 16px; 12 | min-height: 100vh; 13 | display: flex; 14 | align-items: center; 15 | background: variables.$color-fondo; 16 | color: #fff; 17 | font-family: variables.$fuente-primaria; 18 | } 19 | 20 | .contenedor { 21 | width: 90%; 22 | max-width: 640px; 23 | margin: auto; 24 | } 25 | -------------------------------------------------------------------------------- /Proyectos/Formulario/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | $fuente-primaria: 'Roboto', sans-serif; 2 | $color-fondo: #0d0923; 3 | $color-fondo-formulario: #131028; 4 | $color-borde: #30295a; 5 | $color-borde-activo: #4f4a72; 6 | $color-primario: #d1d42f; 7 | $color-primario-deshabilitado: #434408; 8 | -------------------------------------------------------------------------------- /Proyectos/Formulario/sass/alerta.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .alerta { 4 | display: none; 5 | background: variables.$color-fondo-formulario; 6 | border: 1px solid variables.$color-borde; 7 | border-radius: 10px; 8 | flex-direction: column; 9 | align-items: center; 10 | justify-content: center; 11 | gap: 30px; 12 | text-align: center; 13 | padding: 30px; 14 | 15 | &--active { 16 | display: flex; 17 | } 18 | 19 | &__titulo { 20 | font-size: 24px; 21 | } 22 | 23 | &__icono { 24 | color: variables.$color-primario; 25 | height: 80px; 26 | width: 80px; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Proyectos/Formulario/sass/index.scss: -------------------------------------------------------------------------------- 1 | @use 'generales'; 2 | @use 'formulario'; 3 | @use 'linea-pasos'; 4 | @use 'alerta'; 5 | -------------------------------------------------------------------------------- /Proyectos/Formulario/sass/linea-pasos.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .linea-pasos { 4 | display: flex; 5 | justify-content: space-between; 6 | text-align: center; 7 | position: relative; 8 | font-size: 14px; 9 | 10 | &__paso { 11 | // cursor: pointer; 12 | display: flex; 13 | flex-direction: column; 14 | align-items: center; 15 | &:nth-child(1) { 16 | align-items: flex-start; 17 | } 18 | &:nth-last-child(2) { 19 | align-items: flex-end; 20 | } 21 | } 22 | 23 | &__paso-check { 24 | display: block; 25 | background: variables.$color-primario-deshabilitado; 26 | height: 30px; 27 | width: 30px; 28 | border-radius: 30px; 29 | margin-bottom: 10px; 30 | position: relative; 31 | z-index: 2; 32 | 33 | &--checked { 34 | cursor: pointer; 35 | background: variables.$color-primario; 36 | .linea-pasos__icono-check { 37 | display: block; 38 | } 39 | } 40 | 41 | &--active { 42 | background: variables.$color-primario; 43 | &::after { 44 | content: ''; 45 | display: block; 46 | width: 14px; 47 | height: 14px; 48 | border-radius: 14px; 49 | background: variables.$color-primario; 50 | border: 4px solid variables.$color-fondo-formulario; 51 | position: relative; 52 | top: 50%; 53 | left: 50%; 54 | transform: translate(-50%, -50%); 55 | } 56 | } 57 | } 58 | 59 | &__icono-check { 60 | display: none; 61 | position: absolute; 62 | top: 8px; 63 | left: 7px; 64 | color: #000; 65 | } 66 | 67 | &__progreso { 68 | position: absolute; 69 | top: 15px; 70 | width: 100%; 71 | height: 2px; 72 | z-index: 1; 73 | background: variables.$color-primario; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Proyectos/Formulario/src/index.js: -------------------------------------------------------------------------------- 1 | import './lineaPasos'; 2 | import './formulario'; 3 | -------------------------------------------------------------------------------- /Proyectos/Formulario/src/marcarPaso.js: -------------------------------------------------------------------------------- 1 | const marcarPaso = (paso) => { 2 | document 3 | .querySelector(`.linea-pasos [data-paso="${paso}"] .linea-pasos__paso-check`) 4 | .classList.add('linea-pasos__paso-check--checked'); 5 | }; 6 | 7 | export default marcarPaso; 8 | -------------------------------------------------------------------------------- /Proyectos/Formulario/src/siguientePaso.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Funcion que navega al siguiente paso. 3 | */ 4 | const siguientePaso = () => { 5 | // Creamos un arreglo con los pasos. 6 | const pasos = [...document.querySelectorAll('.linea-pasos__paso')]; 7 | 8 | // Obtenemos el paso activo. 9 | const pasoActivo = document.querySelector('.linea-pasos__paso-check--active').closest('.linea-pasos__paso'); 10 | 11 | // Obtenemos el index del paso activo. 12 | const indexPasoActivo = pasos.indexOf(pasoActivo); 13 | 14 | // Comprobamos si hay mas pasos. 15 | if (indexPasoActivo < pasos.length - 1) { 16 | // Eliminamos la clase de paso activo. 17 | pasoActivo.querySelector('span').classList.remove('linea-pasos__paso-check--active'); 18 | // Ponemos la clase de paso activo al siguiente elemento. 19 | pasos[indexPasoActivo + 1].querySelector('span').classList.add('linea-pasos__paso-check--active'); 20 | 21 | // Mostramos el siguiente elemento. 22 | const id = pasos[indexPasoActivo + 1].dataset.paso; 23 | 24 | document.querySelector(`.formulario__body [data-paso="${id}"]`).scrollIntoView({ 25 | inline: 'start', 26 | behavior: 'smooth', 27 | }); 28 | } 29 | }; 30 | 31 | export default siguientePaso; 32 | -------------------------------------------------------------------------------- /Proyectos/Formulario/src/validaciones/validarCantidad.js: -------------------------------------------------------------------------------- 1 | const validarCantidad = () => { 2 | // Aceptamos cualquier digito (0-9), y un punto con decimales (opcional) 3 | const expRegCantidad = /^\d+(\.\d+)?$/; 4 | 5 | // Obtenemos el input cantidad 6 | const inputCantidad = formulario.cantidad; 7 | 8 | // Transformamos la cantidad de una cadena de texto a numero con decimales. 9 | // y comprobamos si es una cantidad correcta 10 | if (expRegCantidad.test(inputCantidad.value)) { 11 | inputCantidad.classList.remove('formulario__input--error'); 12 | return true; 13 | } else { 14 | inputCantidad.classList.add('formulario__input--error'); 15 | return false; 16 | } 17 | }; 18 | 19 | export default validarCantidad; 20 | -------------------------------------------------------------------------------- /Proyectos/Formulario/src/validaciones/validarCorreo.js: -------------------------------------------------------------------------------- 1 | const validarCorreo = () => { 2 | // Expresion regular para validar un correo. 3 | const expRegCorreo = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/; 4 | 5 | // Obtenemos los inputs 6 | const inputCorreo = formulario['correo-receptor']; 7 | 8 | // Comprobamos que el nombre y correo sean correctos. 9 | if (!expRegCorreo.test(inputCorreo.value)) { 10 | inputCorreo.classList.add('formulario__input--error'); 11 | return false; 12 | } else { 13 | inputCorreo.classList.remove('formulario__input--error'); 14 | return true; 15 | } 16 | }; 17 | 18 | export default validarCorreo; 19 | -------------------------------------------------------------------------------- /Proyectos/Formulario/src/validaciones/validarNombre.js: -------------------------------------------------------------------------------- 1 | const validarNombre = () => { 2 | // Aceptamos cualquier digito (0-9), y un punto con decimales (opcional) 3 | const expRegNombre = /^[a-zA-ZÀ-ÿ\s]{1,40}$/; 4 | 5 | // Obtenemos el input 6 | const inputNombre = formulario['nombre-receptor']; 7 | 8 | // Comprobamos que el nombre sea correcto. 9 | if (!expRegNombre.test(inputNombre.value)) { 10 | inputNombre.classList.add('formulario__input--error'); 11 | return false; 12 | } else { 13 | inputNombre.classList.remove('formulario__input--error'); 14 | return true; 15 | } 16 | }; 17 | 18 | export default validarNombre; 19 | -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/1.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/10.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/2.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/3.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/4.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/5.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/6.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/7.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/8.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/africa/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/africa/9.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/1.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/10.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/2.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/3.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/4.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/5.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/6.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/7.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/8.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/america/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/america/9.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida/1.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida/2.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida/3.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida/4.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida/5.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida/6.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida/7.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida/8.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/antartida/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/antartida/9.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/1.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/10.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/2.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/3.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/4.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/5.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/6.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/7.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/8.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/asia/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/asia/9.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/bg.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/1.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/10.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/2.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/3.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/4.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/5.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/6.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/7.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/8.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/europa/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/europa/9.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/1.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/10.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/2.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/3.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/4.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/5.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/6.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/7.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/8.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/img/oceania/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Galeria/img/oceania/9.jpg -------------------------------------------------------------------------------- /Proyectos/Galeria/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "galeria", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "fsevents": { 8 | "version": "2.3.2", 9 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 10 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 11 | "dev": true, 12 | "optional": true 13 | }, 14 | "rollup": { 15 | "version": "2.77.0", 16 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz", 17 | "integrity": "sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==", 18 | "dev": true, 19 | "requires": { 20 | "fsevents": "~2.3.2" 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Proyectos/Galeria/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "galeria", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "sass": "sass --watch --style=compressed sass/index.scss public/bundle.css", 9 | "build": "rollup --watch --config" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "rollup": "^2.77.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Proyectos/Galeria/public/bundle.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sourceRoot":"","sources":["../sass/_generales.scss","../sass/_variables.scss","../sass/_hero.scss","../sass/_categorias.scss","../sass/_galeria.scss","../sass/_footer.scss"],"names":[],"mappings":"AAEA,EACC,SACA,UACA,sBAGD,KACC,WCPa,QDQb,YCVqB,uBDWrB,eACA,WAGD,YACC,UACA,iBACA,YAGD,EACC,qBACA,WAGD,qBAEC,aE1BD,MACC,WACA,aACA,aACA,sBACA,mBACA,uGACA,kCACA,sBACA,kBACA,YDXuB,yBCYvB,kBAEA,cACC,eACA,mBACA,YDfY,4BCkBb,iBACC,eACA,mBACA,YDrBY,4BEDd,YACC,aACA,qCACA,SACA,kBACA,WAGD,WACC,aACA,sBACA,yBACA,mBACA,kBACA,kBAEA,kBACC,WACA,cACA,WACA,YACA,gFACA,kBACA,MACA,OACA,UAEA,4BACA,UAIA,wBACC,WAIF,gBACC,WACA,mBACA,kBAGD,kBACC,kBACA,SACA,WACA,UAGD,mBACC,YFpDsB,yBEqDtB,eACA,kBACA,YFrDY,4BEwDb,yBACC,eACA,mBACA,YF3DY,4BGDd,SACC,aAEA,iBACC,cAGD,kBACC,2BACA,eACA,MACA,OACA,WACA,aACA,YACA,cAGD,qBACC,UACA,iBACA,YACA,eACA,aACA,aACA,iCACA,SACA,kBAGD,4BACC,aACA,8BACA,qBAGD,iBACC,YHtCsB,yBGuCtB,eACA,mBAGD,cACC,gBACA,YACA,WACA,WACA,YACA,eAEA,wBACC,kBACA,SACA,qBAGD,yBACC,kBACA,UACA,qBAIF,sBACC,YACA,WAGD,mCACC,aACA,uBACA,gBAGD,oCACC,eACA,iBACA,mBAGD,mBACC,aACA,oCACA,SACA,mBAGD,qDAEC,aACA,mBACA,qEACC,aAIF,0BACC,WACA,aACA,SACA,cACA,6BAGD,yBACC,cACA,wBACA,+BAEA,iCACC,sBAGF,yBACC,iBACA,mBCnHF,OACC,aACA,uBACA,SACA,mBAEA,cACC,WACA,WACA,YACA,wBAEA,oBACC,WAKH,UACC,YJpBuB,yBIqBvB,eACA,kBACA,oBACA","file":"bundle.css"} -------------------------------------------------------------------------------- /Proyectos/Galeria/rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | input: 'src/index.js', 3 | output: { 4 | file: 'public/bundle.js', 5 | format: 'cjs', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /Proyectos/Galeria/sass/_categorias.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .categorias { 4 | display: grid; 5 | grid-template-columns: repeat(3, 1fr); 6 | gap: 20px; 7 | position: relative; 8 | top: -150px; 9 | } 10 | 11 | .categoria { 12 | display: flex; 13 | flex-direction: column; 14 | justify-content: flex-end; 15 | align-items: center; 16 | text-align: center; 17 | position: relative; 18 | 19 | &::after { 20 | content: ''; 21 | display: block; 22 | width: 100%; 23 | height: 100%; 24 | background: linear-gradient(to bottom, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 1) 100%); 25 | position: absolute; 26 | top: 0; 27 | left: 0; 28 | z-index: 0; 29 | 30 | transition: 0.3s ease-out all; 31 | opacity: 1; 32 | } 33 | 34 | &:hover { 35 | &::after { 36 | opacity: 0.5; 37 | } 38 | } 39 | 40 | &__img { 41 | width: 100%; 42 | vertical-align: top; 43 | position: relative; 44 | } 45 | 46 | &__datos { 47 | position: absolute; 48 | bottom: 0; 49 | width: 100%; 50 | z-index: 1; 51 | } 52 | 53 | &__nombre { 54 | font-family: variables.$secondary-font-family; 55 | font-size: 34px; 56 | margin-bottom: 5px; 57 | text-shadow: variables.$text-shadow; 58 | } 59 | 60 | &__numero-fotos { 61 | font-size: 16px; 62 | margin-bottom: 20px; 63 | text-shadow: variables.$text-shadow; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Proyectos/Galeria/sass/_footer.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .redes { 4 | display: flex; 5 | justify-content: center; 6 | gap: 40px; 7 | margin-bottom: 20px; 8 | 9 | &__icono { 10 | color: #888888; 11 | width: 30px; 12 | height: 30px; 13 | transition: 0.3s ease all; 14 | 15 | &:hover { 16 | color: #fff; 17 | } 18 | } 19 | } 20 | 21 | .creditos { 22 | font-family: variables.$secondary-font-family; 23 | font-size: 16px; 24 | text-align: center; 25 | margin-bottom: 150px; 26 | color: #888888; 27 | } 28 | -------------------------------------------------------------------------------- /Proyectos/Galeria/sass/_galeria.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .galeria { 4 | display: none; 5 | 6 | &--active { 7 | display: block; 8 | } 9 | 10 | &__overlay { 11 | background: rgba(0, 0, 0, 0.95); 12 | position: fixed; 13 | top: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 100vh; 17 | z-index: 100; 18 | overflow: auto; 19 | } 20 | 21 | &__contenedor { 22 | width: 90%; 23 | max-width: 1050px; 24 | margin: auto; 25 | padding: 40px 0; 26 | display: grid; 27 | height: 100vh; 28 | grid-template-rows: auto 1fr auto; 29 | gap: 20px; 30 | position: relative; 31 | } 32 | 33 | &__contenedor-titulo { 34 | display: flex; 35 | justify-content: space-between; 36 | align-items: flex-end; 37 | } 38 | 39 | &__titulo { 40 | font-family: variables.$secondary-font-family; 41 | font-size: 24px; 42 | font-weight: normal; 43 | } 44 | 45 | &__btn { 46 | background: none; 47 | border: none; 48 | color: #fff; 49 | width: 40px; 50 | height: 40px; 51 | cursor: pointer; 52 | 53 | &--anterior { 54 | position: absolute; 55 | left: -5%; 56 | top: calc(50% - 20px); 57 | } 58 | 59 | &--siguiente { 60 | position: absolute; 61 | right: -5%; 62 | top: calc(50% - 20px); 63 | } 64 | } 65 | 66 | &__icono-boton { 67 | height: 100%; 68 | width: 100%; 69 | } 70 | 71 | &__contenedor-imagen-activa { 72 | display: flex; 73 | justify-content: center; 74 | overflow: hidden; 75 | } 76 | 77 | &__descripcion-imagen-activa { 78 | font-size: 16px; 79 | line-height: 24px; 80 | margin-bottom: 10px; 81 | } 82 | 83 | &__carousel { 84 | display: grid; 85 | grid-template-columns: auto 1fr auto; 86 | gap: 10px; 87 | align-items: center; 88 | } 89 | 90 | &__carousel-atras, 91 | &__carousel-adelante { 92 | display: flex; 93 | align-items: center; 94 | &--active { 95 | display: flex; 96 | } 97 | } 98 | 99 | &__carousel-slides { 100 | width: 100%; 101 | display: flex; 102 | gap: 10px; 103 | overflow: auto; 104 | scroll-snap-type: x mandatory; 105 | } 106 | 107 | &__carousel-slide { 108 | display: block; 109 | scroll-snap-align: start; 110 | border: 1px solid transparent; 111 | 112 | &--active { 113 | border: 1px solid #fff; 114 | } 115 | } 116 | &__carousel-image { 117 | max-height: 100px; 118 | vertical-align: top; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Proyectos/Galeria/sass/_generales.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | background: variables.$color-fondo; 11 | font-family: variables.$primary-font-family; 12 | font-size: 16px; 13 | color: #fff; 14 | } 15 | 16 | .contenedor { 17 | width: 90%; 18 | max-width: 1050px; 19 | margin: auto; 20 | } 21 | 22 | a { 23 | text-decoration: none; 24 | color: #fff; 25 | } 26 | 27 | a:focus, 28 | button:focus { 29 | outline: none; 30 | } 31 | -------------------------------------------------------------------------------- /Proyectos/Galeria/sass/_hero.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .hero { 4 | width: 100%; 5 | height: 600px; 6 | display: flex; 7 | flex-direction: column; 8 | align-items: center; 9 | background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(16, 16, 16, 1) 95%), url('./../img/bg.jpg'); 10 | background-position: center center; 11 | background-size: cover; 12 | position: relative; 13 | font-family: variables.$secondary-font-family; 14 | padding-top: 180px; 15 | 16 | &__titulo { 17 | font-size: 40px; 18 | font-weight: normal; 19 | text-shadow: variables.$text-shadow; 20 | } 21 | 22 | &__subtitulo { 23 | font-size: 22px; 24 | font-weight: normal; 25 | text-shadow: variables.$text-shadow; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Proyectos/Galeria/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | $primary-font-family: 'Open Sans', sans-serif; 2 | $secondary-font-family: 'Playfair Display', serif; 3 | $color-fondo: #101010; 4 | $text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); 5 | -------------------------------------------------------------------------------- /Proyectos/Galeria/sass/index.scss: -------------------------------------------------------------------------------- 1 | @use 'generales'; 2 | @use 'hero'; 3 | @use 'categorias'; 4 | @use 'galeria'; 5 | @use 'footer'; 6 | -------------------------------------------------------------------------------- /Proyectos/Galeria/src/cargarCategorias.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Archivo que se encarga de cargar las categorias. 3 | */ 4 | 5 | import dataCategorias from './data/categorias'; 6 | const { categorias } = dataCategorias; 7 | const contenedorCategorias = document.getElementById('categorias'); 8 | 9 | // Cargamos las categorias en la pagina principal. 10 | categorias.forEach((categoria) => { 11 | const nuevaCategoria = document.createElement('a'); 12 | const plantilla = ` 13 | 14 |
15 |

${categoria.nombre}

16 |

${categoria.numeroFotos} Fotos

17 |
18 | `; 19 | 20 | // Agregamos la clase, href, dataset y la plantilla a la nueva categoria. 21 | nuevaCategoria.classList.add('categoria'); 22 | nuevaCategoria.href = '#'; 23 | nuevaCategoria.dataset.categoria = categoria.id; 24 | nuevaCategoria.innerHTML = plantilla; 25 | 26 | // Agregamos la categoria al contenedor de las categorias. 27 | contenedorCategorias.append(nuevaCategoria); 28 | }); 29 | -------------------------------------------------------------------------------- /Proyectos/Galeria/src/data/categorias.js: -------------------------------------------------------------------------------- 1 | import data from './fotos'; 2 | const { fotos } = data; 3 | 4 | export default { 5 | categorias: [ 6 | { id: 'america', nombre: 'America', numeroFotos: fotos['america'].length, imagenPortada: './img/america.jpg' }, 7 | { id: 'europa', nombre: 'Europa', numeroFotos: fotos['europa'].length, imagenPortada: './img/europa.jpg' }, 8 | { id: 'africa', nombre: 'África', numeroFotos: fotos['africa'].length, imagenPortada: './img/africa.jpg' }, 9 | { id: 'asia', nombre: 'Asia', numeroFotos: fotos['asia'].length, imagenPortada: './img/asia.jpg' }, 10 | { id: 'oceania', nombre: 'Oceania', numeroFotos: fotos['oceania'].length, imagenPortada: './img/oceania.jpg' }, 11 | { 12 | id: 'antartida', 13 | nombre: 'Antártida', 14 | numeroFotos: fotos['antartida'].length, 15 | imagenPortada: './img/antartida.jpg', 16 | }, 17 | ], 18 | }; 19 | -------------------------------------------------------------------------------- /Proyectos/Galeria/src/eventoCategorias.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Archivo que se encarga del evento de las categorias. 3 | */ 4 | 5 | import dataFotos from './data/fotos'; 6 | import { cargarImagen } from './galeria/cargarImagen'; 7 | 8 | const contenedorCategorias = document.getElementById('categorias'); 9 | const galeria = document.getElementById('galeria'); 10 | let categoriaActiva; 11 | 12 | // Agregamos el event listener a las categorias. 13 | contenedorCategorias.addEventListener('click', (e) => { 14 | e.preventDefault(); 15 | 16 | // Comprobamos que lo que se le hace click contenga el data-categoria. 17 | if (e.target.closest('a')) { 18 | categoriaActiva = e.target.closest('a').dataset.categoria; 19 | galeria.dataset.categoria = categoriaActiva; 20 | // Obtenemos las fotos que corresponden a la categoria 21 | const fotos = dataFotos.fotos[categoriaActiva]; 22 | const carousel = galeria.querySelector('.galeria__carousel-slides'); 23 | 24 | // Reiniciamos el carousel 25 | carousel.innerHTML = ''; 26 | 27 | // Agregamos un overflow hidden al body. 28 | document.body.style.overflow = 'hidden'; 29 | 30 | // Agregamos la clase active a la galeria. 31 | galeria.classList.add('galeria--active'); 32 | 33 | // Tomamos la informacion de la primera imagen de la categoria y la cargamos en el DOM. 34 | const { id, nombre, ruta, descripcion } = fotos[0]; 35 | cargarImagen(id, nombre, ruta, descripcion); 36 | 37 | // Por cada foto agregamos un slide al carousel. 38 | for (let i = 0; i < fotos.length; i++) { 39 | const slide = ` 40 | 41 | 42 | 43 | `; 44 | 45 | carousel.innerHTML += slide; 46 | } 47 | 48 | // Agregamos la clase active al primer elemento. 49 | galeria.querySelector('.galeria__carousel-slide').classList.add('galeria__carousel-slide--active'); 50 | } 51 | }); 52 | -------------------------------------------------------------------------------- /Proyectos/Galeria/src/galeria/cerrarGaleria.js: -------------------------------------------------------------------------------- 1 | const galeria = document.getElementById('galeria'); 2 | 3 | const cerrarGaleria = () => { 4 | // Agregamos un overflow hidden al body. 5 | document.body.style.overflow = ''; 6 | 7 | // Agregamos la clase active a la galeria. 8 | galeria.classList.remove('galeria--active'); 9 | }; 10 | 11 | export default cerrarGaleria; 12 | -------------------------------------------------------------------------------- /Proyectos/Galeria/src/galeria/eventosGaleria.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Archivo que se encarga de administrar los eventos de la galeria. 3 | */ 4 | 5 | import slideClick from './slideClick'; 6 | import cerrarGaleria from './cerrarGaleria'; 7 | import carousel from './carousel'; 8 | import { cargarAnteriorSiguiente } from './cargarImagen'; 9 | 10 | const galeria = document.getElementById('galeria'); 11 | 12 | // Agregamos event listener a la galeria 13 | galeria.addEventListener('click', (e) => { 14 | e.preventDefault(); 15 | 16 | const boton = e.target.closest('button'); 17 | 18 | // - - - CERRAR GALERIA 19 | // Accedemos al boton mas cercano. Esto para evitar obtener el svg o path. 20 | // Si tiene un dataset y un accion y es igual a cerrar-galeria, cerramos la galeria. 21 | if (boton?.dataset?.accion === 'cerrar-galeria' || e.target?.dataset?.accion === 'cerrar-galeria') { 22 | cerrarGaleria(); 23 | } 24 | 25 | // - - - SIGUIENTE IMAGEN 26 | if (boton?.dataset?.accion === 'siguiente-imagen') { 27 | cargarAnteriorSiguiente('siguiente'); 28 | } 29 | 30 | // - - - ANTERIOR IMAGEN 31 | if (boton?.dataset?.accion === 'anterior-imagen') { 32 | cargarAnteriorSiguiente('anterior'); 33 | } 34 | 35 | // - - - CAROUSEL SLIDE CLICK 36 | // Comprobamos si el elemento tiene un data set y se llama idFoto. 37 | if (e.target?.dataset?.idFoto) { 38 | slideClick(e); 39 | } 40 | 41 | // - - - CAROUSEL ADELANTE 42 | // Comprobamos que el elemento clickeado sea un boton y tenga el data-action="siguiente-slide" 43 | if (boton && boton?.dataset.accion === 'siguiente-slide') { 44 | carousel('adelante'); 45 | } 46 | 47 | // - - - CAROUSEL ATRAS 48 | // Comprobamos que el elemento clickeado sea un boton y tenga el data-action="anterior-slide" 49 | if (boton && boton?.dataset.accion === 'anterior-slide') { 50 | carousel('atras'); 51 | } 52 | }); 53 | -------------------------------------------------------------------------------- /Proyectos/Galeria/src/galeria/slideClick.js: -------------------------------------------------------------------------------- 1 | import data from '../data/fotos'; 2 | import { cargarImagen } from './cargarImagen'; 3 | 4 | const galeria = document.getElementById('galeria'); 5 | 6 | const slideClick = (e) => { 7 | // Obtenemos la categoria activa de la galeria. 8 | const categoriaActiva = galeria.dataset.categoria; 9 | 10 | // Obtenemos la ruta de la imagen accediendo al objeto de fotos y comparando el id del slide con el de las fotos. 11 | let id; 12 | let ruta; 13 | let nombre; 14 | let descripcion; 15 | 16 | data.fotos[categoriaActiva].forEach((foto) => { 17 | if (foto.id === parseInt(e.target.dataset.idFoto)) { 18 | id = foto.id; 19 | ruta = foto.ruta; 20 | nombre = foto.nombre; 21 | descripcion = foto.descripcion; 22 | } 23 | }); 24 | 25 | // Cargamos toda la informacion de la nueva imagen 26 | cargarImagen(id, nombre, ruta, descripcion); 27 | }; 28 | 29 | export default slideClick; 30 | -------------------------------------------------------------------------------- /Proyectos/Galeria/src/index.js: -------------------------------------------------------------------------------- 1 | import './cargarCategorias'; 2 | import './eventoCategorias'; 3 | import './galeria/eventosGaleria'; 4 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/1.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/10.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/11.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/12.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/13.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/14.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/15.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/16.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/2.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/3.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/4.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/5.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/6.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/7.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/8.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/9.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Peliculas/img/logo.png -------------------------------------------------------------------------------- /Proyectos/Peliculas/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "peliculas", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "peliculas", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "rollup": "^2.79.1" 13 | } 14 | }, 15 | "node_modules/fsevents": { 16 | "version": "2.3.2", 17 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 18 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 19 | "dev": true, 20 | "hasInstallScript": true, 21 | "optional": true, 22 | "os": [ 23 | "darwin" 24 | ], 25 | "engines": { 26 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 27 | } 28 | }, 29 | "node_modules/rollup": { 30 | "version": "2.79.1", 31 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", 32 | "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", 33 | "dev": true, 34 | "bin": { 35 | "rollup": "dist/bin/rollup" 36 | }, 37 | "engines": { 38 | "node": ">=10.0.0" 39 | }, 40 | "optionalDependencies": { 41 | "fsevents": "~2.3.2" 42 | } 43 | } 44 | }, 45 | "dependencies": { 46 | "fsevents": { 47 | "version": "2.3.2", 48 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 49 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 50 | "dev": true, 51 | "optional": true 52 | }, 53 | "rollup": { 54 | "version": "2.79.1", 55 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", 56 | "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", 57 | "dev": true, 58 | "requires": { 59 | "fsevents": "~2.3.2" 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "peliculas", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "rollup.config.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "sass": "sass --watch --style=compressed sass/index.scss public/bundle.css", 9 | "build": "rollup --watch --config --sourcemap" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "rollup": "^2.79.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/public/bundle.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sourceRoot":"","sources":["../sass/_generales.scss","../sass/_variables.scss","../sass/_btn.scss","../sass/_sidebar.scss","../sass/_main.scss","../sass/_media.scss"],"names":[],"mappings":"CAEA,EACC,SACA,UACA,sBAGD,KACC,YCTiB,wBDUjB,eACA,WCVa,QDWb,WAGD,EACC,qBAGD,QACC,qBAGD,YACC,WACA,aACA,gCExBD,KACC,qBACA,kBACA,WACA,YDNiB,wBCOjB,eACA,YACA,WDNW,QCOX,mBACA,gBACA,eACA,aACA,mBACA,uBACA,kBACA,QAEA,YACC,WACA,YAGD,WACC,WDrBiB,QCwBlB,UACC,WAGD,aACC,iBD5BkB,QC6BlB,mBACC,iBD9BiB,QCkCnB,WACC,iBDnCkB,QCoClB,iBACC,iBDpCkB,QEJrB,SACC,WFDc,QEEd,eAEA,eACC,iBACA,UACA,gBAGD,sBACC,WAGD,iBACC,kBACA,mBAGD,kBACC,mBAGD,6BACC,aACA,8BACA,SAGD,eACC,mBAGD,4BACC,aACA,SACA,mBAGD,gBACC,WACA,kBACA,kBACA,WACA,YF9CgB,wBE+ChB,YACA,WF7CU,QE8CV,mBACA,gBACA,eACA,aACA,mBACA,uBACA,aACA,uBACC,sBAIF,iBACC,aACA,mBACA,uBC9DF,MACC,YACA,kBACA,aACA,0BACA,SAEA,eACC,aACA,SAGD,cACC,mBAGD,YACC,aACA,SACA,qCAGD,oBACC,gBACA,kBAGD,mBACC,kBACA,eAGD,iBACC,WACA,mBACA,mBACA,mBACA,WHpCU,QGqCV,iBAGD,kBACC,aACA,uBACA,SC5CF,OACC,0BACA,YACA,aACA,eACA,MACA,OACA,aACA,mBACA,uBAEA,eACC,aAGD,mBACC,WJjBY,QIkBZ,UACA,iBACA,aACA,mBACA,gBACA,aACA,SACA,kBAGD,YACC,gBACA,eACA,YACA,WACA,kBACA,WACA,SACA,WACA,YAGD,kBACC,WACA,YAGD,iBACC,kBACA,WACA,YACA,MACA,OACA,UACA,gBAGD,uBACC,WACA,YACA,WACA,mBAGD,eACC,kBACA,UAGD,aACC,aACA,sBACA,SACA,kBACA,UAGD,cACC,eACA,mBAGD,iBACC,iBAGD,eACC","file":"bundle.css"} -------------------------------------------------------------------------------- /Proyectos/Peliculas/rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | input: 'src/index.js', 3 | output: { 4 | file: 'public/bundle.js', 5 | format: 'cjs', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/sass/_btn.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .btn { 4 | display: inline-block; 5 | padding: 10px 15px; 6 | color: #fff; 7 | font-family: variables.$fuente-primaria; 8 | cursor: pointer; 9 | border: none; 10 | background: variables.$color-btn; 11 | border-radius: 50px; 12 | font-weight: 600; 13 | font-size: 14px; 14 | display: flex; 15 | align-items: center; 16 | justify-content: center; 17 | text-align: center; 18 | gap: 8px; 19 | 20 | &__icono { 21 | width: 16px; 22 | height: 16px; 23 | } 24 | 25 | &:hover { 26 | background: variables.$color-btn--hover; 27 | } 28 | 29 | &--100 { 30 | width: 100%; 31 | } 32 | 33 | &--active { 34 | background-color: variables.$color-btn--active; 35 | &:hover { 36 | background-color: variables.$color-btn--active; 37 | } 38 | } 39 | 40 | &--rojo { 41 | background-color: variables.$color-btn--active; 42 | &:hover { 43 | background-color: variables.$color-btn--active2; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/sass/_generales.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | font-family: variables.$fuente-primaria; 11 | font-size: 16px; 12 | background: variables.$color-fondo; 13 | color: #fff; 14 | } 15 | 16 | a { 17 | text-decoration: none; 18 | } 19 | 20 | a:hover { 21 | text-decoration: none; 22 | } 23 | 24 | .contenedor { 25 | width: 100%; 26 | display: grid; 27 | grid-template-columns: 300px 1fr; 28 | } 29 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/sass/_main.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .main { 4 | margin: auto; 5 | padding: 40px 80px; 6 | display: grid; 7 | grid-template-columns: 1fr; 8 | gap: 40px; 9 | 10 | &__filtros { 11 | display: flex; 12 | gap: 10px; 13 | } 14 | 15 | &__titulo { 16 | margin-bottom: 20px; 17 | } 18 | 19 | &__grid { 20 | display: grid; 21 | gap: 20px; 22 | grid-template-columns: repeat(6, 1fr); 23 | } 24 | 25 | &__media-titulo { 26 | font-weight: 600; 27 | text-align: center; 28 | } 29 | 30 | &__media-fecha { 31 | text-align: center; 32 | font-size: 14px; 33 | } 34 | 35 | &__media-img { 36 | width: 100%; 37 | vertical-align: top; 38 | border-radius: 10px; 39 | margin-bottom: 10px; 40 | background: variables.$color-btn; 41 | min-height: 170px; 42 | } 43 | 44 | &__paginacion { 45 | display: flex; 46 | justify-content: center; 47 | gap: 20px; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/sass/_media.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .media { 4 | background: rgba(0, 0, 0, 0.8); 5 | width: 100vw; 6 | height: 100vh; 7 | position: fixed; 8 | top: 0; 9 | left: 0; 10 | display: none; 11 | align-items: center; 12 | justify-content: center; 13 | 14 | &--active { 15 | display: flex; 16 | } 17 | 18 | &__contenedor { 19 | background: variables.$color-fondo; 20 | width: 90%; 21 | max-width: 1000px; 22 | padding: 40px; 23 | border-radius: 10px; 24 | overflow: hidden; 25 | display: flex; 26 | gap: 20px; 27 | position: relative; 28 | } 29 | 30 | &__btn { 31 | background: none; 32 | cursor: pointer; 33 | border: none; 34 | color: #fff; 35 | position: absolute; 36 | right: 20px; 37 | top: 20px; 38 | width: 30px; 39 | height: 30px; 40 | } 41 | 42 | &__btn-icono { 43 | width: 100%; 44 | height: 100%; 45 | } 46 | 47 | &__backdrop { 48 | position: absolute; 49 | width: 100%; 50 | height: 100%; 51 | top: 0; 52 | left: 0; 53 | z-index: 0; 54 | background: #000; 55 | } 56 | 57 | &__backdrop-image { 58 | width: 100%; 59 | height: 100%; 60 | opacity: 0.1; 61 | vertical-align: top; 62 | } 63 | 64 | &__imagen { 65 | position: relative; 66 | z-index: 1; 67 | } 68 | 69 | &__info { 70 | display: flex; 71 | flex-direction: column; 72 | gap: 10px; 73 | position: relative; 74 | z-index: 1; 75 | } 76 | 77 | &__fecha { 78 | font-size: 14px; 79 | margin-bottom: 10px; 80 | } 81 | 82 | &__overview { 83 | line-height: 28px; 84 | } 85 | 86 | &__poster { 87 | max-width: 250px; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/sass/_sidebar.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .sidebar { 4 | background: variables.$color-fondo2; 5 | padding: 0 20px; 6 | 7 | &__logo { 8 | margin: 30px auto; 9 | width: 90%; 10 | max-width: 100px; 11 | } 12 | 13 | &__logo-imagen { 14 | width: 100%; 15 | } 16 | 17 | &__titulo { 18 | text-align: center; 19 | margin-bottom: 20px; 20 | } 21 | 22 | &__generos { 23 | margin-bottom: 40px; 24 | } 25 | 26 | &__contenedor-generos { 27 | display: grid; 28 | grid-template-columns: 1fr 1fr; 29 | gap: 10px; 30 | } 31 | 32 | &__años { 33 | margin-bottom: 40px; 34 | } 35 | 36 | &__contenedor-inputs { 37 | display: flex; 38 | gap: 10px; 39 | align-items: center; 40 | } 41 | 42 | &__input { 43 | width: 100%; 44 | text-align: center; 45 | padding: 10px 15px; 46 | color: #fff; 47 | font-family: variables.$fuente-primaria; 48 | border: none; 49 | background: variables.$color-btn; 50 | border-radius: 20px; 51 | font-weight: 600; 52 | font-size: 14px; 53 | display: flex; 54 | align-items: center; 55 | justify-content: center; 56 | outline: none; 57 | &--error { 58 | outline: 2px solid red; 59 | } 60 | } 61 | 62 | &__buscar { 63 | display: flex; 64 | align-items: center; 65 | justify-content: center; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | $fuente-primaria: 'Montserrat', sans-serif; 2 | $color-fondo: #17171b; 3 | $color-fondo2: #110f14; 4 | $color-btn: #2d2d33; 5 | $color-btn--hover: #3b3b44; 6 | $color-btn--active: #c71717; 7 | $color-btn--active2: #a41111; 8 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/sass/index.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | @use 'generales'; 3 | @use 'btn'; 4 | @use 'sidebar'; 5 | @use 'main'; 6 | @use 'media'; 7 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/cargarGeneros.js: -------------------------------------------------------------------------------- 1 | import fetchGeneros from './fetchGeneros'; 2 | 3 | const contenedorGeneros = document.getElementById('filtro-generos'); 4 | 5 | const cargarGeneros = async (filtro) => { 6 | contenedorGeneros.innerHTML = ''; 7 | 8 | const generos = await fetchGeneros(filtro); 9 | generos.forEach((genero) => { 10 | const btn = document.createElement('button'); 11 | btn.classList.add('btn'); 12 | btn.innerText = genero.name; 13 | btn.setAttribute('data-id', genero.id); 14 | contenedorGeneros.appendChild(btn); 15 | }); 16 | }; 17 | 18 | export default cargarGeneros; 19 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/cargarTitulos.js: -------------------------------------------------------------------------------- 1 | const cargarTitulos = async (resultados = []) => { 2 | const contenedor = document.querySelector('#populares .main__grid'); 3 | 4 | try { 5 | // Reiniciamos las peliculas 6 | contenedor.innerHTML = ''; 7 | 8 | resultados.forEach((resultado) => { 9 | const plantilla = ` 10 |
11 | 12 | 13 | 14 |

${resultado.title || resultado.name}

15 |

${resultado.genero}

16 |
17 | `; 18 | 19 | contenedor.insertAdjacentHTML('beforeend', plantilla); 20 | }); 21 | } catch (e) { 22 | console.log(e); 23 | } 24 | }; 25 | 26 | export default cargarTitulos; 27 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/fetchBusqueda.js: -------------------------------------------------------------------------------- 1 | import fetchGeneros from './fetchGeneros'; 2 | import obtenerGenero from './obtenerGenero'; 3 | 4 | const fetchBusqueda = async (pagina = 1) => { 5 | const tipo = document.querySelector('.main__filtros .btn--active').id; 6 | const idGenero = document.querySelector('#filtro-generos .btn--active')?.dataset.id; 7 | const añoInicial = document.getElementById('años-min').value || 1950; 8 | const añoFinal = document.getElementById('años-max').value || 2022; 9 | 10 | let url; 11 | if (tipo === 'movie') { 12 | url = `https://api.themoviedb.org/3/discover/movie?api_key=b07dda1337fcfe0e08af7d3d2597908c&language=es-MX&sort_by=popularity.desc&include_adult=false&page=1&with_genres=${idGenero}&primary_release_date.gte=${añoInicial}-01-01&primary_release_date.lte=${añoFinal}-12-31®ion=US&page=${pagina}`; 13 | } else if (tipo === 'tv') { 14 | url = `https://api.themoviedb.org/3/discover/tv?api_key=b07dda1337fcfe0e08af7d3d2597908c&language=es-MX&sort_by=popularity.desc&include_adult=false&page=1&with_genres=${idGenero}&first_air_date.gte=${añoInicial}-01-01&first_air_date.lte=${añoFinal}-12-31®ion=US&page=${pagina}`; 15 | } 16 | 17 | let generos; 18 | generos = await fetchGeneros(tipo); 19 | 20 | try { 21 | const respuesta = await fetch(url); 22 | const data = await respuesta.json(); 23 | 24 | let resultados = data.results; 25 | 26 | // Obtenemos el genero de cada resultado y lo agregamos al objeto de resultados. 27 | resultados.forEach((resultado) => { 28 | resultado.genero = obtenerGenero(resultado.genre_ids[0], generos); 29 | }); 30 | 31 | return resultados; 32 | } catch (e) { 33 | console.log(e); 34 | } 35 | }; 36 | 37 | export default fetchBusqueda; 38 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/fetchGeneros.js: -------------------------------------------------------------------------------- 1 | const fetchGeneros = async (filtro = 'movie') => { 2 | const tipo = filtro === 'movie' ? 'movie' : 'tv'; 3 | const url = `https://api.themoviedb.org/3/genre/${tipo}/list?api_key=b07dda1337fcfe0e08af7d3d2597908c&language=es-MX`; 4 | 5 | try { 6 | const resultados = await fetch(url); 7 | const datos = await resultados.json(); 8 | return datos.genres; 9 | } catch (e) { 10 | console.log(e); 11 | } 12 | }; 13 | 14 | export default fetchGeneros; 15 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/fetchItem.js: -------------------------------------------------------------------------------- 1 | const fetchItem = async (id) => { 2 | const tipo = document.querySelector('.main__filtros .btn--active').id; 3 | 4 | try { 5 | const url = `https://api.themoviedb.org/3/${tipo}/${id}?api_key=b07dda1337fcfe0e08af7d3d2597908c&language=es-MX`; 6 | const respuesta = await fetch(url); 7 | const datos = await respuesta.json(); 8 | 9 | return datos; 10 | } catch (e) { 11 | console.log(e); 12 | } 13 | }; 14 | 15 | export default fetchItem; 16 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/fetchPopulares.js: -------------------------------------------------------------------------------- 1 | import obtenerGenero from './obtenerGenero'; 2 | import fetchGeneros from './fetchGeneros'; 3 | 4 | /** 5 | * Funcion que se encarga de hacer fetch para obtener las peliculas o series populares. 6 | * @param {String} filtro Si queremos cargar 'peliculas' o 'series'. 7 | */ 8 | const fetchPopulares = async (filtro = 'movie', pagina = 1) => { 9 | const tipo = filtro === 'movie' ? 'movie' : 'tv'; 10 | const url = `https://api.themoviedb.org/3/${tipo}/popular?api_key=b07dda1337fcfe0e08af7d3d2597908c&language=es-MX®ion=US&page=${pagina}`; 11 | const generos = await fetchGeneros(tipo); 12 | 13 | try { 14 | const respuesta = await fetch(url); 15 | const datos = await respuesta.json(); 16 | const resultados = datos.results; 17 | 18 | // Obtenemos el genero de cada resultado y lo agregamos al objeto de resultados. 19 | resultados.forEach((resultado) => { 20 | resultado.genero = obtenerGenero(resultado.genre_ids[0], generos); 21 | }); 22 | 23 | return resultados; 24 | } catch (e) { 25 | console.log(e); 26 | } 27 | }; 28 | 29 | export default fetchPopulares; 30 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/index.js: -------------------------------------------------------------------------------- 1 | import cargarTitulos from './cargarTitulos'; 2 | import cargarGeneros from './cargarGeneros'; 3 | import './listenerFiltroTipo'; 4 | import './listenerFiltroGeneros'; 5 | import './listenerBuscar'; 6 | import './paginacion'; 7 | import './listenerItems'; 8 | import './listenerPopup'; 9 | import fetchPopulares from './fetchPopulares'; 10 | 11 | const cargar = async () => { 12 | // Obtenemos los resultados. 13 | const resultados = await fetchPopulares('movie'); 14 | 15 | if (resultados) { 16 | // Los cargamos en el DOM. 17 | cargarTitulos(resultados); 18 | } 19 | }; 20 | 21 | cargar(); 22 | cargarGeneros('movie'); 23 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/listenerBuscar.js: -------------------------------------------------------------------------------- 1 | import cargarTitulos from './cargarTitulos'; 2 | import fetchBusqueda from './fetchBusqueda'; 3 | 4 | const btn = document.getElementById('btn-buscar'); 5 | 6 | btn.addEventListener('click', async (e) => { 7 | e.preventDefault(); 8 | 9 | const resultados = await fetchBusqueda(); 10 | cargarTitulos(resultados); 11 | }); 12 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/listenerFiltroGeneros.js: -------------------------------------------------------------------------------- 1 | const contenedor = document.getElementById('filtro-generos'); 2 | contenedor.addEventListener('click', (e) => { 3 | e.preventDefault(); 4 | 5 | if (e.target.closest('button')) { 6 | // Eliminamos la clase active de cualquier otro boton. 7 | contenedor.querySelector('.btn--active')?.classList.remove('btn--active'); 8 | 9 | // Agregamos la clase active al boton que clickamos. 10 | e.target.classList.add('btn--active'); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/listenerFiltroTipo.js: -------------------------------------------------------------------------------- 1 | import fetchPopulares from './fetchPopulares'; 2 | import cargarTitulos from './cargarTitulos'; 3 | import cargarGeneros from './cargarGeneros'; 4 | 5 | const filtroPelicula = document.getElementById('movie'); 6 | const filtroShow = document.getElementById('tv'); 7 | 8 | filtroPelicula.addEventListener('click', async (e) => { 9 | e.preventDefault(); 10 | 11 | // Cargamos los generos en la barra lateral. 12 | cargarGeneros('movie'); 13 | 14 | // Obtenemos los resultados. 15 | const resultados = await fetchPopulares('movie'); 16 | 17 | // Los cargamos en el DOM. 18 | cargarTitulos(resultados); 19 | 20 | filtroShow.classList.remove('btn--active'); 21 | filtroPelicula.classList.add('btn--active'); 22 | document.querySelector('#populares .main__titulo').innerText = 'Peliculas Populares'; 23 | }); 24 | 25 | filtroShow.addEventListener('click', async (e) => { 26 | e.preventDefault(); 27 | 28 | // Cargamos los generos en la barra lateral. 29 | cargarGeneros('tv'); 30 | 31 | // Obtenemos los resultados. 32 | const resultados = await fetchPopulares('tv'); 33 | 34 | // Los cargamos en el DOM. 35 | cargarTitulos(resultados); 36 | 37 | filtroPelicula.classList.remove('btn--active'); 38 | filtroShow.classList.add('btn--active'); 39 | document.querySelector('#populares .main__titulo').innerText = 'Series Populares'; 40 | }); 41 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/listenerItems.js: -------------------------------------------------------------------------------- 1 | import fetchItem from './fetchItem'; 2 | 3 | const contenedor = document.getElementById('populares'); 4 | const popup = document.getElementById('media'); 5 | 6 | contenedor.addEventListener('click', async (e) => { 7 | if (e.target.closest('.main__media')) { 8 | // Activamos el popup. 9 | popup.classList.add('media--active'); 10 | 11 | // Obtenemos el ID del elemento clickeado. 12 | const id = e.target.closest('.main__media').dataset.id; 13 | 14 | // Hacemos fetch de la media. 15 | const resultado = await fetchItem(id); 16 | 17 | const plantilla = ` 18 |
19 | 23 |
24 |
25 | 29 |
30 |
31 |

${resultado.title || resultado.name}

32 |

${resultado.release_date || resultado.first_air_date}

33 |

${resultado.overview}

34 |
35 | 49 | `; 50 | 51 | document.querySelector('.media .media__contenedor').innerHTML = plantilla; 52 | } 53 | }); 54 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/listenerPopup.js: -------------------------------------------------------------------------------- 1 | const popup = document.getElementById('media'); 2 | 3 | popup.addEventListener('click', (e) => { 4 | e.preventDefault(); 5 | 6 | if (e.target.closest('button')) { 7 | popup.classList.remove('media--active'); 8 | } 9 | }); 10 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/obtenerGenero.js: -------------------------------------------------------------------------------- 1 | const obtenerGenero = (id, generos) => { 2 | let genero; 3 | 4 | generos.forEach((elemento) => { 5 | if (id === elemento.id) { 6 | genero = elemento.name; 7 | } 8 | }); 9 | 10 | return genero; 11 | }; 12 | 13 | export default obtenerGenero; 14 | -------------------------------------------------------------------------------- /Proyectos/Peliculas/src/paginacion.js: -------------------------------------------------------------------------------- 1 | import cargarTitulos from './cargarTitulos'; 2 | import fetchBusqueda from './fetchBusqueda'; 3 | 4 | const anterior = document.getElementById('pagina-anterior'); 5 | const siguiente = document.getElementById('pagina-siguiente'); 6 | 7 | siguiente.addEventListener('click', async (e) => { 8 | e.preventDefault(); 9 | 10 | const paginaActual = document.getElementById('populares').dataset.pagina; 11 | 12 | try { 13 | const resultados = await fetchBusqueda(paginaActual + 1); 14 | document.getElementById('populares').setAttribute('data-pagina', parseInt(paginaActual) + 1); 15 | 16 | cargarTitulos(resultados); 17 | window.scrollTo(0, 0); 18 | } catch (e) { 19 | console.log(e); 20 | } 21 | }); 22 | 23 | anterior.addEventListener('click', async (e) => { 24 | e.preventDefault(); 25 | 26 | const paginaActual = document.getElementById('populares').dataset.pagina; 27 | 28 | if (paginaActual > 1) { 29 | try { 30 | const resultados = await fetchBusqueda(paginaActual - 1); 31 | document.getElementById('populares').setAttribute('data-pagina', parseInt(paginaActual) - 1); 32 | 33 | cargarTitulos(resultados); 34 | window.scrollTo(0, 0); 35 | } catch (e) { 36 | console.log(e); 37 | } 38 | } 39 | }); 40 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/hero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/hero.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/info.png -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/review-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/review-1.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/review-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/review-2.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/review-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/review-3.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/review-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/review-4.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/trabajo-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/trabajo-1.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/trabajo-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/trabajo-2.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/trabajo-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/trabajo-3.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/trabajo-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/trabajo-4.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/trabajo-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/trabajo-5.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/img/trabajo-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Portafolio/img/trabajo-6.jpg -------------------------------------------------------------------------------- /Proyectos/Portafolio/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Portafolio", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "devDependencies": { 8 | "rollup": "^2.79.0" 9 | } 10 | }, 11 | "node_modules/fsevents": { 12 | "version": "2.3.2", 13 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 14 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 15 | "dev": true, 16 | "hasInstallScript": true, 17 | "optional": true, 18 | "os": [ 19 | "darwin" 20 | ], 21 | "engines": { 22 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 23 | } 24 | }, 25 | "node_modules/rollup": { 26 | "version": "2.79.0", 27 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.0.tgz", 28 | "integrity": "sha512-x4KsrCgwQ7ZJPcFA/SUu6QVcYlO7uRLfLAy0DSA4NS2eG8japdbpM50ToH7z4iObodRYOJ0soneF0iaQRJ6zhA==", 29 | "dev": true, 30 | "bin": { 31 | "rollup": "dist/bin/rollup" 32 | }, 33 | "engines": { 34 | "node": ">=10.0.0" 35 | }, 36 | "optionalDependencies": { 37 | "fsevents": "~2.3.2" 38 | } 39 | } 40 | }, 41 | "dependencies": { 42 | "fsevents": { 43 | "version": "2.3.2", 44 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 45 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 46 | "dev": true, 47 | "optional": true 48 | }, 49 | "rollup": { 50 | "version": "2.79.0", 51 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.0.tgz", 52 | "integrity": "sha512-x4KsrCgwQ7ZJPcFA/SUu6QVcYlO7uRLfLAy0DSA4NS2eG8japdbpM50ToH7z4iObodRYOJ0soneF0iaQRJ6zhA==", 53 | "dev": true, 54 | "requires": { 55 | "fsevents": "~2.3.2" 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "rollup": "^2.79.0" 4 | }, 5 | "name": "portafolio", 6 | "version": "1.0.0", 7 | "main": "rollup.config.js", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "sass": "sass --watch --style=compressed sass/index.scss public/bundle.css", 11 | "build": "rollup --watch --config --sourcemap" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "description": "" 17 | } 18 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/public/bundle.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sourceRoot":"","sources":["../sass/_generales.scss","../sass/_variables.scss","../sass/_header.scss","../sass/_hero.scss","../sass/_trabajos.scss","../sass/_comentarios.scss","../sass/_footer.scss","../sass/_ventana.scss"],"names":[],"mappings":"AAEA,EACC,SACA,UACA,sBAGD,KACC,YCTiB,wBDUjB,eACA,WCVa,QDad,EACC,qBAGD,QACC,qBEjBD,QACC,UACA,iBACA,wBACA,gBACA,kBACA,aACA,8BACA,mBACA,4BAEA,gBACC,eACA,gBACA,WAGD,cACC,aACA,SAGD,cACC,gBACA,WACA,oBACC,MD1Bc,cEChB,UACA,iBACA,YACA,iBACA,aACA,8BAEA,YACC,gBACA,aACA,sBACA,uBACA,kBAGD,cACC,kBACA,aACA,sBACA,uBAGD,cACC,eACA,gBACA,qBACA,kBAGD,iBACC,eACA,gBACA,cACA,MFlCe,QEqChB,cACC,aACA,YACA,WACA,cACA,kBACA,QAGA,YACA,uBACC,cAGD,sBACC,kDAIF,kBACC,KACC,UAED,GACC,WAIF,oBACC,YACA,WAGD,eACC,iBACA,eACA,MFvEuB,QEwEvB,mBAGD,aACC,aACA,SAGD,WACC,WACA,YACA,aACA,mBACA,uBACA,aACA,mBACA,oBACC,mBAED,qBACC,mBAED,kBACC,mBAIF,aACC,WACA,YACA,WAGD,uBACC,kBAGD,YACC,mBACA,WAGD,eACC,gBACA,aACA,oBACA,WACA,kBACA,eACA,gBACA,kBACA,iBACA,iDACA,aACA,UAEA,wBACC,8BACA,YACA,WFpIa,QEqIb,WAGD,qBACC,kCACA,YACA,WF5Ic,QE6Id,YAGD,yBACC,6BACA,UAGD,yBACC,6BACA,UCvJH,UACC,mBAEA,UACA,iBACA,YACA,kBAEA,kBACC,kBACA,WACA,mBAGD,kBACC,mBAGD,mBACC,UACA,wBACA,4BACC,UAIF,oBACC,aACA,qCACA,QAGD,kBACC,WCjCF,aACC,mBACA,yBACA,UACA,iBACA,YACA,kBACA,4BAEA,qBACC,mBAGD,qBACC,mBAGD,qBACC,aACA,uBACA,sBACA,SACA,gBACA,YACA,oBACA,iBACA,iBACA,mBAGD,qBACC,gBACA,oBACA,kBAGD,8BACC,kBACA,SACA,iBAGD,gCACC,gBACA,4BACA,6CACA,kBACA,aACA,sBACA,SAGD,mBACC,WACA,YACA,mBAGD,oBACC,eACA,cACA,mBAGD,oBACC,MJjEe,QIkEf,gBACA,eAGD,sBACC,eCzEF,QACC,UACA,iBACA,YACA,kBACA,iBAEA,gBACC,mBACA,eAGD,mBACC,mBAGD,eACC,aACA,mBACA,uBACA,SAGD,aACC,WACA,YACA,mBACA,WACA,aAEA,sBACC,mBAED,uBACC,mBAED,oBACC,mBAIF,eACC,WACA,YCzCF,SACC,aACA,YACA,aACA,eACA,YACA,MACA,OAEA,iBACC,cAGD,kBACC,WACA,YACA,0BACA,aACA,mBACA,uBAGD,iBACC,UACA,gBACA,aACA,gBACA,mBACA,aACA,sBACA,mBACA,SACA,kBACA,kBAGD,qBACC,kBACA,YACA,UACA,eACA,gBACA,YACA,WACA,WACA,YAGD,uBACC,WACA,YAGD,iBACC,eAGD,wBACC,YAGD,eACC,eACA,MN7DuB,QMgExB,eACC,gBACA,YACA,UACA,gBACA,mBACA,aACA,8BACA,SACA,kBAGD,iBACC,WACA,kBACA,mBAGD,gBACC,eACA,MNpFuB,QMuFxB,kBACC,iBAGD,eACC,aACA,sBACA,SACA","file":"bundle.css"} -------------------------------------------------------------------------------- /Proyectos/Portafolio/rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | input: 'src/index.js', 3 | output: { 4 | file: 'public/bundle.js', 5 | format: 'cjs', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/sass/_comentarios.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .comentarios { 4 | background: #f1f1f1; 5 | padding: 40px 0 40px 65px; 6 | width: 90%; 7 | max-width: 1000px; 8 | margin: auto; 9 | text-align: center; 10 | border-radius: 0 0 15px 15px; 11 | 12 | &__header { 13 | margin-bottom: 40px; 14 | } 15 | 16 | &__titulo { 17 | margin-bottom: 10px; 18 | } 19 | 20 | &__slider { 21 | display: grid; 22 | grid-template-rows: 1fr; 23 | grid-auto-flow: column; 24 | gap: 20px; 25 | overflow-x: auto; 26 | cursor: move; 27 | cursor: -webkit-grab; 28 | cursor: -moz-grab; 29 | user-select: none; 30 | padding-right: 20px; 31 | } 32 | 33 | &__review { 34 | min-width: 400px; 35 | padding-bottom: 10px; 36 | position: relative; 37 | } 38 | 39 | &__contenedor-foto { 40 | position: relative; 41 | top: 40px; 42 | margin-top: -40px; 43 | } 44 | 45 | &__contenedor-textos { 46 | background: #fff; 47 | padding: 60px 20px 20px 20px; 48 | box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px; 49 | border-radius: 5px; 50 | display: flex; 51 | flex-direction: column; 52 | gap: 10px; 53 | } 54 | 55 | &__foto { 56 | width: 80px; 57 | height: 80px; 58 | border-radius: 80px; 59 | } 60 | 61 | &__texto { 62 | font-size: 14px; 63 | color: #6f6f6f; 64 | margin-bottom: 20px; 65 | } 66 | 67 | &__autor { 68 | color: variables.$color-primario; 69 | font-weight: 600; 70 | font-size: 14px; 71 | } 72 | 73 | &__empresa { 74 | font-size: 14px; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/sass/_footer.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | width: 90%; 3 | max-width: 1000px; 4 | margin: auto; 5 | text-align: center; 6 | padding: 40px 0px; 7 | 8 | &__titulo { 9 | margin-bottom: 10px; 10 | font-size: 24px; 11 | } 12 | 13 | &__subtitulo { 14 | margin-bottom: 40px; 15 | } 16 | 17 | &__redes { 18 | display: flex; 19 | align-items: center; 20 | justify-content: center; 21 | gap: 20px; 22 | } 23 | 24 | &__red { 25 | width: 70px; 26 | height: 70px; 27 | border-radius: 70px; 28 | color: #fff; 29 | padding: 24px; 30 | 31 | &--twitter { 32 | background: #1da1f2; 33 | } 34 | &--linkedin { 35 | background: #0077b5; 36 | } 37 | &--email { 38 | background: #656565; 39 | } 40 | } 41 | 42 | &__icono { 43 | width: 100%; 44 | height: 100%; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/sass/_generales.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | font-family: variables.$fuente-primaria; 11 | font-size: 16px; 12 | background: variables.$color-fondo; 13 | } 14 | 15 | a { 16 | text-decoration: none; 17 | } 18 | 19 | a:hover { 20 | text-decoration: none; 21 | } 22 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/sass/_header.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .header { 4 | width: 90%; 5 | max-width: 1000px; 6 | margin: 40px auto 0 auto; 7 | background: #fff; 8 | padding: 40px 65px; 9 | display: flex; 10 | justify-content: space-between; 11 | align-items: center; 12 | border-radius: 20px 20px 0 0; 13 | 14 | &__titulo { 15 | font-size: 26px; 16 | font-weight: 700; 17 | color: #000; 18 | } 19 | 20 | &__menu { 21 | display: flex; 22 | gap: 50px; 23 | } 24 | 25 | &__link { 26 | font-weight: 600; 27 | color: #000; 28 | &:hover { 29 | color: variables.$color-primario; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/sass/_trabajos.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .trabajos { 4 | background: #0d0e26; 5 | 6 | width: 90%; 7 | max-width: 1000px; 8 | margin: auto; 9 | padding: 40px 65px; 10 | 11 | &__header { 12 | text-align: center; 13 | color: #fff; 14 | margin-bottom: 40px; 15 | } 16 | 17 | &__titulo { 18 | margin-bottom: 10px; 19 | } 20 | 21 | &__trabajo { 22 | opacity: 0; 23 | transition: 0.5s ease all; 24 | &--visible { 25 | opacity: 1; 26 | } 27 | } 28 | 29 | &__imagenes { 30 | display: grid; 31 | grid-template-columns: repeat(3, 1fr); 32 | gap: 5px; 33 | } 34 | 35 | &__imagen { 36 | width: 100%; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | $fuente-primaria: 'Montserrat', sans-serif; 2 | $color-fondo: #d9d9d9; 3 | $color-primario: #255ecd; 4 | $color-naranja: #e49318; 5 | $color-texto-secundario: #8c8c8c; 6 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/sass/_ventana.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | .ventana { 4 | display: none; 5 | width: 100vw; 6 | height: 100vh; 7 | position: fixed; 8 | z-index: 100; 9 | top: 0; 10 | left: 0; 11 | 12 | &--active { 13 | display: block; 14 | } 15 | 16 | &__overlay { 17 | width: 100%; 18 | height: 100%; 19 | background: rgba(0, 0, 0, 0.8); 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | 25 | &__correo { 26 | width: 90%; 27 | max-width: 600px; 28 | padding: 40px; 29 | background: #fff; 30 | border-radius: 10px; 31 | display: flex; 32 | flex-direction: column; 33 | align-items: center; 34 | gap: 20px; 35 | text-align: center; 36 | position: relative; 37 | } 38 | 39 | &__btn-cerrar { 40 | position: absolute; 41 | right: -40px; 42 | top: -40px; 43 | cursor: pointer; 44 | background: none; 45 | border: none; 46 | color: #fff; 47 | width: 40px; 48 | height: 40px; 49 | } 50 | 51 | &__icono-cerrar { 52 | width: 100%; 53 | height: 100%; 54 | } 55 | 56 | &__titulo { 57 | font-size: 24px; 58 | } 59 | 60 | &__imagen-correo { 61 | width: 300px; 62 | } 63 | 64 | &__hint { 65 | font-size: 16px; 66 | color: variables.$color-texto-secundario; 67 | } 68 | 69 | &__body { 70 | background: #fff; 71 | padding: 5px; 72 | width: 90%; 73 | max-width: 900px; 74 | border-radius: 10px; 75 | display: grid; 76 | grid-template-columns: 3fr 2fr; 77 | gap: 20px; 78 | position: relative; 79 | } 80 | 81 | &__imagen { 82 | width: 100%; 83 | border-radius: 5px; 84 | vertical-align: top; 85 | } 86 | 87 | &__fecha { 88 | font-size: 14px; 89 | color: variables.$color-texto-secundario; 90 | } 91 | 92 | &__parrafo { 93 | line-height: 24px; 94 | } 95 | 96 | &__info { 97 | display: flex; 98 | flex-direction: column; 99 | gap: 20px; 100 | padding: 20px 0; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/sass/index.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | @use 'generales'; 3 | @use 'header'; 4 | @use 'hero'; 5 | @use 'trabajos'; 6 | @use 'comentarios'; 7 | @use 'footer'; 8 | @use 'ventana'; 9 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/src/animarGaleria.js: -------------------------------------------------------------------------------- 1 | const galeria = document.getElementById('trabajos'); 2 | 3 | const animarGaleria = () => {}; 4 | const observer = new IntersectionObserver( 5 | (entries) => { 6 | // Nos aseguramos de que haya pasado al menos medio segundo. 7 | if (entries[0].time > 500) { 8 | const trabajos = galeria.querySelectorAll('.trabajos__imagenes a'); 9 | trabajos.forEach((trabajo, index) => { 10 | setTimeout(() => { 11 | trabajo.classList.add('trabajos__trabajo--visible'); 12 | }, index * 200); 13 | }); 14 | } 15 | }, 16 | { 17 | rootMargin: '0px 0px 0px 0px', 18 | threshold: 0.5, 19 | } 20 | ); 21 | 22 | window.addEventListener('load', observer.observe(galeria)); 23 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/src/animarTexto.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Funcion que se encarga de animar nuestros textos. 3 | * @param {DOMElement} texto Elemento del dom que queremos animar. 4 | */ 5 | 6 | const animarTexto = (texto, delay = 0) => { 7 | const numeroDeLetras = texto.dataset.texto.length; 8 | 9 | // Activamos el cursor cuando comienza la animacion. 10 | const cursor = texto.querySelector('.hero__cursor'); 11 | cursor.classList.add('hero__cursor--visible'); 12 | 13 | // Por cada letra, la agregamos al DOM con 100ms de separacion. 14 | for (let i = 0; i < numeroDeLetras; i++) { 15 | setTimeout(() => { 16 | const letra = document.createElement('span'); 17 | letra.append(texto.dataset.texto[i]); 18 | texto.append(letra); 19 | }, 100 * i); 20 | } 21 | 22 | // Cambiamos la clase del cursor cuando termine la animacion de letras. 23 | setTimeout(() => { 24 | // Obtenemos los cursores. 25 | const cursores = [...texto.closest('.hero__header').querySelectorAll('.hero__cursor')]; 26 | // Obtenemos el index del cursor actual. 27 | const indexCursorActual = cursores.indexOf(cursor); 28 | 29 | // Comprobamos que el cursor no sea el ultimo. 30 | if (indexCursorActual < cursores.length - 1) { 31 | // Si no es el ultimo, ocultamos el cursor. 32 | cursor.classList.remove('hero__cursor--visible'); 33 | } else { 34 | // Si es el ultimo, le ponemos la clase de active. 35 | cursor.classList.add('hero__cursor--active'); 36 | } 37 | }, 100 * numeroDeLetras); 38 | 39 | // Retornamos una promesa para saber cuando la animacion acabo. 40 | return new Promise((resolve) => setTimeout(resolve, 100 * numeroDeLetras)); 41 | }; 42 | 43 | export default animarTexto; 44 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/src/index.js: -------------------------------------------------------------------------------- 1 | import './ventanaCorreo'; 2 | import './animarGaleria'; 3 | import './galeria'; 4 | import './slider'; 5 | 6 | import animarTexto from './animarTexto'; 7 | 8 | // Ejecutamos las animaciones cuando termina de cargar. 9 | window.addEventListener('load', async () => { 10 | await animarTexto(document.querySelector('.hero__titulo--uno')); 11 | await animarTexto(document.querySelector('.hero__titulo--dos')); 12 | 13 | document.querySelectorAll('.hero__burbuja')[0].classList.add('hero__burbuja--active-1'); 14 | document.querySelectorAll('.hero__burbuja')[1].classList.add('hero__burbuja--active-2'); 15 | }); 16 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/src/slider.js: -------------------------------------------------------------------------------- 1 | const slider = document.getElementById('slider'); 2 | 3 | // Variable que guarda el estado de si tenemos el click presionado. 4 | let clickPresionado = false; 5 | let coordenadaInicial; 6 | let scrollLeft; // Guardamos la posicion del scroll del slider 7 | 8 | const presiona = (e) => { 9 | // console.log('presiona'); 10 | clickPresionado = true; 11 | 12 | // e.pageX - Coordenada horizontal del evento. En que coordenada dimos click con respecto al documento. 13 | // slider.offsetLeft - El espacio entre el slider y la parte izquierda del documento. 14 | coordenadaInicial = e.pageX - slider.offsetLeft; 15 | scrollLeft = slider.scrollLeft; 16 | 17 | console.log('startX: ', e.pageX); 18 | console.log('slider.offsetLeft: ', slider.offsetLeft); 19 | console.log('scrollLeft: ', slider.scrollLeft); 20 | }; 21 | const mueve = (e) => { 22 | if (!clickPresionado) { 23 | return; 24 | } 25 | 26 | // console.log('mueve'); 27 | // Espaciado entre la coordenada de inicio del slider y donde dimos click. 28 | const espaciado = e.pageX - slider.offsetLeft; 29 | const distanciaRecorrida = espaciado - coordenadaInicial; 30 | 31 | console.log('distancia: ', distanciaRecorrida); 32 | console.log('scrollLeft: ', scrollLeft); 33 | 34 | // Desplazamos el scroll. 35 | // A la posicion inicial del scroll cuando dimos click le restamos la distancia. 36 | slider.scrollLeft = scrollLeft - distanciaRecorrida; 37 | }; 38 | const suelta = (e) => { 39 | // console.log('suelta'); 40 | clickPresionado = false; 41 | }; 42 | 43 | slider.addEventListener('mousedown', presiona); 44 | slider.addEventListener('mousemove', mueve); 45 | slider.addEventListener('mouseup', suelta); 46 | -------------------------------------------------------------------------------- /Proyectos/Portafolio/src/ventanaCorreo.js: -------------------------------------------------------------------------------- 1 | const botonesEmail = document.querySelectorAll('[data-action="abrir-ventana-correo"]'); 2 | const ventanaCorreo = document.getElementById('ventana-correo'); 3 | 4 | botonesEmail.forEach((boton) => 5 | boton.addEventListener('click', (e) => { 6 | e.preventDefault(); 7 | ventanaCorreo.classList.add('ventana--active'); 8 | }) 9 | ); 10 | 11 | // Eventlistener para cerrar ventana con el boton. 12 | ventanaCorreo.querySelector('button[data-action="cerrar-ventana"]').addEventListener('click', (e) => { 13 | e.preventDefault(); 14 | ventanaCorreo.classList.remove('ventana--active'); 15 | }); 16 | 17 | // Eventlistener para cerrar ventana con el overlay. 18 | ventanaCorreo.querySelector('.ventana__overlay').addEventListener('click', (e) => { 19 | e.preventDefault(); 20 | if (e.target.matches('.ventana__overlay')) { 21 | ventanaCorreo.classList.remove('ventana--active'); 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/ayo-ogunseinde-6W4F62sN_yI-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/ayo-ogunseinde-6W4F62sN_yI-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/ayo-ogunseinde-sibVwORYqs0-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/ayo-ogunseinde-sibVwORYqs0-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/camila-damasio-mWYhrOiAgmA-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/camila-damasio-mWYhrOiAgmA-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/darklabs-india-g9JTq14wBQM-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/darklabs-india-g9JTq14wBQM-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/douglas-bagg-Yb_pvbQc0mc-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/douglas-bagg-Yb_pvbQc0mc-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/jaizer-capangpangan-2Xhv5zrTLN0-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/jaizer-capangpangan-2Xhv5zrTLN0-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/kris-gerhard-0BKZfcamvGg-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/kris-gerhard-0BKZfcamvGg-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/mitchel-lensink-1BI-ar91C7U-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/mitchel-lensink-1BI-ar91C7U-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/rachael-ren-Ueu_6ZrVb80-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/rachael-ren-Ueu_6ZrVb80-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/thamara-maura-rniFdQKztF8-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/thamara-maura-rniFdQKztF8-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/thuan-pham-tvl2Pa98K_g-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/thuan-pham-tvl2Pa98K_g-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/raw/vince-fleming-j3lf-Jn6deo-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/raw/vince-fleming-j3lf-Jn6deo-unsplash.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/tennis/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/tennis/1.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/tennis/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/tennis/2.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/tennis/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/tennis/3.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/tennis/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/tennis/4.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/tennis/amarillo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/tennis/amarillo.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/tennis/negro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/tennis/negro.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/tennis/rojo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/tennis/rojo.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/thumbs/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/thumbs/1.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/thumbs/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/thumbs/2.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/thumbs/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/thumbs/3.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/thumbs/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/thumbs/4.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/thumbs/amarillo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/thumbs/amarillo.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/thumbs/negro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/thumbs/negro.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/thumbs/rojo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/thumbs/rojo.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/users/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/users/1.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/users/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/users/2.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/img/users/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falconmasters/curso_javascript-/d981c9fb9eab47a5d76ec2a58f7ecbb8c3982749/Proyectos/Tienda/img/users/3.jpg -------------------------------------------------------------------------------- /Proyectos/Tienda/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tienda", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "fsevents": { 8 | "version": "2.3.2", 9 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 10 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 11 | "dev": true, 12 | "optional": true 13 | }, 14 | "rollup": { 15 | "version": "2.75.7", 16 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz", 17 | "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==", 18 | "dev": true, 19 | "requires": { 20 | "fsevents": "~2.3.2" 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Proyectos/Tienda/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tienda", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "sass": "sass --watch --style=compressed sass/index.scss public/bundle.css", 9 | "build": "rollup --watch --config" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "rollup": "^2.75.7" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Proyectos/Tienda/rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | input: 'src/index.js', 3 | output: { 4 | file: 'public/bundle.js', 5 | format: 'cjs', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /Proyectos/Tienda/sass/_generales.scss: -------------------------------------------------------------------------------- 1 | @use 'variables'; 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | background: variables.$color-fondo; 11 | font-family: variables.$font-family; 12 | font-size: 16px; 13 | } 14 | 15 | .contenedor { 16 | width: 90%; 17 | max-width: 1050px; 18 | margin: auto; 19 | } 20 | 21 | a { 22 | text-decoration: none; 23 | } 24 | -------------------------------------------------------------------------------- /Proyectos/Tienda/sass/_header.scss: -------------------------------------------------------------------------------- 1 | .header { 2 | padding: 40px 0; 3 | display: flex; 4 | justify-content: space-between; 5 | align-items: center; 6 | 7 | &__logo { 8 | text-transform: uppercase; 9 | font-size: 32px; 10 | font-weight: 700; 11 | } 12 | 13 | &__menu { 14 | display: flex; 15 | gap: 20px; 16 | } 17 | 18 | &__link { 19 | color: #000; 20 | } 21 | 22 | &__link:hover { 23 | text-decoration: underline; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Proyectos/Tienda/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | $font-family: 'Rubik', sans-serif; 2 | $shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px; 3 | $color-fondo: #f3f5f7; 4 | $color-muted: #707070; 5 | $color-blanco-secundario: #f3f5f7; 6 | $color-gris-oscuro: #2b2b2b; 7 | $color-btn: #000; 8 | $color-btn-hover: #199a28; 9 | $color-btn-claro-secundario: #dfdfdf; 10 | -------------------------------------------------------------------------------- /Proyectos/Tienda/sass/componentes/_breadcrumbs.scss: -------------------------------------------------------------------------------- 1 | @use '../variables'; 2 | 3 | .breadcrumbs { 4 | display: flex; 5 | align-items: center; 6 | gap: 10px; 7 | margin-bottom: 20px; 8 | 9 | &__svg { 10 | height: 10px; 11 | width: 10px; 12 | color: variables.$color-muted; 13 | } 14 | 15 | &__link { 16 | color: variables.$color-muted; 17 | font-size: 14px; 18 | } 19 | 20 | &__link:hover { 21 | text-decoration: underline; 22 | } 23 | 24 | &__active { 25 | font-size: 14px; 26 | text-decoration: underline; 27 | color: #000; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Proyectos/Tienda/sass/componentes/_notificacion.scss: -------------------------------------------------------------------------------- 1 | @use '../variables'; 2 | 3 | .notificacion { 4 | background: #fff; 5 | box-shadow: variables.$shadow; 6 | border-radius: 10px; 7 | padding: 20px; 8 | position: fixed; 9 | right: -200px; 10 | bottom: 40px; 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | gap: 10px; 15 | text-align: center; 16 | transition: 0.3s ease-in all; 17 | opacity: 0; 18 | 19 | &.notificacion--active { 20 | right: 40px; 21 | opacity: 1; 22 | } 23 | 24 | &__titulo { 25 | font-size: 14px; 26 | font-weight: 600; 27 | } 28 | 29 | &__thumb { 30 | width: 100px; 31 | border-radius: 5px; 32 | } 33 | 34 | &__link { 35 | font-size: 14px; 36 | text-decoration: underline; 37 | font-weight: 600; 38 | color: #000; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Proyectos/Tienda/sass/componentes/_tabs.scss: -------------------------------------------------------------------------------- 1 | @use '../variables'; 2 | 3 | .tabs { 4 | display: flex; 5 | gap: 10px; 6 | margin-bottom: 10px; 7 | 8 | &__button { 9 | background: #e4e4e4; 10 | color: #000; 11 | border: none; 12 | cursor: pointer; 13 | font-size: 16px; 14 | font-family: variables.$font-family; 15 | border-radius: 5px; 16 | padding: 10px 20px; 17 | } 18 | 19 | &__button--active { 20 | background: variables.$color-btn; 21 | color: #fff; 22 | } 23 | } 24 | 25 | .tab { 26 | background: #fff; 27 | padding: 20px; 28 | border-radius: 5px; 29 | box-shadow: variables.$shadow; 30 | margin-bottom: 20px; 31 | display: none; 32 | 33 | &--active { 34 | display: block; 35 | } 36 | 37 | &__titulo { 38 | font-size: 24px; 39 | font-weight: 700; 40 | margin-bottom: 20px; 41 | } 42 | 43 | &__parrafo { 44 | margin-bottom: 20px; 45 | } 46 | 47 | &__lista { 48 | margin-left: 15px; 49 | line-height: 24px; 50 | } 51 | } 52 | 53 | .reseña { 54 | display: flex; 55 | margin-bottom: 30px; 56 | gap: 20px; 57 | 58 | &__foto { 59 | border-radius: 50px; 60 | vertical-align: top; 61 | height: 65px; 62 | width: 65px; 63 | } 64 | 65 | &__estrellas { 66 | display: flex; 67 | gap: 10px; 68 | color: #049aef; 69 | margin-bottom: 10px; 70 | } 71 | 72 | &__estrella { 73 | width: 10px; 74 | height: 10px; 75 | } 76 | 77 | &__estrella svg { 78 | width: 100%; 79 | height: 100%; 80 | } 81 | 82 | &__fecha { 83 | color: variables.$color-muted; 84 | font-size: 12px; 85 | margin-bottom: 10px; 86 | } 87 | 88 | &__texto { 89 | line-height: 24px; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Proyectos/Tienda/sass/index.scss: -------------------------------------------------------------------------------- 1 | @use 'generales'; 2 | @use 'header'; 3 | @use 'componentes/breadcrumbs'; 4 | @use 'componentes/producto'; 5 | @use 'componentes/tabs'; 6 | @use 'componentes/notificacion'; 7 | @use 'componentes/carrito'; 8 | -------------------------------------------------------------------------------- /Proyectos/Tienda/src/data/productos.js: -------------------------------------------------------------------------------- 1 | export default { 2 | productos: [ 3 | { 4 | id: '1', 5 | nombre: 'Tennis Converse Standard', 6 | descripcion: 'Consectetur adipisicing elit.', 7 | precio: 500.0, 8 | colores: ['negro', 'rojo', 'amarillo'], 9 | tamaños: ['1,5', '2', '2,5', '3', '4'], 10 | }, 11 | { 12 | id: '2', 13 | nombre: 'Tennis Converse 2000', 14 | descripcion: 'Consectetur adipisicing elit.', 15 | precio: 450.0, 16 | colores: ['negro', 'rojo', 'amarillo'], 17 | tamaños: ['1,5', '2', '2,5', '3', '4'], 18 | }, 19 | ], 20 | }; 21 | -------------------------------------------------------------------------------- /Proyectos/Tienda/src/index.js: -------------------------------------------------------------------------------- 1 | import Tabs from './tabs'; 2 | import './producto'; 3 | import './carrito'; 4 | 5 | // Creamos una instancia de Tabs 6 | new Tabs('mas-informacion'); 7 | -------------------------------------------------------------------------------- /Proyectos/Tienda/src/producto.js: -------------------------------------------------------------------------------- 1 | const producto = document.getElementById('producto'); 2 | const productoImagen = producto.querySelector('.producto__imagen'); 3 | const thumbs = producto.querySelector('.producto__thumbs'); 4 | 5 | // Color 6 | const propiedadColor = producto.querySelector('#propiedad-color'); 7 | 8 | // Cantidad 9 | const btnIncrementarCantidad = producto.querySelector('#incrementar-cantidad'); 10 | const btnDisminuirCantidad = producto.querySelector('#disminuir-cantidad'); 11 | const inputCantidad = producto.querySelector('#cantidad'); 12 | 13 | // Funcionalidad de las thumbnails 14 | thumbs.addEventListener('click', (e) => { 15 | if (e.target.tagName === 'IMG') { 16 | const imagenSrc = e.target.src; 17 | 18 | // Obtenemos la posicion del ultimo / 19 | const lastIndex = imagenSrc.lastIndexOf('/'); 20 | 21 | // Cortamos la cadena de texto para obtener solamente una parte. 22 | const nombreImagen = imagenSrc.substring(lastIndex + 1); 23 | 24 | // Cambiamos la ruta de la imagen del producto. 25 | productoImagen.src = `./img/tennis/${nombreImagen}`; 26 | } 27 | }); 28 | 29 | // Cambiamos la imagen del producto dependiendo de la propiedad que seleccionen 30 | propiedadColor.addEventListener('click', (e) => { 31 | if (e.target.tagName === 'INPUT') { 32 | // Cambiamos la ruta de la imagen del producto. 33 | productoImagen.src = `./img/tennis/${e.target.value}.jpg`; 34 | } 35 | }); 36 | 37 | // Cambiamos la cantidad a agregar al carrito 38 | btnIncrementarCantidad.addEventListener('click', (e) => { 39 | inputCantidad.value = parseInt(inputCantidad.value) + 1; 40 | }); 41 | btnDisminuirCantidad.addEventListener('click', (e) => { 42 | if (parseInt(inputCantidad.value) > 1) { 43 | inputCantidad.value = parseInt(inputCantidad.value) - 1; 44 | } 45 | }); 46 | -------------------------------------------------------------------------------- /Proyectos/Tienda/src/tabs.js: -------------------------------------------------------------------------------- 1 | export default class Tabs { 2 | constructor(idElemento) { 3 | this.tabs = document.getElementById(idElemento); 4 | this.nav = this.tabs.querySelector('.tabs'); 5 | 6 | this.nav.addEventListener('click', (e) => { 7 | e.preventDefault(); 8 | 9 | // Comprobamos que el elemento que clickeamos tenga la clase de tabs__link. 10 | if ([...e.target.classList].includes('tabs__button')) { 11 | // Obtenemos la tab que queremos mostrar. 12 | const tab = e.target.dataset.tab; 13 | 14 | // Quitamos la clase active de alguna otras tabs que la tengan. 15 | if (this.tabs.querySelector('.tab--active')) { 16 | this.tabs.querySelector('.tab--active').classList.remove('tab--active'); 17 | } 18 | 19 | // Quitamos la clase active del boton. 20 | if (this.tabs.querySelector('.tabs__button--active')) { 21 | this.tabs.querySelector('.tabs__button--active').classList.remove('tabs__button--active'); 22 | } 23 | 24 | // Agregamos la clase active al tab. 25 | this.tabs.querySelector(`#${tab}`).classList.add('tab--active'); 26 | 27 | // Agregamos la clase active al boton. 28 | e.target.classList.add('tabs__button--active'); 29 | } 30 | }); 31 | } 32 | } 33 | --------------------------------------------------------------------------------