Pequeño carrito de compras | JavaScript

Hoy te mostraré como crear un carrito de compras básico usando solamente JavaScript, empecemos.
Creación del index.html
Primero crearemos nuestro archivo index.html, crearemos algo sencillo para no complicarnos agregando algunos productos:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Carrito</title> | |
<link rel="stylesheet" href="css/normalize.css"> | |
<link rel="stylesheet" href="css/skeleton.css"> | |
<link rel="stylesheet" href="css/custom.css"> | |
</head> | |
<body> | |
<header id="header" class="header"> | |
<div class="container"> | |
<div class="row"> | |
<div class="four columns"> | |
<img src="img/logo.jpg" id="logo"> | |
</div> | |
<div class="two columns u-pull-right"> | |
<ul> | |
<li class="submenu"> | |
<img src="img/cart.png" id="img-carrito"> | |
<div id="carrito"> | |
<table id="lista-carrito" class="u-full-width"> | |
<thead> | |
<tr> | |
<th>Imagen</th> | |
<th>Nombre</th> | |
<th>Precio</th> | |
<th>Cantidad</th> | |
<th></th> | |
</tr> | |
</thead> | |
<tbody></tbody> | |
</table> | |
<a href="#" id="vaciar-carrito" class="button u-full-width">Vaciar Carrito</a> | |
</div> | |
</li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
</header> | |
<div id="hero"> | |
<div class="container"> | |
<div class="row"> | |
<div class="six columns"> | |
<div class="contenido-hero"> | |
<h2>Aprende algo nuevo</h2> | |
<p>Todos los cursos a $15</p> | |
<form action="#" id="busqueda" method="post" class="formulario"> | |
<input class="u-full-width" type="text" placeholder="¿Que te gustaría Aprender?" id="buscador"> | |
<input type="submit" id="submit-buscador" class="submit-buscador"> | |
</form> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="barra"> | |
<div class="container"> | |
<div class="row"> | |
<div class="four columns icono icono1"> | |
<p>20,000 Cursos en línea <br> | |
Explora los temas más recientes</p> | |
</div> | |
<div class="four columns icono icono2"> | |
<p>Instructores Expertos <br> | |
Aprende con distintos estilos</p> | |
</div> | |
<div class="four columns icono icono3"> | |
<p>Acceso de por vida <br> | |
Aprende a tu ritmo</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div id="lista-cursos" class="container"> | |
<h1 id="encabezado" class="encabezado">Cursos En Línea</h1> | |
<div class="row"> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso1.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>HTML5, CSS3, JavaScript para Principiantes</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="1">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso2.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>Curso de Comida Vegetariana</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="2">Agregar Al Carrito</a> | |
</div> | |
</div> | |
</div> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso3.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>Guitarra para Principiantes</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="3">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
</div> <!--.row--> | |
<div class="row"> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso4.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>Huerto en tu casa</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="4">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso5.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>Decoración con productos de tu hogar</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="5">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso1.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>Diseño Web para Principiantes</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="6">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
</div> <!--.row--> | |
<div class="row"> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso2.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>Comida Mexicana para principiantes</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="7">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso3.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>Estudio Musical en tu casa</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="8">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso4.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>Cosecha tus propias frutas y verduras</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="9">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
</div> <!--.row--> | |
<div class="row"> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso5.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>Prepara galletas caseras</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="10">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso1.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>JavaScript Moderno con ES6</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="11">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
<div class="four columns"> | |
<div class="card"> | |
<img src="img/curso2.jpg" class="imagen-curso u-full-width"> | |
<div class="info-card"> | |
<h4>100 Recetas de Comida Natural</h4> | |
<p>Juan Pedro</p> | |
<img src="img/estrellas.png"> | |
<p class="precio">$200 <span class="u-pull-right ">$15</span></p> | |
<a href="#" class="u-full-width button-primary button input agregar-carrito" data-id="12">Agregar Al Carrito</a> | |
</div> | |
</div> <!--.card--> | |
</div> | |
</div> <!--.row--> | |
</div> | |
<footer id="footer" class="footer"> | |
<div class="container"> | |
<div class="row"> | |
<div class="four columns"> | |
<nav id="principal" class="menu"> | |
<a class="enlace" href="#">Para tu Negocio</a> | |
<a class="enlace" href="#">Conviertete en Instructor</a> | |
<a class="enlace" href="#">Aplicaciones Móviles</a> | |
<a class="enlace" href="#">Soporte</a> | |
<a class="enlace" href="#">Temas</a> | |
</nav> | |
</div> | |
<div class="four columns"> | |
<nav id="secundaria" class="menu"> | |
<a class="enlace" href="#">¿Quienes Somos?</a> | |
<a class="enlace" href="#">Empleo</a> | |
<a class="enlace" href="#">Blog</a> | |
</nav> | |
</div> | |
</div> | |
</div> | |
</footer> | |
<script src="js/app.js"></script> | |
</body> | |
</html> |
Creando el app.js
Ahora vamos a crear el archivo javascript que nos permitirá controlar nuestro carrito de compras.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Variables | |
const carrito = document.querySelector('#carrito'); | |
const contenedorCarrito = document.querySelector('#lista-carrito tbody'); | |
const vaciarCarritoBtn = document.querySelector('#vaciar-carrito'); | |
const listaCursos = document.querySelector('#lista-cursos'); | |
let articulosCarrito = []; | |
cargarEventListeners(); | |
function cargarEventListeners() { | |
// Cuando agregas un curso presionando "Agregar al Carrito" | |
listaCursos.addEventListener('click', agregarCurso); | |
// Elimina cursos del carrito | |
carrito.addEventListener('click', eliminarCurso); | |
// Muestra los cursos de Local Storage | |
document.addEventListener('DOMContentLoaded', () => { | |
articulosCarrito = JSON.parse( localStorage.getItem('carrito') ) || []; | |
carritoHTML(); | |
}) | |
// Vaciar el carrito | |
vaciarCarritoBtn.addEventListener('click', () => { | |
articulosCarrito = []; // reseteamos el arreglo | |
limpiarHTML(); // Eliminamos todo el HTML | |
}) | |
} | |
// Funciones | |
function agregarCurso(e) { | |
e.preventDefault(); | |
if( e.target.classList.contains('agregar-carrito') ) { | |
const cursoSeleccionado = e.target.parentElement.parentElement; | |
leerDatosCurso(cursoSeleccionado); | |
} | |
} | |
// Elimina un curso del carrito | |
function eliminarCurso(e) { | |
if(e.target.classList.contains('borrar-curso')) { | |
const cursoId = e.target.getAttribute('data-id'); | |
// Elimina del arreglo de articulosCarrito por el data-id | |
articulosCarrito = articulosCarrito.filter( curso => curso.id !== cursoId ); | |
carritoHTML(); // Iterar sobre el carrito y mostrar su HTML | |
} | |
} | |
// Lee el contenido del HTML al que le dimos click y extrae la información del curso | |
function leerDatosCurso(curso) { | |
// console.log(curso); | |
// Crear un objeto con el contenido del curso actual | |
const infoCurso = { | |
imagen: curso.querySelector('img').src, | |
titulo: curso.querySelector('h4').textContent, | |
precio: curso.querySelector('.precio span').textContent, | |
id: curso.querySelector('a').getAttribute('data-id'), | |
cantidad: 1 | |
} | |
// Revisa si un elemento ya existe en el carrito | |
const existe = articulosCarrito.some( curso => curso.id === infoCurso.id ); | |
if(existe) { | |
// Actualizamos la cantidad | |
const cursos = articulosCarrito.map( curso => { | |
if( curso.id === infoCurso.id ) { | |
curso.cantidad++; | |
return curso; // retorna el objeto actualizado | |
} else { | |
return curso; // retorna los objetos que no son los duplicados | |
} | |
} ); | |
articulosCarrito = [...cursos]; | |
} else { | |
// Agrega elementos al arreglo de carrito | |
articulosCarrito = [...articulosCarrito, infoCurso]; | |
} | |
console.log(articulosCarrito); | |
carritoHTML(); | |
} | |
// Muestra el Carrito de compras en el HTML | |
function carritoHTML() { | |
// Limpiar el HTML | |
limpiarHTML(); | |
// Recorre el carrito y genera el HTML | |
articulosCarrito.forEach( curso => { | |
const { imagen, titulo, precio, cantidad, id } = curso; | |
const row = document.createElement('tr'); | |
row.innerHTML = ` | |
<td> | |
<img src="${imagen}" width="100"> | |
</td> | |
<td>${titulo}</td> | |
<td>${precio}</td> | |
<td>${cantidad}</td> | |
<td> | |
<a href="#" class="borrar-curso" data-id="${id}" > X </a> | |
</td> | |
`; | |
// Agrega el HTML del carrito en el tbody | |
contenedorCarrito.appendChild(row); | |
}); | |
// Agregar el carrito de compras al storage | |
sincronizarStorage(); | |
} | |
function sincronizarStorage() { | |
localStorage.setItem('carrito', JSON.stringify(articulosCarrito)); | |
} | |
// Elimina los cursos del tbody | |
function limpiarHTML() { | |
// Forma lenta | |
// contenedorCarrito.innerHTML = ''; | |
while(contenedorCarrito.firstChild) { | |
contenedorCarrito.removeChild(contenedorCarrito.firstChild) | |
} | |
} |
y al final tendremos nuestro pequeño carrito así:
Comentarios
Publicar un comentario