No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

18 Días
4 Hrs
9 Min
21 Seg

Creando las imagenes con JavaScript

22/29
Recursos

Aportes 105

Preguntas 6

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

🙂Me encanta la honestidad con la que dice que no es necesario aprenderse las fórmulas de memoria

Chic@s, PARA LOS QUE RECIEN VEN EL VIDEO, una sugerencia, no hay necesidad de calcular un valor random. solo es leer. en la pagina donde extraemos los datos. tiene este texto.

API is Available: https://randomfox.ca/floof

ya con eso hacen la petición fetch y les entrega el resultado. no he visto el video pero observe que todos los compañeros calcularon un número random para tener ese dato aleatorio en la imagen

Reto antes de ver el codigo:

const getRandomInt = (min, max) => {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
};

const addImage = () => {
  const app = document.querySelector('#app');

  const image = document.createElement('img');
  image.width = '320';
  image.src = `https://randomfox.ca/images/${getRandomInt(1, 120)}.jpg`;
  image.alt = 'cute fox';
  image.className = 'mx-auto rounded';

  const imageContainer = document.createElement('div');
  imageContainer.className = 'p-4';
  imageContainer.append(image);

  app.append(imageContainer);
};

const adButton = document.createElement('button');
adButton.textContent = 'Agregar Imagen';
adButton.className = 'text-white px-3 py-2 rounded-lg bg-indigo-600 focus:outline-none';
adButton.addEventListener('click', addImage);

const cleanButton = document.createElement('button');
cleanButton.className =
  'rounded-lg mt-5 px-3 py-2 text-indigo-600 border border-indigo-600 focus:outline-none';
cleanButton.textContent = 'Limpiar';

const container = document.createElement('div');
container.className = 'flex flex-col items-center';
container.append(adButton, cleanButton);

const app = document.querySelector('#app');
app.append(container);```

Realizado con ASYNC/AWAIT

Dato curioso, la función random() que creamos aquí es la misma función random que vimos en el curso gratis de programación básica 👀.
.
De nuevo me gustaría recordar que no es necesario agregar un mountNode = document.querySelector("images"), esto porque HTML al ver que existe un id llamado images automágicamente crea una variable dentro de JavaScript con ese nombre 😄.
.
Les dejo el código de esta clase:
.
Creando imágenes con JavaScript

Problemas tipicos en despliegue o consumos de APIS

Hay un problema cuando consumes una API y la despliegas en un servidor y es que el servidor al menos en github, no deja que tu API o codigo AJAX obtenga o envie información a sitios no seguros, esto ni siquiera lo sabia, y cuando desplegué mi sitio en github pages me tope con este problema.
.

Como lo solucionas ?

Muy simple debes de asegurarte de que tu JS obtenga todo via HTTPS, la S es muy importante y lo otro es colocar la etiqueta
Meta con su equivalente http-equiv o name tambien es posible, añadir un policy y listo todo quedo !

<!--Esta etiqueta es muy importante para tu API --> 
<meta http-equiv= content-security-policy content= upgrade-insecure-requests>

Por fin ya pienso que la programación es para humanos uff. Pensaba que era para genios.

APUNTES DE LA CLASE SIN FALTA 😃


//genamos un numero random para crear imagenes aleatorias

const maximun = 121;
const minimun = 1;

const random = () => Math.floor(Math.random()*(maximun - minimun)+ minimun)
// creamos la imagen

const createImageNode = () => 
{
//creamos el contenedor de imagenes
    const container = document.createElement('div');
    container.className = "p-4";

//creamos la imagen y agregamos las propiedades + el link de la imagen

    const imagen = document.createElement('img');
    imagen.className = "mx-auto";
    imagen.width = '320';
    imagen.src = `https://randomfox.ca/images/${random()}.jpg`;
  
  // agregamos la imagen al contenedor

  container.appendChild(imagen)


  //retornamos el container
  return container

};

//guardaremos la imagen en una variable
//const nuevaImagen = createImageNode();

//obtenemos el contenedor padre donde estaran todos nuestros elementos
const mountNode = document.getElementById('imagenes');


//agregamos las imagenes al contenedor padre

//mountNode.append(nuevaImagen, createImageNode());

//creamos una funcion para agregar la imagen cuando damos clic a un boton

//obtenemos el boton

const addboton = document.querySelector('button');

const addImage = () => 
{ 
    //guardamos la imagen que recibimos retornada de la funcion en una variable
    const newImage = createImageNode();
    //agregamos la imagen al contenedor padre
    mountNode.append(newImage)

    
}

addboton.addEventListener('click', addImage);


En la funcion random se puede simplificar asi

const random = (maximo) => {
    return Math.floor((Math.random()*maximo - 1)+ 1))
}

Math.random() es una funcion que te retorna un valor entre 0 y 1, para simplificar un poco la fórmula que nos dió el profesor podemos multiplicar el resultado por 122 que es el máximo de imagenes que devuelve el api. Y a ésto le aplicamos el Math.floor() para redondear el resultado.

Entonces la formula quedaría de ésta forma:

const random = Math.floor(Math.random() * 122)

Lo que mas me a gustado del Curso.

Me gusta mucho el Lazy Loading como tecnica de carga y las APIS. Es increíble como se siente someter una API o tener todos esos datos en un solo lugar.

Con lo que aprendí del curso consumí una API que obtiene información de la pelicula o serie que tu quieras pueden probarla aca.
https://erickuu.github.io/api-movie/
.
El diseno es algo simple y el responsive design a veces se rompe dependiendo del cel, pero es lo de menos.

https://devdocs.io
https://devdocs.io/dom/

Si quieren usar lo de random directamente existe un paquete en npm que lo hace (más algunas validaciones): https://www.npmjs.com/package/number-random

Mi código antes de ver la clase 😄
.
HTML

<div id="imagesApp">
</div>

.
JavaScript

const URL = "https://randomfox.ca/floof/";
const imagesApp = document.getElementById("imagesApp");
const btnAdd = document.getElementById("btn-add");

const getImage = async () => {
  const res = await fetch(URL);
  const data = await res.json();

  return data.image;
};

const addImg = async () => {
  const container = document.createElement("figure");
  container.className = "p-4";
  const img = document.createElement("img");
  img.className = "mx-auto fox-img";
  img.src = await getImage();
  container.appendChild(img);
  imagesApp.appendChild(container);
};

btnAdd.addEventListener("click", addImg);

.
Lo único que añadí de CSS jeje

.fox-img {
  width: 320px;
}

Haciendo pruebas y siguiendo el curso como el profesor indica de guardar los elementos en un array y hacer un solo append, me di cuenta que cuando hacía click en el botón por una segunda vez, se supone que debía mostrar la primera imágen repetida, ya que el array ya tenía un elemento guardado, pero esto no sucedía y después un rato encontré que si no usamos .cloneNode(true), el DOM detecta que es un nodo duplicado y no lo inserta o algo así.

A pesar de que no quería que se clonaran los nodos para esta práctica, quería saber porqué pasaba eso y me llevó un rato encontrarlo 🧐.

