No tienes acceso a esta clase

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

Curso Práctico de JavaScript

Curso Práctico de JavaScript

Juan David Castro Gallego

Juan David Castro Gallego

Fusión del menú en mobile

20/28
Recursos

Aportes 81

Preguntas 12

Ordenar por:

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

const burguerMenu queda bien jaja

Pregunta y respuesta del chat antes de publicarla. pero no me voy a quedar con las ganas 😃

Escribi esto:

Que lastima que el addEventListener no permite enviar parametros/argumentos en la funcion invocada.
Se podria usar una sola funcion para todos los clickleables del menu.
quedaria asi

menuEmail.addEventListener("click", toggleElement(desktopMenu));
hamburguesa.addEventListener("click", toggleElement(menuMobile));

function toggleElement(elemento){
    elemento.classList.toggle("inactive");
}

Alguien sabe porque no se puede?
Probe y no funciono 😦

Antes publicar la pregunta el automaticamente se me recomendo esto:
https://platzi.com/comentario/2932415/

Y este es el resultado que si funciona 😃

menuEmail.addEventListener("click", function(){toggleDesktopMenu(desktopMenu)});
hamburguesa.addEventListener("click", function(){toggleDesktopMenu(menuMobile)});

function toggleDesktopMenu(elemento){
    
    elemento.classList.toggle("inactive");
}

Resulta que si llamamos una funcion directamente no funciona, pero si lo hacemos por medio de una funcion anonima ssi, que loco no?

