Location y hash navigation
Clase 8 de 17 • Curso de API REST con Javascript: Ejemplos con APIs reales
Contenido del curso
Oscar Fuentes Esteves
Juan Castro
Christian Velázquez
Julian Franco
Juan Castro
Raycris Maldonado
Jose Castillo
Paula Inés Cudicio
Ricardo Alfonso Chavez Vilcapoma
CRISTIAN DARIO AGUDELO PORRAS
Frandel Corporan Rodríguez
Henry Alexander Velásquez Rosas
Angel Hernandez
Elber Liebermen
Orangel Gonzalez
Axel Enrique Galeed Gutierrez
Juan Castro
Génesis Jarlenis Patiño Ynfante
Cesidio Antonio Di Benedetto Carri
Juan Castro
Patricia Julliete Rangel Mujica
Jose Angel Morales Gonzalez
Jose Angel Morales Gonzalez
Andrés Aguirre
Kevin Daniel Hincapie Lumbaque
Arlen Elian Ruiz Pedraza
Victor Hugo Cruz Carballo
Maurizio Alejandro Iglesias Fernandez
Juan Castro
Luis Torres
Juan Castro
Rodrigo Andre Gutierrez
Jhojan Alberto Tobón Monsalve
Sergio Javier Lopez Olivera
N40 M10
Henry Alexander Velásquez Rosas
Xavier Flores
Si están usando la extensión live server, deben de tener cuidado de la url que está en el navegador, al cambiar el location.hash manualmente (desde consola) se cambia la ruta en la ventana del navagador también, y si pusieron en consola algo como:
location.hash="hola"
y realizan algún cambio en el código, al guardar, la extension live server "refrescará" la ventana del navegador, pero conservando el hash "#hola" en la dirección de la página, lo que puede provocar que creas que tu código está mal, cual en realidad sí está funcionando.
Ufff, no se me había ocurrido. Muy buen ojo ahí.
Gracias.
El
false
según la documentación se conoce como
useCapture
Es Opcional
Si es true, useCapture indica que el usuario desea iniciar la captura. Después de iniciar la captura, todos los eventos del tipo especificado serán lanzados al listener registrado antes de comenzar a ser controlados por algún EventTarget que esté por debajo en el arbol DOM del documento.
https://developer.mozilla.org/es/docs/Web/API/EventTarget/addEventListener
Adicional en la parte que menciona el:
load
Este cuenta con una caracteristica vs el DOMContentLoaded
El evento load se desencadena cuando se ha cargado toda la página, incluidos todos los recursos dependientes, como hojas de estilo e imágenes. Esto contrasta con DOMContentLoaded, que se activa tan pronto como se ha cargado el DOM de la página, sin esperar a que los recursos terminen de cargarse.
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Se que escribi mucho perdón, Pero si declaran la funcion como arrow function de la siguiente manera
window.addEventListener('DOMContentLoaded', navigatior, false) window.addEventListener('hashchange', navigatior, false) const navigatior = () => { //your code }
Les va a generar un error interesante 😏
:clap:
Grande amigo, me estaba dando el error por tener el arrow function!
En videos anteriores hicieron un aporte para optimizar el código y no tener que andar escribiendo a cada rato la linea de .querySelector cuando necesitamos hacer target a un elemento del html.
En esto me base para ahorrar lineas de código e implementar la misma idea pero con el .createElement que usamos muy seguido.
const Cr = (elemento) => document.createElement(elemento);
Utilice Cr por ser las siglas de la palabra "Create", pero pueden nombrarla del modo que quieran, de este modo cada vez que necesitemos crear un elemento por medio de Js Solo tendríamos que escribirlo así:
const parrafo = Cr('p');
Buenísimo!! no había visto el otro comentario, asique me viene muy bien. Gracias!!!
Creo que una vez trataron de hacer lo mismo con console.log y el prof Juan dijo que era un error gravísimo y una mala práctica.
Esta es mi solucion para evitar anidar tantos if y que ademas me parece mas pulida y facil de leer y entender
Epic👌
Cool
No es película pero si es documental, por si les interesa: El viaje interminable
++Location++ Propiedad del navegador de JS que permite leer la URL en la que nos encontramos actualmente, entre sus propiedades está el hash, puerto, ruta, etc
++onhaschange:++ Permite que ejecutemos cierto código cada vez que cambie nuestro hash
Codigo de la clase 😁👍🏻
window.addEventListener("DOMContentLoaded", navigator, false) window.addEventListener("hashchange", navigator, false) function navigator() { if (location.hash.startsWith("#trends")) { trendsPage() } else if (location.hash.startsWith("#search=")) { searchPage() } else if (location.hash.startsWith("#movie=")) { movieDetailsPage() } else if (location.hash.startsWith("#category=")) { categoriesPage() } else { homePage() } } function homePage() { console.log("Home!!") getTrendingMoviesPreview() getCategoriesPreview() } function categoriesPage() { console.log("Categories!!") } function movieDetailsPage() { console.log("Movie!!") } function searchPage() { console.log("Search!!") } function trendsPage() { console.log("TRENDS!!") }
Les comparto una forma que encontré para facilitar la lectura del código. :D
const navegador = () => { console.log({ location }); const HASHES = { '#trends' : () => trendsPage(), '#search=' : () => searchPage(), '#movie=' : () => moviePage(), '#category=' : () => categoryPage(), }; for (const KEY of Object.keys(HASHES)) { if (location.hash.startsWith(KEY)) { HASHES[KEY](); return; } } homePage(); }; const homePage = () => { console.log('HOME'); }; const categoryPage = () => { console.log('CATEGORY 37'); }; const moviePage = () => { console.log('MOVIE'); }; const searchPage = () => { console.log('SEARCH'); }; const trendsPage = () => { console.log('TRENDS'); }; window.addEventListener('load', navegador, false); window.addEventListener('hashchange', navegador, false);
Fuaaaa me encanta la función de navegador!!!
Me gustó mucho tu código, Galeed. Lo tomé como ejemplo. Yo en lugar de usar for of, usé for in e iteré directamente sobre la key. Gracias!!
El tercer parametro se utiliza para determinar si se va a manejar con bubbling cuando es false o capturing cuando es true
¡Super! Pero ¿qué significa "bubbling"? :eyes:
el bubbling es la manera de como se propagan los eventos. Desde el elemento hijo, subiendo hasta todos sus padres...
Para quien se pregunte como puede hacer más leíble el nido de if else:
window.addEventListener('load', handleRouter, false) window.addEventListener('hashchange', handleRouter, false) function navigator(){ const router = { '#trends': () => {console.log('trends')}, '#search=': () => {console.log('search')}, '#movie=': () => {console.log('movies')}, '#category=': () => {console.log('categories')}, '#home': () => {console.log('home')}, } if(true){ return router[window.location.hash] || router['#home'] } } function handleRouter(){ const router = navigator() router() }
De hecho me lo enseño juan dc en otro curso.
El if(true) no es necesario
Me parece interesante utilizar llave y valor para hacer el routing de los endpoints, sin embargo, el problema de esto es que si el hash no es igual a la llave, no lo va a identificar por lo cual no ejecutaria el codigo que quisieramos, y como estamos usando queryParameters esto pasaria muy seguido.
Por ejemplo, si el hash fuera '#search=123', el codigo no estaria tomandolo como '#search' ya que no son iguales, por lo cual devolveria 'router['#home']'
Lo del los objetos con llave y valor serian más utiles cuando sabemos que los endpoints no van a cambiar ó si vamos a hacer más validaciones para que los valores que recibamos como parametros coincidan con las llaves del router.
Tal vez no les importe mucho pero estaba leyendo la documentacion del evento 'DOMContentLoaded' y dice que este no espera a que todo cargue: " It doesn't wait for other things like images, subframes, and async scripts to finish loading." No espera la carga de imagenes, subframes(no se que son) y scrips asincronos.
En cambio el evento "load": " should be used only to detect a fully-loaded page" se usa para detectar paginas completamente cargadas.
Ademas dice que el objetivo de este evento es el Document pero que se usa sobre el windo para manejar el evento en fase de captura o burbuja: "The original target for this event is the Document that has loaded. You can listen for this event on the Window interface to handle it in the capture or bubbling phases."
Lo de las fases lo explico bastante bien un compañero en estos comentarios. link info
Dejo la documentación sobre el addEventListener en este link
Como mensiono Juan tambien en el evento de carga tambien funciona con 'load' pero hay un pequeño problema, cuando cambias el hash no te va a redirecionar sino que se quedara en la misma pantalla. Asi que tenemos que utilizar en el argumento 'DOMContentLoaded'
Me ando muriendo de risa por el "PUMM" del minuto 16:27 JAJAJJAJAJA
Por cierto, asi va mi proyecto
Love it! Al final del curso comparte tu repo :)
Vengo del futuro, ya hice mi deploy del proyecto pero mi sorpresa fue que el location.hash = windows.history.back(); NO funciona en cualquier dispositivo de Apple sin importar el navegador...
Hice el intento con location.href, pero al hacer el history.back() me manda a undefined.
He buscado soluciones en Google pero no logro dar con ella.
¿Alguien tiene alguna idea?
Hmmmm... Qué extraño, parece que history.back tiene muy buen soporte en prácticamente todos los navegadores, mira: https://developer.mozilla.org/en-US/docs/Web/API/History/back#browser_compatibility
windows.history.back() o window.history.back()?
ojo
En resumen hay dos formas de propagación en el DOM bubbling=false y capturing=true. Si se quiere que el evento de un elemento dentro de otro elemento con evento se ejecute primero, entonces se utiliza false o no se coloca nada porque por defecto es false, pero si se quiere que el evento del elemento externo se ejecute primero que el elemento con el evento interno se utiliza true.
El evento 'hashchange' tiene un valor booleano al final para determinar si la navegación es un fragmento o no. Una navegación por fragmentos ocurre cuando la parte de la URL correspondiente al '#' ha cambiado y el valor booleano será cambiado a 'true' si la navegación es una navegación por fragmentos, y 'false' si no lo es. . Básicamente te permite lograr eventos por cambios en el anchor (#) haciendo el sitio dinámico. Esto podría servir por ejemplo para hacer toggle a las clases de tus etiquetas HTML con JS para así mostrar u ocultar distintas vistas.
Deberían de hacer un curso en donde se separe la teoría de localStorage, location y otros elementos, así quedarían mucho más claros, de paso que ese curso también tenga a las API Web más útiles.
En este curso, al tener que detenerse al explicar de manera superficial ciertos conceptos, por un lado, provoca que sea más lento y, por otro lado, no se profundiza lo suficiente en ciertos conceptos, pues solo se limitan a que el ejercicio funcione, pero no a que un estudiante pueda aplicar lo que quiera con esos conceptos.
Generalmente, eso le pasa al grupo que desarrollo este curso en otros mas.
Auto Save de VSC 🔥
Si te olvidas con frecuencia de guardar los cambios de tus archivos puedes usar el autoguardado de VSC que lo hará automáticamente por ti.
Solo ve a File y luego dale check en Auto Save
de lo aprendido en otro curso lo correcto sería escribirlo así:
const navigator = () => { console.log({ location }); if (location.hash.startsWith('#trends')) { trendPage(); } else if (location.hash.startsWith('#search=')) { searchPage(); } else if (location.hash.startsWith('#movie=')) { movieDetailsPage(); } else if (location.hash.startsWith('#category=')) { categoriesPage(); } else { homePage(); } location.hash } window.addEventListener('DOMContentLoaded', navigator, false); window.addEventListener('haschange', navigator, false);
Cuando se trabaja con eventListener lo recomendable es colocar nuestra funcion con un arrow function (en este caso "navigator" debido a que si en un futuro necesitemos eleminar ese evento lo podriamos ubicar con su nombre "navigator" y optimizar el performance de nuestro DOM.