No es necesario crear la funcion random, basta con usar la API de la página. Aquí la solución: ```js const baseUrl = 'https://randomfox.ca/floof'; const card = document.getElementById('images'); const addButton = document.querySelector('button'); const newImage = () => fetch(baseUrl) .then(response => response.json()) .then(data => { const imagecontainer = document.createElement('div'); imagecontainer.className = 'p-4'; const image = document.createElement('img'); image.className = 'mx-auto'; image.width = '320'; image.src = data.image; imagecontainer.appendChild(image); card.append(imagecontainer); }); addButton.addEventListener('click', newImage); ```const baseUrl = 'https://randomfox.ca/floof'; const card = document.getElementById('images'); const addButton = document.querySelector('button'); const newImage = () => fetch(baseUrl) .then(response => response.json()) .then(data => { const imagecontainer = document.createElement('div'); imagecontainer.className = 'p-4'; const image = document.createElement('img'); image.className = 'mx-auto'; image.width = '320'; image.src = data.image; imagecontainer.appendChild(image); card.append(imagecontainer); }); addButton.addEventListener('click', newImage);

Mi solucion antes de ver el video

const boton = document.getElementById("boton")

const raro = function(){ 
	const numeroAlea = Math.round(Math.random() * 122)
	return numeroAlea
}

function accion() {
	const contenedor = document.createElement("div");
	contenedor.className = "p-4"

	const image = document.createElement("img");
	image.className = "mx-auto";
    image.src = `https://randomfox.ca/images/${raro()}.jpg`;
    image.width = "320"
	padre.appendChild(image);
}

boton.addEventListener("click", accion)

Asi resolvi el reto🦊:

  • Guardar la api y el padre
// guardamos la API en una variable
const API = 'https://randomfox.ca/floof';

// obtenemos la app
const appNode = document.querySelector('#app');

  • Convertimos los datos a formato json
// función para consultar api
async function fetchData(urlAPI) {
    const response = await fetch(urlAPI);
    const data = await response.json();
    return data;
}
  • Creamos el template de las imagenes y lo agregamos al DOM
async function getImage(urlAPI) {
    const data = await fetchData(urlAPI);

    // crear imagen
    const image = document.createElement('img');
    image.src = await data.image;
    image.width = '320';
    image.className = 'mx-auto';

    // crear imgContainer
    const imgContainer = document.createElement('div');
    imgContainer.className = 'p-4';
    imgContainer.append(image);

   // se agrega al padre
    appNode.append(imgContainer);
}
  • Creamos el boton y le asignamos su evento
// crear boton
const addImg = async ()=> {
   // Texto y sus estilos
    const txtBoton = document.createElement('span');
    txtBoton.textContent = 'Cargar imagen'
    txtBoton.className = 'relative px-5 py-2.5 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-md group-hover:bg-opacity-0'

    // boton y sus estilos
    const boton = document.createElement('button');
    boton.className = 'relative inline-flex items-center justify-center mt-4 p-0.5 mb-2 mr-2 overflow-hidden text-sm font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-purple-600 to-blue-500 group-hover:from-purple-600 group-hover:to-blue-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800'
    boton.append(txtBoton);

    //Crear evento
    await boton.addEventListener('click', ()=>{getImage(API)});

    // agregar al padre
    appNode.append(boton);
}

addImg();

Y listo 🦊

Mi versión del desafío que dejó al comienzo:

const API = 'https://placekitten.com/g/500/200';

async function fetchData(APIurl) {
    try {
        const res = await fetch(APIurl);
        const data = res.url;

        return data;
    } catch (error) {
        return new Error(error)
    }

}

async function getKittyImage(api) {

    const app = document.querySelector('#app');
    const addKitt = document.querySelector('#app button')
    const container = document.createElement('div');

    addKitt.addEventListener('click', async () => {
        const res = await fetchData(api);

        const image = document.createElement('img');
        image.src = res;
        image.className = 'mx-auto mb-5';
        image.width = '320';

        container.append(image);
    })

    app.insertAdjacentElement('beforeend', container);
}

getKittyImage(API)

La solución propuesta antes de ver el video:

const URLBase = "https://randomfox.ca/images/";
const imageExt = ".jpg";
const imagesNode = document.querySelector("#images");

// Se le debe pasar el src por aparte para que se generen imágenes diferentes
const imageTemplate = (imagesrc) => {
  return `<div class="p-4"><img class="mx-auto" width="320" src="${imagesrc}" alt="image"></div>`;
};

// Se especifica el número de imagenes deseadas
const generateImageSrc = (numberOfImages) => {
  const srcArray = [];

  for (let index = 0; index < numberOfImages; index++) {
    const newSrc = `${URLBase}${index + 1}${imageExt}`;
    srcArray.push(newSrc);
  }
  return srcArray;
};

// Se especifica el número de imagenes deseadas
const generateImages = (numberOfImages) => {
  const imagesSrcArray = generateImageSrc(numberOfImages);
  const imagesAray = [];

  imagesSrcArray.forEach((element) => {
    const newNode = document.createElement("div");
    newNode.innerHTML = imageTemplate(element);
    imagesAray.push(newNode);
  });

  imagesNode.append(...imagesAray);
};

//Debería generar 10 imágenes
generateImages(10);

Hola! Podemos utilizar los Parametros por defecto / Default Params para definir las variables Maximo y minimo en la funcion “Random”, quedaria asi:

const random =  (maximum = 122, minimum = 1) => 
    Math.floor(Math.random() * (maximum - minimum)) + minimum;

Hola camaradas!!
Les dejo mi código en el cual uso al máximo las funcionalidades del API de zorros y tambien de ES6+:

const API = 'https://randomfox.ca/floof/';
const mountNode = document.querySelector('#images')
const btnAdd = document.getElementById('addImg');
const btnClean = document.getElementById('clean');

const fetchUrl = async ()=> {
    const response          = await fetch(API);
    // const data      = await response.json();
    // const url       = data.image;
    const { image : url}    = await response.json();
    return url;
}

const createImageNode = async ()=>{
    const container = document.createElement("div");
    container.classList.add('p-4');
    const image = document.createElement("img");
    image.src = await fetchUrl();
    image.classList.add('mx-auto');
    image.width = 320;
    container.append(image);
    return container
}

const addImage = async ()=>{
    const newImage = await createImageNode()
    mountNode.append(newImage);
}

btnAdd.addEventListener('click', addImage);

btnClean.addEventListener('click', ()=>{
    mountNode.innerHTML = "";
})
    

Hola, comparto como logre realizar el codigo para quien pueda ayudar.

Ojo, aun no visto la clase por si alguien llega a notar algun error o forma de mejorar.

let url = "https://randomfox.ca/floof/";

const container = document.querySelector('#imagenes')

const button = document.createElement('button');
button.textContent = 'Obten un nuevo Zorro';
button.className = 'boton';
container.appendChild(button);


async function fetchData() {
    const response = await fetch(url);
    const jsonConv = await response.json();
    const urlImg = jsonConv.image;

    const imagen = document.createElement('img');
    imagen.src = urlImg;
    imagen.classList = 'p-4 mx-auto'
    container.appendChild(imagen);
}

button.addEventListener('click', (e) => fetchData());

Hasta ahora venia un poco perdido con JavaScript, pero este curo me ha dejado muy tranquilo y me ha hecho entender muchísimas cosas que hasta ahora no entendía

Mi código usando fetch

const container = document.getElementById('images');
const boton = document.getElementById('btnAgregarImg');