Buenas amigos, en esta clase, antes de verla quise intentar realizarlo por mi cuenta, y le agregué una transición, para que cuando el menú saliera, lo hiciera con un desplazamiento lateral, miren cómo quedó, y diganme qué les parece y si hay una forma más profesional de hacerla también la acepto, le agregué a mis estilos del mobile menu lo siguiente.![](

Y en mi JavaScript ![](
Y el resultado fue este

Me encanta cuando incluyen los errores del profesor! Porque no sólo es realista, en el día a día de trabajo sucede. Sino que además a los que estamos aprendiendo nos saca toda esa inseguridad que tenemos y aprendemos que ser profesionales no significa hacer las cosas a la perfección de primeras. Justamente lo que te hace profesional es reconocer los errores y corregirlos.

Para mejorar los comentarios en nuestros proyectos les recomiendo esta extensión de VSC Better Comments 💚🚀
https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments

A mi los menus de mobile me gusta animarlos entrando y saliendo de la pantalla de forma fluida, para esto escondo el menu a la izquierda del documento usando position y luego con una clase lo muevo devuelta a la posicion 0 de esta forma:

.mobile-menu {
  position: absolute;
  top: 61px;
  left: -400px;

  transition: 400ms;
}

.slide-right {
  left: 0;
}

Al hacer esto y aplicando el transition a la clase de .mobile-menu, hace que el cambio se vea fluido lo cual creo no seria posible con la clase de .inactive.

Asi lo hago yo, me gustaria saber si conocen una forma distinta o mas efectiva de lograr este efecto

Si les quedó duda como funciona el método toggle, aquí hay mas métodos de classList

Así lo hice para ocultar el menú desde JS

window.onresize = function () {
  document.documentElement.scrollWidth <= 640 &&
    desktopMenu.classList.add('inactive');
};
onresize();

Buenas muchachos analizando detenidamenmente se que nos vamos enfretar situaciones donde realmente lo que importe son la capacidad de entender codigo de otros y ser capaz de desenvolvernos, pero yo hice este mismo proyecto el css y html por mi cuenta con mobile-first y cuando agrandaba en desktop el menu “hamburguesa” desaparecia dado a los Media query entonces no me seguia apareciendo el menu-phone en desktop facilita que primero lo hagas desde pequeno, si leiste mi comentario lo agradezco fue un poco extenso<3

Si alguno gusta aventurarse a manejar los Media Queries con JavaScript, aquí un post de CSS Tricks para hacerlo ✨

https://css-tricks.com/working-with-javascript-media-queries/

Yo le puse así😂😂:

const burgerBtn;

Por si consideran ahorrar codigo :

 .navbar-left ul, .navbar-email, .desktop-menu {
            display: none;
        } 

Esta fue la manera como lo hice😀

Código Css

.desktop-menu {
        display: none;

      }


      .mobile-menu {
        width: 92%;
        border-style: solid;
        border-width: 1px;
        color: var(--very-light-pink);
        padding: 24px;
        top: 60px;
        left: 0px;
        position: absolute;
        display: none;
      }

      .mobile-menu a {
        display: flex;
        justify-content: center;
        font-size: 20px;
      }

Código Js

let btnMenu = document.querySelector('.menu');
let mobileMenu = document.querySelector('.mobile-menu');
let menuMbl = "menuAparecido";

btnMenu.addEventListener('click', menuHamburguesa);

function menuHamburguesa() {

    if(menuMbl == "menuAparecido") {
        mobileMenu.style.display = 'block';
        menuMbl = "menuDesaparecido";
    }
    else {
        mobileMenu.style.display = 'none';
        menuMbl = "menuAparecido";
    }

}

Quise implementar algo que siempre veo en muchas páginas web, y es que el menú desplegable se oculta cuando se toca en cualquier otro lugar de la página, excepto en el área del menú. Así se puede ocultar el menú sin tener que hacer click al área de clic inicial.
Esto lo implemente así:

document.onclick = function (e) {
  let targetClass = e.target.getAttribute('class');

  if (targetClass !== 'mobile-menu' && targetClass !== 'menu')
    mobileMenu.classList.add('inactive');

  if (targetClass !== 'desktop-menu' && targetClass !== 'navbar-email')
    desktopMenu.classList.add('inactive');
};

CSS:

.desktop-menu {
    width: 100px;
    height: auto;
    border: 1px solid var(--very-light-pink);
    border-radius: 6px;
    padding: 20px 20px 0 20px;
    position: absolute;
    right: 60px;
    top: 60px;
    background-color: var(--white);
    visibility: visible;
    opacity: 1;
    transition:visibility .3s, opacity .3s;
}
.desktop-menu::before{
    content: '';
    position: absolute;
    top: -15px;
    right: 15px;
    border-right: 15px solid transparent;
    border-left: 15px solid transparent;
    border-bottom: 15px solid var(--very-light-pink);
    width: 0.1px;
    height: 0.1px;
    z-index: 1;
}

.inactive{
    /* display: none;
    transition: none 1s; */
    visibility: hidden;
    opacity: 0;
    transition:visibility .3s, opacity .3s;
}

JS

const navbar_email = document.querySelector('.navbar-email');
const desktop_menu = document.querySelector('.desktop-menu');

navbar_email.addEventListener('click', () => desktop_menu.classList.toggle('inactive'));

Creo que en el diseño original el menú mobile tenía un botón “X”, ubicado en la esquina superior derecha del elemento para cerrar el menú.

Like si colocaste la clase correcta “menu” 😃

Yo lo tengo asi hasta el momento.

const mail = document.querySelector(".navbar-email");
const mailMenu = document.querySelector(".desktop-menu");
const mobileMenuIcon = document.querySelector(".menu");
const mobileMenu = document.querySelector(".mobile-menu");

mail.addEventListener("click", () => toggleMenu(mailMenu));
mobileMenuIcon.addEventListener("click", () => toggleMenu(mobileMenu));

function toggleMenu(element) {
  element.classList.toggle("inactive");
}

Que buenas explicaciones y uso en practica de html css y javaScript me encanta este curso

Don’t Repeat Yourself
(Hice que la función fuera genérica para que pudiera reutilizarse y no repetir código, para ello en el add event listener debemos usas una arrow function, concepto que no hemos visto, sin embargo es sencillo de entender)

const navEmail = document.querySelector(".navbar-email");
const burgerBtn = document.querySelector(".menu");
const desktopMenu = document.querySelector(".desktop-menu");
const mobileMenu = document.querySelector(".mobile-menu");

const toggleInactiveClass = (element) => {
  element.classList.toggle("inactive");
};

navEmail.addEventListener("click", () => toggleInactiveClass(desktopMenu));
burgerBtn.addEventListener("click", () => toggleInactiveClass(mobileMenu));

Aquí les comparto otra solución para no tener que crear funciones por cada menú, sino una genérica que permita mostrar o esconder cualquiera:

const menuEmail = document.querySelector('.navbar-email')
const desktopMenu = document.querySelector('.desktop-menu')
const menuHamIcon = document.querySelector('.menu')
const mobileMenu = document.querySelector('.mobile-menu')

menuEmail.addEventListener('click', () => toggleMenu(desktopMenu))
menuHamIcon.addEventListener('click', () => toggleMenu(mobileMenu))

function toggleMenu(menu) {
    menu.classList.toggle('inactive')
}

P.D: La notación de funciones flecha se usa para evitar que la función “toggleMenu()” se ejecute inmediatamente por medio del addEventListener, haciendo que esta sólo ocurra al hacer click en el elemento HTML.

De verdad que he aprendido muchísimo con este curso, ¡Más cursos como este por favor! 😌

🚀 Para que la interacción con el menú hamburguesa quede mucho mejor pueden actualizar el cursor a “pointer” en la clase menu en el archivo css: 💚

.menu {
  display: none;
  cursor: pointer;
}

¿Qué tal si reutilizamos algo de código?👀

  1. Agregue la clase “inactive” en nuestra sección del menú que aparecerá y desaparecerá.
  2. Algunos estilos pendientes (solo para la parte interactiva de nuestro menú):
.mobile-menu {
    padding: 24px;

    position: absolute;
    top: 61px;
    left: 0;

    background-color:var(--white);
    border: 1px solid #EEEFEF;
    border-radius: 5px;
    transition: .3s;
  }
  1. De acuerdo, juguemos con JS tal cuál lo hicimos la clase pasada:
const barMenu = document.querySelector(".menu")
const barMenuResult = document.querySelector(".mobile-menu")

barMenu.addEventListener("click", toggleBarMenu);

function toggleBarMenu() {
    barMenuResult.classList.toggle("inactive");
}

¡Oh sorpresa!🙀
Nuestra función toggleBarMenu() recarga toda la página cada vez que se ejecuta, evitando que podamos ver algún resultado favorable.

  1. Indiquemos que la acción no avance hacia el servidor (invitación a indagar más sobre le tema) añadiendo un return false; al final de nuestra función problemática.
function toggleBarMenu() {
    barMenuResult.classList.toggle("inactive");
    return false;
}

Sugerencias y preguntyas a la orden. 😄💚

Yo le puse en vez de menu burguerMenu y no se porque a mi me mostraba el icono hambuguesa siempre, pero lo solucione agregandolo al media query que hicimos para las pantallas grandes.
asi:

@media (min-width: 641px) {
    .mobile-menu{
        display: none;
    }
    .burguerMenu{
        display: none;
    }
}

Así le puse a mi trabajo:

const leftIconMenu = document.querySelector('.menu');
@media (max-width: 640px) {
      .menu {
        display: block;
      }
      .navbar-left ul {
        display: none;
      }
      .navbar-email {
        display: none;
      }
      .desktop-menu {
        display: none;
      }
    }

    @media (min-width: 641px) {
        .mobile-menu {
          display: none;
        }
      }

const mobileBurguerMenu

Hola chicos, he agregado en JavaScript un “listener” para controlar el tamaño de la página. De esta manera, cuando la ventana se hace más pequeña o más grande, se añade la clase “inactive” según convenga. Tal vez no sea necesario para este proyecto en particular, pero podría ser útil conocer cómo se hace para necesidades futuras. Este es el código:

window.addEventListener('resize', checkWindowSize);
function checkWindowSize(){
    if (window.innerWidth > 640) {
        mobileMenu.classList.add('inactive');
    }
    if(window.innerWidth < 640) {
        desktopMenu.classList.add('inactive');
    }
}

// Comprobar el tamaño de la ventana al cargar la página
checkWindowSize();

Espero que les sea útil. Saludos ❤️

Ese código que está haciendo el profesor es un arroz con mango de buenas y malas prácticas, hubiera sido mejor si Teff desde el principio hubiera usado las medidas min-width que son estándares a diferencia de max-width, así no tendría problemas en fusionar esta parte de la clase y el resto que sigue.

si quieren ver su proyecto mobile con un dispositibo mobil y usando live server pueden hacerlo de la siguiente manera
primera nos vamos a cmd a la consola predeterminada de tu pc yo tengo windos y wsl bueno 1 colocan el comando ipconfig, les va a desglosar una información donde van a buscar donde diga direccion IPv4 y colocaran el numero que aparece adelante en su buscador acompañado del numero de puerto de su archivo , este es el numero que ami me aparecio 192.168.1.3:aqui va el numero de puerto el numero de puerto lo puedes ver cuando abres tu archivo con liveserver en el navegador adelante de los 2 puntos ese es tu numero de puerto el mio es 5500
y al final tiene que verse algo asi 192.168.1.3:5500 y mostrar el archivo en el navegador de tu celular obiamente cuando apagues tu pc este archivo se dejar de ver como si apagaras el servidor en backend

Para el que le interesó como implementar el ocultar los menús con media queries en JavaScript. Aquí está como lo hice yo:

const mediaQuery = window.matchMedia('(min-width: 640px)');

menuDisplay(mediaQuery); //Initial check
mediaQuery.addListener(menuDisplay); // Attach listener function on state changes

//Media querie to display menu
function menuDisplay(mediaQuery) {
  if (mediaQuery.matches) mobileMenu.classList.add('inactive');
  else desktopMenu.classList.add('inactive');
}

Quise implementarlo de esta manera para que, al cambiar la ventana de móvil a escritorio o de escritorio a móvil, el menú se elimine por completo. De esta forma, cuando se vuelva al tamaño de la ventana anterior, el menú no estará presente.

Así va mi solución antes de ver la clase del prof…por cierto, yo ando usando mi código que hice en el curso de Frontend Developer Práctico, se me hace más fácil pero lo ideal es lo del prof que al entrar a un trabajo se tiene que hacer un fork de un proyecto ya hecho.

Para el media@ preferí mejor esto:

@media (min-width: 639px)

ya que si ponemos este:

@media (min-width: 641px)

Es posible que se topen ambos estilo en el pixel 640.

Yo hice los ejercicios utilizando el atributo html hidden, ahorrandome crear una clase que aporta casi nada al codigo, no se si sea lo correcto o mala practica, pero aqui les dejo el codigo:
El atributo html

<div hidden class="mobile-menu"> 

el JS

const mobileicon = document.querySelector('.menu');
const mobilemenu = document.querySelector(".mobile-menu");

mobileicon.addEventListener("click",()=>{
    mobilemenu.toggleAttribute("hidden")
});

Humilde aporte 😄 .
Para no estar creando varias funciones con la misma funcionalidad de hacer toogle/inactive creé una Función de Expresión para usarla las veces que necesitemos.
Solo se debe asignar los argumentos del elemento al que se le hace clic, el que se muestra/oculta y el evento.

var toogleFunction = function(btnToggle,contentToggle,eventToogle) {
    btnToggle.addEventListener(eventToogle, function() {
        contentToggle.classList.toggle('inactive');
    });
}
toogleFunction(btnAccount,desktopMenu,'click');
toogleFunction(btnMobileMenu,mobileMenu,'click');

¿En qué se diferencian width, max-width y min-width?:

Yo le puse menuNav 😉

Como nombrar adecuadamente nuestros elementos!

Antes de ver la clase les digo las dos formas de resolverlo que encontré como desafío por mi cuenta:
1- Resolverlo con dos funciones, una para el menú desktop y otra para el menú mobile (la opción facil):

const navEmail = document.querySelector('.navbar-email');
const desktopMenu = document.querySelector('.desktop-menu');
const navMenu = document.querySelector('.menu');
const mobileMenu = document.querySelector('.mobile-menu');
navEmail.addEventListener('click', toggleDesktopMenu);
navMenu.addEventListener('click', toggleMobileMenu);
function toggleDesktopMenu(event) {
    console.log(event);
    desktopMenu.classList.toggle('inactive');
}

function toggleMobileMenu(event) {
    console.log(event);
    mobileMenu.classList.toggle('inactive');
}

2- Resolverlo con una única función que escuchando las caracteristicas del evento pueda determinar si el toggle se lo hace al mobileMenu o al desktopMenu (opción mas óptima pero complicada):

const navEmail = document.querySelector('.navbar-email');
const desktopMenu = document.querySelector('.desktop-menu');
const navMenu = document.querySelector('.menu');
const mobileMenu = document.querySelector('.mobile-menu');
navEmail.addEventListener('click', toggleMenu);
navMenu.addEventListener('click', toggleMenu);
function toggleMenu(event) {
    if (event.srcElement.className === 'menu') {
        mobileMenu.classList.toggle('inactive');
    } else if (event.srcElement.className === 'navbar-email') {
        desktopMenu.classList.toggle('inactive');
    }
}

JS

const menuEmail = document.querySelector('.navbar-right');
const desktopMenu = document.querySelector('.desktop-menu');
const menuBurger = document.querySelector('.menuImgBurger');
const mobileMenu = document.querySelector('.mobile-menu');

menuEmail.addEventListener('click', () => {
    desktopMenu.classList.toggle('inactive');
});

menuBurger.addEventListener('click', () => {
    mobileMenu.classList.toggle('inactive');
});

Que genial Juan

const menuBurguer o menurguer 🤣

"Rotísimo, rotísimo"
Ahí me quebré yo, pero de la risa jajaja
Excelentes clases Profe Juan

Ahora cada vez que hago que algo funcione me imagino la emocion que hace juandc y el grito jujujuy! jajajaja

Hola, ¿cómo están?✌😊, me imagino que algo preocupados de que addEventListener no permite argumentos😢, después de recordar algunas cosas de ECMAScript 6 🤔podemos usar array funciones, es una forma más fácil de crear funciones rápida, no son iguales, pero puedes ser bastante útiles, para este caso en especial sería lo siguiente:

const menuEmail = document.querySelector('.navbar-email');
const desktopMenu = document.querySelector('.desktop-menu');
const menuHamIcon = document.querySelector('.menu');
const mobileMenu = document.querySelector('.mobile-menu');

menuEmail.addEventListener('click', toggle => {toggleMenu(desktopMenu)});
menuHamIcon.addEventListener('click', toggle => {toggleMenu(mobileMenu)});

function toggleDesktopMenu(elemento) {
    elemento.classList.toggle('inactive');
}

Así podemos cumplir con el objetivo de las funciones que es reutilizarlas 😎👌

Antes de empezar el video hice esto:

<script>
/*MOSTRAR DROPDOWN EMAIL NAV*/

const navbarEmailClick = document.querySelector(".navbar-email").addEventListener("click", toggleDropdownMenu);
const navbarEmailOver = document.querySelector(".navbar-email").addEventListener("mouseover", toggleDropdownMenu);
const dropdownMenu = document.querySelector(".desktop-menu");


function toggleDropdownMenu() {
    return dropdownMenu.classList.toggle("inactive");
}


/*MOSTRAR BURGER MENU EN MOBILE*/
const iconMenuClick = document.querySelector(".icon-menu").addEventListener("click", toggleMobileMenu);
const iconMenuOver = document.querySelector(".icon-menu").addEventListener("mouseover", toggleMobileMenu);
const mobileMenu = document.querySelector(".mobile-menu");
const closeMobilemenuClick = document.querySelector(".close-mobilemenu").addEventListener("click", closeMobileMenu);
const closeMobilemenuOut = document.querySelector(".close-mobilemenu").addEventListener("mouseout", closeMobileMenu);


function toggleMobileMenu() {
    return mobileMenu.classList.toggle("inactive");
}

function closeMobileMenu() {
    return mobileMenu.classList.add("inactive");
}
</script>

El mejor nombre para mi es mobileIconMenu

🚀🚀 Así, realice el código para utilizar solo una función (toggleMenus), haciendo uso del mediaQuery por medio del JavaScript 🚀🚀

Para tener paz mental, yo cambié los media query a

//
max-width: 800px;
//
min-width: 801px;

Yo le puse mobileMenuCtl

El mas descriptivo me parece:

const burguerMenuIcon = document.querySelector(".menu");

😉

Yo en lugar de colocar el mq para que al momento de agrandar la pagina o encogerla se guardara el menú le coloque un evento para que cuando el mouse se saliera del contenedor de “mobileMenu” o “desktopMenu” guardara el menú asi me quedo…!! Espero les sirva para el que quiera intentar algo diferentes.

menuEmail.addEventListener('click', toggleDesktopMenu);
menuHamIcon.addEventListener('click', toggleMobileMenu);
mobileMenu.addEventListener("mouseout", outMobil);
desktopMenu.addEventListener("mouseout", outDesktop);

function toggleDesktopMenu(){
    desktopMenu.classList.toggle('inactive');
}

function toggleMobileMenu() {
    mobileMenu.classList.toggle('inactive');
}

function outMobil() {
    mobileMenu.classList.toggle('inactive');
}
function outDesktop() {
    desktopMenu.classList.toggle('inactive');
}
yo de plano le puse const burgerButton
:) me gusta mucho las clases de juan dc es alegre, se explica correctamente y se ve su pasion y corazon en este curso en especifico, tambien por su sinceridad al dar la clase

🦄✨

Usando una etiqueta como alternativa al .inactive, se puede lograr una animación más suave c:
En el .mobile-menu

left: 0;
opacity: 1;
transition: all .3s;

La clase alternativa al .inactive:

.inactive-mobile_menu{
    left: -100%;
    opacity: 0;
}

Y el JavaScript:

const mobileMenuIcon = document.querySelector('.menu-icon');
const mobileMenu = document.querySelector('.mobile-menu');
function toogleMobileMenu(){
    mobileMenu.classList.toggle('inactive-mobile_menu');
}

Juan dc, sencillamente el mejor profe de la historia.

como la sufro cuando utilizo css jaja

Me gusta el curso!

me gusta la clase , bien hecho

Me quedo la duda porque simulamos como si usaramos mobile y pasaramos a desktop o al reves. En realidad el usuario va a usar una o la otra, no ambas me parece.

Saludos, yo usé un solo media querie para este problema, solo intercambié y modifiqué algunas clases

nombre del menu en mobile:

const iconMenuMob = document.querySelector(".menu");

commit:

Lo llamé BurgerIcon

nav mobile

Yo hice algo parecido a esto para mi pag web usando matchMedia en JS :p

Me sucedió lo de que mi código no funcionaba porque no había agregado el Script no puede ser ajsdjasjsaj

Contexto: Menurger

Hola, esta chido ese ajuste con el menu, pero tengo una duda, si en la seccion de abajo donde queda el menu hubiese mas contenido ese desacomoda todo como lo solucionaría profe?

como dato, si a alguien le pasa el mismo problema que el mio, que una vez que desplegan el menu, no lo pueden volver a retraer haciendo click, es por que el bloque tapa la etiqueta .menu-mobil, lo que hice fue agregar un margin, en vez del padding

.mobile-menu {
    position: absolute;
    margin-top:35px;
    padding: 5px;
}

yo le puse menuBurger, tambien le pondria burgerMenu XD y listo

Amo a este profesor, excelente Metodología y se ve la pasión por lo que hace 100pto

Cambiar de opinión es de sabios.
-Capitan Juan Marvel ugr ugr… digo DC -

traductor de google
hamburger-menu

me encanta como me adelanté y sin ver la clase lo hice igual, bueno, almenos hasta la parte de las funciones, aun falta ver si lo de los media lo hiciste igual que yo profe, yo puse un media pero al contrario, en lugar de max le puse min-width. y luego la función.
SandwichMenu sounds better!

Buenas, para el que quiera saber como desaparecer los menus dependiendo del ancho de pantalla (como el @media) les dejo la solucion.

const desktopMenu = document.querySelector('.desktop-menu');
const mobileMenu = document.querySelector('.mobile-menu');
const menuHamIcon = document.querySelector('.menu');

// Toma el ancho de la pantalla
window.addEventListener('resize', hideDesktopMenu)
menuHamIcon.addEventListener('click', toggleMobileMenu)

// Oculta el menu si el ancho de la pantalla es menor a 768px (ESTO PUEDO HACERLO CON CSS TAMBIEN)
function hideDesktopMenu() {
    if (window.innerWidth < 768) {
        desktopMenu.classList.add('inactive')
    }
    if (window.innerWidth > 640) {
        mobileMenu.classList.add('inactive')
    }
}


Si colocamos la misma class “inactive” que utilizamos en el desktop menu no se requiere de utilizar los media queries. Así los menús siempre estarán inactivos y solo aparecerán cuando ocurra el evento click.

lejos lejos el mejor curso hasta el momento