No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Creando las imagenes con JavaScript

21/28
Recursos

Aportes 104

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 鈥淩andom鈥, 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

![](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: {
鈥楥ontent-Type鈥: 鈥榓pplication/json;charset=utf-8鈥,
},
})
const btns = document.querySelector(鈥#btns鈥)
const btn1 = document.createElement(鈥榖utton鈥)
const btn2 = document.createElement(鈥榖utton鈥)
const btn1__text = document.createTextNode(鈥楢gregar Im谩gen鈥)
const btn2__text = document.createTextNode(鈥楺uitar 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(鈥榗lick鈥, addNewImage)

async function createImageNode() {
const { data } = await api()
const container = document.querySelector(鈥#container鈥)
const image__fox = document.createElement(鈥榠mg鈥)
const image = document.createElement(鈥榙iv鈥)
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=鈥渃ontainer1鈥
<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鈥 鈥渢e 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, 鈥溌縠n 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);

Pude hacerlo de esta forma:

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

const app = document.querySelector('#images');
const addButton = document.querySelector('button');

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

const createImage = async () => {
    try {
        const image = document.createElement('img');
        image.className = 'mx-auto';
        image.width = '320';
        image.src = await `${url}/images/${randomImage(1, 122)}.jpg`;
    
        const container = document.createElement('div');
        container.className = 'p-4';
    
        app.append(container, image);
    } catch(error) {
        console.error(error.message);
    }
}

const addImage = () => {
    const newImage = createImage();

    return newImage;
}

addButton.addEventListener('click', addImage);