const fetchFox = async function (){
    const response = await fetch('https://randomfox.ca/floof/');
    const fox      = await response.json()
    
    return fox;
}

const agregarImagen = async function (event) {
    const contenedor = document.createElement('div');
    contenedor.classList.add('p-4');

    const fox = await fetchFox();

    contenedor.innerHTML = `
    <img class="mx-auto" width="320" src="${fox.image}" alt="Any Fox">
    `
    
    container.appendChild(contenedor);
}

boton.addEventListener('click', agregarImagen);

Así quedo mi código.


const imgUrl = 'https://randomfox.ca/floof/';

const createNewImg = () => {

    const container = document.createElement('div');
    window.fetch( imgUrl )
        .then( resp => resp.json() )
        .then( respJson => {
            container.className = 'p-4';

            const img = document.createElement('img');
            img.className = 'mx-auto';
            img.width = '300';
            img.src = respJson.image;

            container.appendChild( img );
        })

        return container;
}

const newImg = createNewImg();
const mountNode = document.getElementById('images')

const buttonAdd = document.getElementById('button');

const addImage = () => {
    const newImage = createNewImg();
    mountNode.append( newImage );
}

buttonAdd.addEventListener("click", addImage );

Pueden usar ahora lazyload directo en el html!

revisen este codigo, fuera del css, esta muy simple!

https://github.com/domakedev/GATITOS-API-LAZY-LOAD

Creo que usar el fetch al floof demora en recargar más la pagina, no se veré como lo hizo el profe, aquí mi solución.


const app = document.querySelector("#images");

const addButton = document.createElement("button");
addButton.style = "width: 200px; height: 50px; background-color: rgb(255, 217, 217); border-radius: 8px; margin-top: 20px; font-size: 1.5rem";
addButton.textContent = "Add a fox"
app.appendChild(addButton);


function addImage() {
  const randomFox = Math.floor(Math.random() * (124 - 1)) + 1;

  const imageContainer = document.createElement("div");
  imageContainer.className = "p-10";

  const image = document.createElement("img");
  image.className = "mx-auto";
  image.width = "320"
  image.src = `https://randomfox.ca/images/${randomFox}.jpg`;
  image.alt = "fox pic"
  imageContainer.appendChild(image);
  app.appendChild(imageContainer);
}

addButton.addEventListener("click", addImage)

Reto antes de ver la solución:

HTML

<!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="description" content="Web site created using create-snowpack-app" />
    <link rel="stylesheet" type="text/css" href="%PUBLIC_URL%/_dist_/index.css" />
    <title>Snowpack & Tailwind App</title>
</head>

<body>
    <div class="py-10 max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
        <div class="text-center">
            <p class="text-base leading-6 text-indigo-600 font-semibold tracking-wide uppercase">
                Snowpack
            </p>
            <h3 class="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl sm:leading-10">
                Tailwind template
            </h3>
            <p class="mt-4 max-w-2xl text-xl leading-7 text-gray-500 mx-auto">
                Use this template to build awesome websites using Snowpack and Tailwind. It also includes Prettier and automatic publish to GitHub pages using GitHub Actions. Learn more:
            </p>
            <button class="bg-purple-400 p-2 border-4 rounded-full border-gray-400">Generar imagen</button>
            <div id="images">
            </div>
        </div>
    </div>
    <script type="module" src="%PUBLIC_URL%/_dist_/index.js"></script>
</body>

JS

const listadoImagenes = document.getElementById('images');
const URL = 'https://randomfox.ca/images/';
const boton = document.querySelector('button');

const generar = (valor) => {
    const contenedor = document.createElement('div');
    const image = document.createElement('img');
    image.src = `${URL}${valor}.jpg`;
    contenedor.className = "p-4";
    image.className = "mx-auto w-1/4";
    contenedor.append(image);
    listadoImagenes.append(contenedor);
};

function generarImagen() {
    var aleatorio = Math.round(Math.random() * 122, 1);
    generar(aleatorio);
}

boton.addEventListener('click', () => {
    generarImagen();
}) 

My Code

// random images
const min=1, max=122;
const random=()=> Math.floor(Math.random()*(max-min))+min;
// images HTML -> JS
const createImageNode=()=>{
    const container = document.createElement('div');
    container.className='p-4';
    const image= document.createElement('img');
    image.className='mx-auto';
    image.width='320';
    image.src=`https://randomfox.ca/images/${random()}.jpg`
    container.appendChild(image);
    return container;
};
const mountnode=document.getElementById('images')
//eventListerner DOM -> addImages
const addButton=document.querySelector('button');
const addImage=()=>{
    mountnode.append(createImageNode());
};
addButton.addEventListener('click',addImage);

![](

En el video aprendimos mas sobre eventos y que Raul flores bernal tiene que salir de casa 😄

este curso es muy muy muy bueno

Comparto mi código antes de ver la clase. No es mucho, pero cumple con lo básico de crear imágenes presionando el botón: ```js const url = 'https://randomfox.ca/floof/' const appImages = document.querySelector('#images') generateButton.addEventListener('click', ()=>{ fetch(url).then(image => image.json()).then(imageJson => { const imageGenerated = imageJson.image const containerImg = document.createElement('div') containerImg.className = 'p-4' const image = document.createElement('img') image.src = `${imageGenerated}` image.className = 'mx-auto' image.width = '320' containerImg.appendChild(image) appImages.appendChild(containerImg) }) }) ```NOTA: el botón 'generateButton' no lo guardo en una variable, ya que al crear un elemento con algún id en el html js crea algo así como una 'variable' con ese nombre para poder interactuar con él (no funciona con clases). Creo yo que por buena práctica se debe mandar a llamar con querySelector o getElementById, pero quise probar :D.
![](https://static.platzi.com/media/user_upload/image-4ac57d8d-214e-4a36-8a0b-b3e7f03ac8e5.jpg) ![](https://static.platzi.com/media/user_upload/image-e7df3fa0-3874-42d7-b8bc-f5f57e63a561.jpg) ![](https://static.platzi.com/media/user_upload/image-e2de1982-9e77-4795-a8f9-761a363d278b.jpg)

Despues del curso definitivo de HTML y CSS esto es pan comido para mi 😁

Que buen profe , deberia dictar mas clases en muchos mas cursos
Que gran profe , deberian haber mas cursos con el
```js const BASE_URL_API_IMGS = "https://source.unsplash.com/random"; const BASE_URL_API_FOX = "https://randomfox.ca/images/"; const imgContainer = document.getElementById("img-container"); const randomSize = () => Math.floor(Math.random() * 10) + 90; const createImgNode = () => { const url = `${BASE_URL_API_FOX}/${randomSize()}.jpg`; const img = document.createElement("img"); img.src = url; img.alt = url; img.style.width = `320px`; img.classList.add("p-4", "mx-auto"); return img; }; const numberOfImages = 100; for (let index = 0; index < numberOfImages; index++) { const img = createImgNode(); imgContainer.append(img); } ```const BASE\_URL\_API\_IMGS = "https://source.unsplash.com/random";const BASE\_URL\_API\_FOX = "https://randomfox.ca/images/"; const imgContainer = document.getElementById("img-container"); const randomSize = () => Math.floor(Math.random() \* 10) + 90; const createImgNode = () => { const url = `${BASE\_URL\_API\_FOX}/${randomSize()}.jpg`;// const url = `${BASE\_URL\_API\_IMGS}`; const img = document.createElement("img"); img.src = url; img.alt = url; img.style.width = `320px`; img.classList.add("p-4", "mx-auto"); return img;}; const numberOfImages = 100;for (let index = 0; index < numberOfImages; index++) { const img = createImgNode(); imgContainer.append(img);}

Hice el código con la función random() y también con lo que aprendí de fetch
Porfa si se puede mejorar me confirman.
PS la función random() esta comentada pero ambas sirven

const addNewImg = document.querySelector("#adNewImg")
const images = document.querySelector('#images');

/* const maxNum = 123;
const minNum = 1;
const random = () => Math.floor(Math.random() * (maxNum - minNum) + minNum)

function createImages() {
    const contenImg = document.createElement('div');
    const foxImg = document.createElement("img");
    contenImg.classList.add('p-4');
    foxImg.classList.add('mx-auto')
    foxImg.src = `https://randomfox.ca/images/${random()}.jpg`;
    foxImg.style.width = "300px";

    contenImg.appendChild(foxImg);
    images.appendChild(contenImg)
}

addNewImg.addEventListener("click", createImages) */

const url = "https://randomfox.ca/floof";

async function fetchData() {
    const response = await fetch(url);
    const data = await response.json();
    
    const contenImg = document.createElement('div');
    const foxImg = document.createElement("img");
    contenImg.classList.add('p-4');
    foxImg.classList.add('mx-auto')
    foxImg.style.width = "300px";
    foxImg.src = `${data.image}`;

    contenImg.appendChild(foxImg);
    images.appendChild(contenImg)
}

addNewImg.addEventListener("click", fetchData)

Un poco mas comrpimido el código

Gracias al aporte de un compañero pude plantear una solución con uso de fetch

const urlRandomFox = "https://randomfox.ca/floof/" //url de imgs random
const imgContainer = document.getElementById("images") //contenedor general
const newImg = document.getElementById("newImg") //boton 

newImg.addEventListener("click", createImg)

function createImg() {
    window
        .fetch(urlRandomFox)
        .then((res) => res.json())
        .then((resjson) => {
            const urlRandom = resjson.image
    
            const img = document.createElement("img")
            img.className = "mx-auto"
            img.width = '320'
            const divCh = document.createElement("div")
            divCh.className = "p-4"

            img.src = urlRandom

            divCh.append(img)
            imgContainer.append(divCh)
        })
}            

Solución antes de ver el video:

const url = 'https://randomfox.ca/floof/'

const imagesNode = document.getElementById('images')
const add = document.getElementById('new')
const clear = document.getElementById('delete')

async function foxImages() {
    const response = await fetch(url);
    const responseJSON = await response.json();

    const image = document.createElement('img');
    image.src = responseJSON.image;
    image.className = 'mx-auto';
    image.width = '320';

    const card = document.createElement('div');
    card.className = 'p-4';
    card.appendChild(image);

    imagesNode.appendChild(card);
}

const clearImages = () => imagesNode.innerHTML = '\n        '

add.addEventListener('click', foxImages)
clear.addEventListener('click', clearImages)

Asi se ve mi JavaScript:

PD: Cambie el nombre de el id de images a pictures

const ENDPOINT = "https://randomfox.ca/images";
let picturesRenderedCounter = 0;

const addPictureButton = document.getElementById("add-picture-button");
const picturesContainer = document.getElementById("pictures");

const buttonEventListener = () => {
  picturesRenderedCounter++;
  const newPictureURL = `${ENDPOINT}/${picturesRenderedCounter}.jpg`;

  const pictureWrapperElement = document.createElement("div");
  pictureWrapperElement.classList.add("p-4");

  const pictureElement = document.createElement("img");
  pictureElement.src = newPictureURL;
  pictureElement.alt = `fox #${picturesRenderedCounter}`;
  pictureElement.classList.add("mx-auto");
  pictureElement.width = "320";

  pictureWrapperElement.append(pictureElement);

  picturesContainer.append(pictureWrapperElement);
}

addPictureButton.addEventListener("click", buttonEventListener);

Aplicando el contenido expuesto con async y await:
.
.
.

const API = 'https://randomfox.ca/floof';

const wrapper = document.querySelector('#images');

async function fetchData(url){
    //fetching data
    const raw = await fetch(url);
    const parsed = await raw.json();

    //creating container
    const container = document.createElement('div');
    const image = document.createElement('img');
    image.src = parsed.image;

    container.classList.add('p-4');
    image.classList.add('mx-auto');
    image.width = 300;

    container.append(image);
    wrapper.append(container);
}

const button = document.querySelector('button');
const addImage = () => {
    const newImage = fetchData(API);
    return newImage;
}

button.addEventListener('click', addImage);

const api = axios.create({
baseURL: ‘https://randomfox.ca/floof/’,
headers: {
‘Content-Type’: ‘application/json;charset=utf-8’,
},
})
const btns = document.querySelector(’#btns’)
const btn1 = document.createElement(‘button’)
const btn2 = document.createElement(‘button’)
const btn1__text = document.createTextNode(‘Agregar Imágen’)
const btn2__text = document.createTextNode(‘Quitar Imágen’)
btn1.className = 'button’
btn2.className = 'button’
btns.className = 'container’
btn1.append(btn1__text)
btn2.append(btn2__text)
btns.append(btn1, btn2)
btn1.addEventListener(‘click’, addNewImage)

async function createImageNode() {
const { data } = await api()
const container = document.querySelector(’#container’)
const image__fox = document.createElement(‘img’)
const image = document.createElement(‘div’)
image__fox.className='image__fox’
image.className = 'image’
console.log(Ruta: ${data.image} ---)
image__fox.src = ${data.image}
image.appendChild(image__fox)
document.body.appendChild(image)
container.appendChild(image)
}

function addNewImage(){
createImageNode()
}

Mi solución antes de ver el video:

const URL = 'https://randomfox.ca/floof/';

console.log('Happy hacking :)')

async function fetchData(){
    const data = await fetch(URL);
    const dataJson = await data.json();

    const img = document.createElement('img');
    img.src = dataJson.image;
    img.className = 'mx-auto'

    const divImage = document.createElement('div');
    divImage.className = 'p-4';
    divImage.appendChild(img);

    const divApp = document.createElement('div');
    divApp.className = 'app'
    divApp.appendChild(divImage);

    const body = document.querySelector('body');
    body.appendChild(divApp);

}

fetchData();

yo lo hice asi:

const mountNode = document.querySelector('#images');

const createImage = () => { 
    const img = document.createElement('img');
    img.style.width = '320px';
    img.className = 'mx-auto';
    
    const div = document.createElement('div');
    div.className = 'p-4';
    div.append(img);
    mountNode.append(div);

    const url = 'https://randomfox.ca/floof';
    console.log(url); 
    window.fetch(url)
            .then(response=>response.json())
            .then(myjson => {
                console.log(myjson);
                img.src=myjson.image;
            });
}

const addButton = document.querySelector('button');
const accion = () => createImage();
addButton.addEventListener('click', accion);

SOLUCIÓN ANTES DE VER LA RESPUESTA

En el archivo index.html

        <div id="images">
          <button  id="botonAgregarImagen" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
            Button
          </button>

        </div>

En el archivo index.js

/**
 * This file is just a silly example to show everything working in the browser.
 * When you're ready to start on your site, clear the file. Happy hacking!
 **/
function getRandomInt(max) {
    return Math.floor(Math.random() * max);
  }



const appNode = document.querySelector('#images');

const botonAgregar = document.querySelector('#botonAgregarImagen');


const agregarImagen = () => {
    const numeroAleatorio = getRandomInt(124);

    const contenedor = document.createElement('div');

    contenedor.className = "p-4";

    const imagen = document.createElement('img');

    imagen.className = "mx-auto";
    imagen.width="320";
    imagen.src=`https://randomfox.ca/images/${numeroAleatorio}.jpg`;

    contenedor.append(imagen)

    appNode.append(contenedor);
}


botonAgregar.addEventListener("click", agregarImagen);

Les comparto mi código en donde se lee la información de la API del Fox y se obtienen imágenes aleatoras. Además un botón que agrega imagenes ilimitadas, ya que usa una función y anida divs. Cada imagen es distinta porque hace la petición a la API de forma asincrónica.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta
      name="description"
      content="Web site created using create-snowpack-app"
    />
    <!--
      Snowpack will replace %PUBLIC_URL% with the value you have for `baseUrl` in `snowpack.config.js`.
      Make sure to update it with your GitHub Page URL. https://<your-username>.github.io/<your-repo-name>

      More about config options:
      - https://www.snowpack.dev/reference/configuration#buildoptions.baseurl
    -->
    <link
      rel="stylesheet"
      type="text/css"
      href="%PUBLIC_URL%/_dist_/index.css"
    />
    <title>Lazy Load Images</title>
  </head>
  <body>
    <!--
      This HTML file is a template.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.

      Start modyfing from here.
    -->
    <div id="contenedor" class="py-10 max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
      <div class="text-center">
        <h3
          class="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl sm:leading-10">
        Lazy Load Images
        </h3>
        <p class="mt-4 max-w-2xl text-xl leading-7 text-gray-500 mx-auto p-4">
          En este script podemos cargar imagenes aleatoras desde la API Fox Images
        </p>
        <div class="rounded-md shadow">
          <button id="addImage" class="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 md:py-4 md:text-lg md:px-10">Agregar imagen de zorro</button>
        </div>
      </div>
    </div>

    <!-- Add more scripts here -->
    <script type="module" src="%PUBLIC_URL%/_dist_/index.js"></script>
  </body>
</html>
 

Script de JavaScript

const baseUrl = "https://randomfox.ca/floof";

const addImage = () => {
    fetch(baseUrl).then(response => {
        return response.json();
        }).then(data => {
        const nodoImagen = () => {
            const imagesrc = data.image;
            const divimg = document.createElement("div");
            divimg.className = "p-4";
    
            const imagen = document.createElement("img");
            imagen.className = "rounded-md mx-auto shadow-md";
            imagen.src = imagesrc;
            //imagen.width = "350";
    
            divimg.append(imagen);
    
            return divimg;
        }
    
        const nuevaImagen = nodoImagen();
        const nodoMontaje = document.getElementById("contenedor");
    
        nodoMontaje.append(nuevaImagen);
    
        //console.log(data);
        }).catch(err => {
        // Do something for an error here
        });
}

const addButton = document.getElementById("addImage");
//const accion = () => console.log("Boton agregar presionado");

addButton.addEventListener("click", addImage);

mi codigo un tin diferente

const baseUrl = 'url';

const appNode = document.getElementById('images')

const btn = document.createElement('button');
const btnText = document.createTextNode('agregar');
btn.appendChild(btnText);
btn.style.backgroundColor = '#ff975d'
btn.className = "p-3"
btn.addEventListener('click', load)
appNode.appendChild(btn);

var randomId = () => Math.floor(Math.random()*(122+1))

function load() {
    const container = document.createElement('div');
    container.className = 'p-4';
    
    const img = document.createElement('img');
    img.className = 'mx-auto';
    img.src = `${baseUrl}${randomId()}.jpg`
    img.width = '320'

    container.appendChild(img);
    appNode.appendChild(container);
}
load();

Reto antes de ver la clase, hasta ahora sólo es pedir y mostrar las imágenes, todo desde js, para implementar el lazy loading ya es más complejo, supongo que lo haremos con intersection observer 🤔

const URL_API = "https://randomfox.ca/floof";

const getRandomImage = async () => {
	const res = await fetch(URL_API).then((response) => response.json());
  const gallery = document.getElementById("gallery")
  const img = document.createElement("img")
  img.src = res.image
  gallery.appendChild(img)
};

const container = document.querySelector("main");
const button = document.createElement("button");
button.className =
"mx-auto my-4 block bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded";
button.textContent = "Añadir imagen";
button.type = "button";
const gallery = document.createElement("div");
gallery.id = "gallery";
gallery.className = "flex flex-wrap justify-center";
button.addEventListener("click", getRandomImage);
container.append(button, gallery);

El mio con async:

const url = 'https://randomfox.ca/floof';
const container = document.querySelector('#container')
container.style.display = 'flex'
container.style.width = '400px'
container.style.flexDirection = 'column'
container.style.margin = '0 auto'
container.style.gap = '20px'

const button = document.createElement('button')
button.innerHTML = 'Agregar imagen'
button.style.fontWeight = 'bold'
button.style.width = '150px'
button.style.backgroundColor = 'gray'
button.style.display = 'block'
button.style.margin = '20px auto'
button.style.borderRadius = '10px'

container.insertAdjacentElement("beforebegin", button)



async function fetchData(){
    const response = await fetch(url);
    const data = await response.json();
    
    const img = document.createElement('img')
    img.src = data.image;
    container.append(img)    
}

button.addEventListener('click', ()=>{
    fetchData()
})

Si hacemos un pedido a la API, ya por si mismo nos entrega imágenes aleatorias. Solo hay que hacer un request a la url (https://randomfox.ca/floof), como nos indica en la pagina.

Dejo mi código de ejemplo con Fetch y Async/Await.

P.D: Escucho correcciones y sugerencias, aun estoy aprendiendo 😋

const API = "https://randomfox.ca/floof"

const sectionImages = document.querySelector("section.images")
const btnAddImage = document.querySelector("#addImage")

const fetchImage = async url =>{

    const imageSrc = await (await fetch(url)).json();

    const imageContainer = document.createElement("div")
    imageContainer.className = "image-container"

    const image = document.createElement("img")
    image.src = imageSrc.image

    imageContainer.appendChild(image);

    sectionImages.appendChild(imageContainer) 
}

btnAddImage.addEventListener("click", () => fetchImage(API))

Este curso me ha resultado absolutamente genial!!, el profe es super calmado y se le entiende todo lo que explica y además los retos que pone son super interesantes 😄

Qué cool son las clases con el profe J Alvarez, el dueño del sistema 😎

Este es mi código hecho antes de seguir con la clase, bastante sencillo, aunque le dí a mi código una apariencia como Pinterest.

//Web Api
const baseUrl = "https://randomfox.ca/floof/",
    appNode = document.querySelector('#images');
    btnAdd = document.querySelector('#btn-fox')


async function fetchData() {
    const response = await fetch(baseUrl),
        jsonResponse = await response.json();

    //Se toma la imagen
    const foxImage = document.createElement("img");
    foxImage.src = jsonResponse.image;
    foxImage.classList.add('foxy-img');

    //Se crea el contenedor
    const container = document.createElement("div");

    //Se Agrega la imagen al contenedor
    container.append(foxImage);

    //Se Agrega al DOM
    console.log('Fox Added')
    appNode.append(container)
    
}

btnAdd.addEventListener('click', fetchData)

Reto antes de ver la clase 😄

const baseUrl = 'https://randomfox.ca/images/'
const imagesContainer = document.querySelector('#images')

function randomIntFromInterval(min, max) { 
    return Math.floor(Math.random() * (max - min + 1) + min)
}

const addImage = () => {
    const imageNumber = randomIntFromInterval(1, 123)
    const imageUrl = `${baseUrl}${imageNumber}.jpg`

    const containerImage = document.createElement('div')
    containerImage.className = 'p-4'

    const imageEl = document.createElement('img')
    imageEl.src = imageUrl
    imageEl.width = 320
    imageEl.className = 'mx-auto'

    containerImage.appendChild(imageEl)
    imagesContainer.appendChild(containerImage)
}

const addButton = document.querySelector('#add-image-button')
addButton.addEventListener('click', addImage)

Que buena clase

Mi solución al reto antes de ver la clase:

  1. Agregué en el html un id al padre del div.images.
    id=“container1”
<div class="py-10 max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
      <div class="text-center" id="container1">
	////El resto de código
      </div>
</div>
  1. En el Js hice el resto:

const url = "https://randomfox.ca/floof/";
const images = document.getElementById('images');
const container1 = document.querySelector("#container1");

const buttonsContainer = document.createElement('div');
const agregar = document.createElement('button');
const limpiar = document.createElement('button');
const textoAgregar = document.createTextNode('Agregar');
const textoLimpiar = document.createTextNode('Limpiar');


buttonsContainer.className = "p-4";
agregar.className = "p-4 w-32 bg-indigo-400 rounded-full mx-3 hover:bg-blue-300 active:bg-blue-800";
limpiar.className = "p-4 w-32 bg-indigo-400 rounded-full mx-3 hover:bg-blue-300 active:bg-blue-800";
agregar.style.color = "white";
limpiar.style.color = "white";
agregar.style.outline = "none";
limpiar.style.outline = "none";


container1.insertBefore(buttonsContainer, images);
buttonsContainer.append(agregar, limpiar);
agregar.appendChild(textoAgregar);
limpiar.appendChild(textoLimpiar);



 const stickImages = (url) => {
    fetch(url)
    .then(respuesta => respuesta.json())
    .then(responseJson => {
        const div1 = document.createElement('div');
        div1.className = 'div1 p-4';

        const img1 = document.createElement('img');
        img1.src = responseJson.image;
        img1.className = 'mx-auto';
        img1.style = "width: 320px";

        div1.appendChild(img1);
        images.appendChild(div1);
        console.log(responseJson)
    })
}

agregar.addEventListener('click', function(){stickImages(url)});
limpiar.addEventListener('click', removeImages);

function removeImages(){
    const allImages = document.getElementsByClassName('div1');
    const arrayImages = Array.from(allImages);
    arrayImages.forEach( item =>{
        const parent = item.parentNode;
        parent.removeChild(item);
    });
}

Me daba un error al agregar la imagen y descubrí que era porque me faltaba redondear el valor que daba nuestra función random, aquí dejo mi código:

const random = () => (Math.random() * (maxium - minium)) + minium
const createImageNode = () => {
    const container = document.createElement("div")
    container.className = "p-4"
    const imagen = document.createElement('img');
    imagen.className = "mx-auto"
    imagen.width = "320"
    imagen.src = `https:\/\/randomfox.ca\/images\/${Math.round(random())}.jpg`
    container.appendChild(imagen)

    return container
}

Encontré y adapté una función para que los número generados aleatoriamente no se repitan:

const generateRandomInteger = max =>  
  Math.floor(Math.random() * max) + 1

const maxFoxes = 123
const arr = []
const mountNode = document.querySelector('#images')
const addFox = document.querySelector('#addFox')

const addImage = () => {
  
  const v = generateRandomInteger(maxFoxes)
  if(!arr.some((e) => {return e == v})){ 
    arr.push(v);
    const image = document.createElement('img');
    image.src = `https://randomfox.ca/images/${v}.jpg`;
    image.alt = 'Fox :3';
    image.className = 'w-96';

    const imageContainer = document.createElement('div');
    imageContainer.className = 'pb-5';
    imageContainer.append(image);
    
    mountNode.append(imageContainer);
  }
};

addFox.addEventListener('click', addImage)

Este es mi codigo antes de ver la clase no tiene nada de asincronismo pero funciona tanto el boton de agregar imagen y limpiar todo, j ugue particularmente con los valores de UNDEFINED y NULL para agregar o no contenido

```jsx
/*----------------------------------------------------
DESARROLLO APP JAVASCRIPT 
------------------------------------------------------*/
const $imgApp = document.querySelector('.imgApp') 

const min = 1
const max = 123
const random = () => Math.floor(Math.random()*(max-min))+min

const addImg = ()=>{
    const $verificador = document.querySelector('.contenedorImg')
    let $containImgs;
    if($verificador == null){
        $containImgs = document.createElement('div') 
        $containImgs.className='contenedorImg'
        $imgApp.appendChild($containImgs)
    }

    //Funcion generadora imgs
    const generateImg = ()=>{
        const $imagen = document.createElement('img')    
        $imagen.src=`https://randomfox.ca/images/${random()}.jpg`
        $imagen.className='mx-auto'
        $imagen.width='320'
        $imagen.style.setProperty('margin-bottom','10px')
        $imagen.style.setProperty('border', '2px dashed black')
        $imagen.id='foxImg' 

        return $imagen
    }

    if($containImgs == undefined){
        const $nodoContainImgs = document.querySelector(".contenedorImg")
        $nodoContainImgs.appendChild(generateImg())
    } else{
        $containImgs.appendChild(generateImg())
    }

}

const $addImgDom = document.querySelector('.btnObtener')
$addImgDom.addEventListener('click', addImg)

//FUNCION PARA ELIMINAR
const fnEliminarNodo = ()=>{
    let $nodoImgs = document.querySelector(".contenedorImg");    
   
    if($nodoImgs != undefined){
        $nodoImgs.remove()
    } 
    
}

const $btnEliminar = document.querySelector(".btnClean")
$btnEliminar.addEventListener("click", fnEliminarNodo)

Excelente profesor

Este es mi resultado del reto antes de ver el vídeo:

😎😁Mi solución al reto. Es código de principiante pero estoy orgulloso jajaja. Aun no se cual sea la solución del profe. Si ven que este código pueda causar algún conflicto o tenga malas practicas me encantaría me lo hagan saber💚.

html

 <button id="add" class="m-4 p-2 bg-blue-500 text-white text-xl rounded">
          Agregar imagen
   </button>
      <div id="images">

index.js

const images = document.querySelector('#images');
const boton = document.querySelector('#add');
let i = 1;

boton.addEventListener("click",() => {

    if(i<=123){
        const url = 'https://randomfox.ca/images/'+i+'.jpg';
        let imagen = document.createElement('img');
        
        console.log(url);    
        imagen.src = url;
        imagen.style.width = "320";
        imagen.className = "mx-auto p-4";
        images.appendChild(imagen);
        i++;
    }
    else {
        if(i===124){
            let h3 = document.createElement('H3');
            h3.textContent = "Ya son todas las imagenes 😁";
            h3.className = "text-blue-500";
            images.appendChild(h3);
            i++;
        }
    }

});
 

Sencillo paso a paso sin apuros y entretenido.
Incluso me animo a investigar que es el snowpack , la verdad que el no le da mucha importancia pero gracias a eso he estado investigando sobre el tema de snowpack y webpack…

El máximo sería 123 ya que este es excluido según la fórmula:

// Retorna un entero aleatorio entre min (incluido) y max (excluido)
// ¡Usando Math.round() te dará una distribución no-uniforme!
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

Fuente: Aquí

Listo 😄
En el HTML agregue una section para ser el contenedor padre de todas las imágenes.

      <section id="imagesContainer">

      </section>

y el JS

const URL = "https://randomfox.ca/images/"
const container = document.querySelector("#imagesContainer")
const maxNumberofImageInAPI = 123


const imagesCollection = []
const numberOfFoxes = 10


const generateImages = (maxNumberofImages) =>{
    for(let i = 0; i < numberOfFoxes; i++){
        const containerImage = document.createElement("div")
        containerImage.className = "p-4" 
        
        const foxImage = document.createElement("img")
        foxImage.src = `${URL}${Math.floor(Math.random() * (maxNumberofImages - 1)) + 1}.jpg`
        foxImage.className = "mx-auto"
        foxImage.style.width = "320px"

        containerImage.append(foxImage)

        imagesCollection.push(containerImage)
    
    }
        container.append(...imagesCollection)
}

generateImages(maxNumberofImageInAPI)

Wow super clase y super curso.

Otra forma para obtener un número random puede ser la siguiente:

const random = (max = 122) => Math.ceil(Math.random() * max)

Yo lo hice con fetch pero con promesas. Por si alguien le sirve.

Otra manera de hacer el random es

const random = Math.ceil(Math.random() * maxNumber)

Esto nos data un numero del 1 al maxNumber, en este caso creo que había 140 fotos de zorros o algo asi

Este es mi código antes de ver la clase 😄

//Usaremos async / await para este proyecto.

// la url traerá un dato random
const baseUrl = "https://randomfox.ca/floof/"
const idImg = document.querySelector("#images")
const button = document.querySelector("#button")

const createImg = async () => {
    // Petición Asincrona a nuestra url
    let imgUrl = await fetch(baseUrl)
    let data = await imgUrl.json()
    let valor = data.image
    imgTemplate(valor)
}

const imgTemplate = (url) => {

    // Creamos nuestro contenedor de img
    const card = document.createElement("div")
    card.className = "p-4"

    // Creamos nuestra imagen
    const img = document.createElement("img")
    img.src = url
    img.setAttribute("width", "320")
    img.setAttribute("alt", "fox")
    img.className = "mx-auto"

    //agregamos las imagenes a las cards
    card.append(img)

    //Agregamos imagenes a un array o al document
    idImg.append(card)

}

button.addEventListener("click", createImg)

Me encantó experimentar con este proyecto 😃

Realmente he aprendido cosas que antes me parecían imposibles, amo este curso carajo.

Les comparto mi solución antes que el profesor la haga la de el. Que agradable que te motiven así, deberían agregar siempre este tipo de retos en los cursos. 😁

const btnAdd = document.querySelector('.btn-primary')
const limpiar = document.querySelector('.clean-image')

const imageContainer = document.querySelector('.image-container')

const minimo = 1
const maximo = 122
const random = () => Math.floor(Math.random() * (maximo-minimo))+1

btnAdd.addEventListener('click', (e) => {
	const img = document.createElement('img')
	img.src = `https://randomfox.ca/images/${random()}.jpg`
	img.setAttribute('height','400px')
	img.classList.add('d-block','m-auto')
	imageContainer.appendChild(img)
})

limpiar.addEventListener('click', (e) => {
	e.preventDefault()
	imageContainer.remove()
})

Mi codigo usando la api simplificada de Unsplash

Mi reto sin ver el video.

const app = document.querySelector('#images-container');
const newContent = [];

const loadImage = () => {
    fetch('https://randomfox.ca/floof/')
        .then( response => response.json())
        .then( data => {
            // create div
            const div = document.createElement('div');
            div.className = 'p-4';

            // create img
            const img = document.createElement('img');
            img.src = data.image;
            img.className = 'mx-auto';
            img.width = '320';

            div.appendChild(img);
            newContent.push(div);
            app.append(...newContent);
        });
}

const button = document.querySelector('#button-load');
button.addEventListener('click', loadImage);

Me da este error.

¿Alguien más creó su botón con javascript? Je.

const button = document.createElement('button')
button.textContent = 'Agregar imagen.'

Trate de minimizar mucho el codigo a solo 38 lineas espero les ayude!


const maximum = 122
const minimum = 1

const get = select => document.querySelector(select)
const crear = select => document.createElement(select)
const getRandom = () => Math.floor(Math.random() * ( maximum - minimum )) + minimum
const buttonAdd = get('button')
const app = get('#images')

const AddImage = () => app.append( createImageComponent() )

buttonAdd.addEventListener( 'click' , AddImage )

const createImageComponent = () => 
{

    const imagen = crear('img')
    imagen.className = 'mx-auto'
    imagen.width = '320'
    // imagen.src = url
    imagen.src = `https://randomfox.ca/images/${getRandom()}.jpg`

    const container = crear('div')
    container.className = "p-4"
    container.append( imagen )

    return container

}

const RenderDOM = () => {
    
    app.append( createImageComponent() )
    
}

RenderDOM()

no se ustedes pero yo siento que utilizar tailwind es innecesario creo que los estilos son muy basicos comoo para usar algo asi, ademas mientras se buscan las clases en tailwind se pueden crear los estilos que opinan ustedes?

  • Reto (Trate de hacer un codigo generico)
const addButton = document.querySelector('button')
const parent = document.querySelector('#images')

function createElement(type, className='') {
    const node = document.createElement(type)
    if (className != '') {
        node.className = className
    }
    return node
}

function generateRandomImage(src, width) {
    let container = createElement('div', 'p-4')
    //
    const element = createElement('img', 'mx-auto rounded-lg')
    element.width = width
    element.src = src
    container.append(element)
    //console.log(images);
    return container
}

function generateRandomNumber(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min)
}

let printImage = () => {
    return generateRandomImage(`https://randomfox.ca/images/${generateRandomNumber(1, 122)}.jpg`, 320)
}

function printRandomImages (qty, container) {
    const imagesArray = []
    for (let index = 0; index < qty; index++) {
        imagesArray.push(printImage())
    }
    //console.log(printImage());
    container.append(...imagesArray)   
}

const addImage = () => {
    printRandomImages(1, parent)
}

addButton.addEventListener('click', addImage)     

Jonathan es verdaderamente un gran profesional. Espero que vengan más cursos dictados por el donde nos entregue mucha de su experiencia.

// Imágenes aleatorias
const minimum = 1;
const maximum = 122;
const random = () => Math.floor(Math.random() * (maximum - minimum) + minimum);

const createImageNote = () => {
    const container = document.createElement('div');
    container.className = "p-4";

    const imagen = document.createElement('img');
    imagen.class = "mx-auto";
    imagen.width =  "320";
    imagen.src = `https://randomfox.ca/images/${random()}.jpg`;
    
    container.appendChild(imagen);
    
    return container;
}

//2.1 Imágenes aleatorias.
const nuevaImagen = createImageNote();
// Agregar una imágene

const mountNode = document.getElementById('images');

//Agregar boton para que al darle click se genere una imagen
const addButton = document.querySelector('button')

const addImage = () => {
    const newImage = createImageNote();
    mountNode.append(newImage);
};

//3 agregar imágenes como acción
addButton.addEventListener('click', addImage);

Este es mi código antes de ver el video, como muchos usaban numero random , quise usar la API que ahi te da, use funciones async y await

HTML

          <button id="addImg">Agregar Imagen</button>
          <button id="clean">Limpiar Imagenes</button>
        </div>
        
        <div id="imagenes">
          <div class="p-4">
            <img   
              width="300px"  
              src="https://randomfox.ca/images/2.jpg" 
              alt="zorrito" 
              class="mx-auto">
          </div>
          <div class="p-4">
            <img 
              width="300px"
              src="https://randomfox.ca/images/38.jpg" 
              alt="zorrito" 
              class="mx-auto">
          </div>
        </div>

JavaScript

const API = 'https://randomfox.ca/floof/'
const containerNode = document.getElementById('imagenes');
const btnAdd = document.getElementById('addImg');
const btnClean = document.getElementById('clean');

const fetchImage = async () => {
    const response = await fetch(API);
    const responseJSON = await response.json();
    const url = responseJSON.image;
    
    const containerImg = document.createElement('div');
    containerImg.className = "p-4";

    const image = document.createElement('img');
    image.src = url;
    image.className = "mx-auto";

    containerImg.appendChild(image);
    containerNode.appendChild(containerImg);
}

btnAdd.addEventListener('click',fetchImage);

Use CSS para mis botones

.buttons {
    font-family:  Helvetica,Arial, sans-serif;
    font-size: 1.2rem;
    display: flex;
    flex-direction: column;
    height: 8rem;
    align-items: center;
    justify-content: space-evenly;
}


.buttons button {
    margin: 0 0.5rem;
    width: 13rem;
    height: 2rem;
    border-radius: 0.4rem;
    cursor: pointer;
    outline: none;
}

#clean {
    color: beige;
    background-color: indigo;
}

#addImg {
    color: indigo;
    background-color: beige;
}

img {
    width: 300px;
}

Pueden usar esta función para obtener una imagen random:

const randomImage = () => Math.floor(Math.random() * 123)

Sí, puse 123 a pesar de existir solo 122 imáganes. Esto es porque random() te arroja valores menores que 1 y mayores que 0. Por eso uso también floor().

Yo agregue un array con los diferentes temas que me interesan para las imágenes.

Mi codigo

Genial

Reto cumplido:

HTML

<div id="images">
          <button id="button" class="m-5 px-5 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700">
            Load a Fox
          </button>
        </div>

JS

const url = 'https://randomfox.ca/images/';
const button = document.querySelector('#button');
const imagesContainer = document.querySelector('#images');

const newImage = () => {
    const card = document.createElement('div');
    card.className = 'p-4';
    imagesContainer.append(card);

    const image = document.createElement('img');
    image.className = 'mx-auto';
    image.width = '320';
    image.src = `${url}${Math.ceil(Math.random()*122)}.jpg`;
    card.append(image);
}

button.addEventListener('click', newImage);

Resultado

¿Que implicaciones tiene declarar una función dentro de una constante?

¿La función puede ser usada renglones antes de que se declare la constante?

¿La funcion puede ser modificada?

Este es mi código:

const randomNum = max => Math.floor((Math.random()* max -1) + 1);

getImages.addEventListener('click', () => {
    let url = 'https://randomfox.ca/images/:id.jpg'
    let nodoImg = document.createElement('img');
    nodoImg.src = url.replace(':id', randomNum(120))
    nodoImg.className ='image-item';
    container.append(nodoImg);
})

Como buenas prácticas no es recomendable cargar desde Javascript elementos estáticos en el DOM (como los botones, que permanecen estáticos en la web y estan siempre) ya que puede suponer una carga de procesamiento extra para nuestra web, a menos que sea por un motivo de práctica, en ese caso está bien.

Challenge

const container = document.getElementById('root')
const boton = document.getElementById('buton')

boton.addEventListener('click', getAnImage)

function getAnImage() {
    let random = Math.floor(Math.random() * (122 - 1)) + 1

    const createImage = (url) => {
        const Figure = document.createElement('figure')
        Figure.className ='p-4'

        const image = document.createElement('img')
        image.src=`${url}`
        image.className = 'mx-auto'
        image.width = '320'

        Figure.appendChild(image)
    
        return Figure
    }
    const newImage = createImage(`https://randomfox.ca/images/${random}.jpg`)
    container.appendChild(newImage)
}```

Cuando el profe dijo… “te reto a que lo hagas por cuenta” tuve… pero mi manera rompió todo, hacía peticiones a la url de las imágenes, pero nunca funcionó… al ver la solución del profe, Yo, “¿en serio… era así?” de ahí me di cuenta que tenemos el complejo de complicar siempre las cosas.

Antes de la clase 😃

const container = document.querySelector('#images')

const createImage = () => {
    const numRandom = (min, max) => Math.floor(Math.random() * (min - max) + max)

    const image = document.createElement('img')
    image.src = `https://randomFox.ca/images/${numRandom(1, 122)}.jpg`
    image.className = "mx-auto"
    image.width = '320'

    const imageContainer = document.createElement('div')
    imageContainer.className = 'p-4'
    imageContainer.append(image)

    container.append(imageContainer)

}

const button = document.createElement('button')
button.className = 'font-bold text-white py-2 px-4 rounded'
button.style.backgroundColor = 'blue'
button.textContent = 'Agregar Imagen'
button.type = 'button'
button.addEventListener('click', createImage)

container.append(button)```

This is my code before of the practice:

const url = "https://randomfox.ca/images/";

const btnAdd = document.getElementById('btnAdd');
const btnClear = document.getElementById('btnClear');
const allImg = []

function addImgRandom(){
    //estructura del math.random => Math.floor(Math.random() * (max - min)) + min;
    const number = Math.floor(Math.random() * (119 - 1)) + 1;
    console.log(number)
    const divImg = document.createElement('div');
    const img = document.createElement('img');
    img.src = `${url}${number}.jpg`
    img.width = "320"
    img.style.padding = "10px"
    divImg.append(img)
    allImg.push(divImg)
    document.body.append(...allImg)
}
btnAdd.addEventListener('click', addImgRandom)```

Que Raul Florez Bernal tiene que salir, que tiene otra reunion 🙊🙊🙊🙊

Mi boton remover Imagen antes de ver la siguiente clase.

const removeButton = document.querySelector('#remove');
removeButton.className = 'text-white px-3 py-2 rounded-lg bg-red-900 focus:outline-none';

const removeImage = () => {
const container = mountNode.lastElementChild;
mountNode.removeChild(container);
}

removeButton.addEventListener('click', removeImage);