Creé un conmutador de barra lateral y también di opacidad de fondo, pero cuando hago clic en otra área o cuando cerré la barra lateral, la opacidad de fondo no se cerró. cuando hago clic en el botón, se muestra el contenido del menú desplegable y se muestra la opacidad del fondo, pero cuando hago clic nuevamente en el botón, el contenido del menú desplegable se cierra pero la opacidad del fondo no se cierra. como lo hice Por favor, ayúdame. Le di el código a continuación. Si alguien me puede ayudar me será de gran ayuda. Lo intento muchas veces, pero al final, no puedo hacerlo. 😥
function toggleDropDown(id) { document.querySelectorAll('.dropdown-content').forEach(el => el.id === id ? el.classList.toggle('show') : el.classList.remove("show")); document.body.style.backgroundColor = "rgba(0,0,0,0.4)"; } document.addEventListener('click', (e) => { // cases where we want to close the dropdown if (e.target.closest(".dropdown") === null) { document.querySelectorAll('.dropdown-content').forEach(el => el.classList.remove("show")); } }); *{margin:0;padding:0;} .dropdown-content{ position: fixed; width: 30%; height:100%; background-color: rgb(255,0,0); margin-left: 20%; top:0; display:none; z-index:100; } .dropbtn{width:20%} .show{display:block;} <div class="dropdown"> <button class="dropbtn" onclick="toggleDropDown('openContent')">open</button> <div class="dropdown-content" id="openContent">Hello, Div</div> </div> <h1>Hello World, Heading 1</h1>Primero, sugeriría crear una variable que realice un seguimiento del estado actual del menú desplegable, que es true o false .
Además, no veo el beneficio de usar document.querySelectorAll y tener que recorrer cada elemento, cuando podría obtener el elemento directamente abordando su id (openContent)... a menos que desee reutilizar la función para otros ¿casos?
Como también está escuchando un evento de clic en el documento, tenemos que tener cuidado con el burbujeo de eventos llamando a e.stopPropagation . En el caso del button , por ejemplo, esto significa que solo disparamos el evento para el button pero no para el document . Dado que el button es un elemento secundario del document , de lo contrario detectaría un evento de clic para ambos y se activaría dos veces.
const dropdownContent = document.getElementById("openContent"); let dropDownVisible = false; function toggleDropDown(e) { // we need this to prevent the event bubbling from the dropdown button to the document e.stopPropagation(); // set the dropDownVisible state to the opposite it has been before dropDownVisible = !dropDownVisible; if (dropDownVisible) { dropdownContent.classList.add("show"); document.body.classList.add("bgcolor"); } else { dropdownContent.classList.remove("show"); document.body.classList.remove("bgcolor"); } } // we need this to prevent the event bubbling from the dropdown to the document dropdownContent.addEventListener("click", (e) => { e.stopPropagation(); }); // listen for click events on the document document.addEventListener("click", (e) => { // -> if the dropdown is visible, toggle its state dropDownVisible && toggleDropDown(e); }); * { margin: 0; padding: 0; } .dropdown-content { position: fixed; width: 30%; height: 100%; background-color: rgb(255, 0, 0); margin-left: 20%; top: 0; display: none; z-index: 100; } .dropbtn { width: 20%; } .show { display: block; } .bgcolor { background-color: rgba(0, 0, 0, 0.4); } <body> <div class="dropdown"> <button class="dropbtn" onclick="toggleDropDown(event)"> open </button> <div class="dropdown-content" id="openContent">Hello, Div</div> </div> <h1>Hello World, Heading 1</h1> </body>Tendrá que eliminar también el fondo del "cuerpo".
document.body.style.backgroundColor = "initial"; function toggleDropDown(id) { document.querySelectorAll('.dropdown-content').forEach(el => el.id === id ? el.classList.toggle('show') : el.classList.remove("show")); document.body.style.backgroundColor = "rgba(0,0,0,0.4)"; } document.addEventListener('click', (e) => { // cases where we want to close the dropdown if (e.target.closest(".dropdown") === null) { document.querySelectorAll('.dropdown-content').forEach(el => el.classList.remove("show")); document.body.style.backgroundColor = "initial"; } }); *{margin:0;padding:0;} .dropdown-content{ position: fixed; width: 30%; height:100%; background-color: rgb(255,0,0); margin-left: 20%; top:0; display:none; z-index:100; } .dropbtn{width:20%} .show{display:block;} <div class="dropdown"> <button class="dropbtn" onclick="toggleDropDown('openContent')">open</button> <div class="dropdown-content" id="openContent">Hello, Div</div> </div> <h1>Hello World, Heading 1</h1>Agregar clase al cuerpo document.body.classList.add('bgcolor'); y eliminar después de cerrar el menú desplegable
function toggleDropDown(id) { document.querySelectorAll('.dropdown-content').forEach(el => el.id === id ? el.classList.toggle('show') : el.classList.remove("show")); document.body.classList.add('bgcolor'); } document.addEventListener('click', (e) => { // cases where we want to close the dropdown if (e.target.closest(".dropdown") === null) { document.querySelectorAll('.dropdown-content').forEach(el => el.classList.remove("show")); document.body.classList.remove('bgcolor'); } }); *{margin:0;padding:0;} .dropdown-content{ position: fixed; width: 30%; height:100%; background-color: rgb(255,0,0); margin-left: 20%; top:0; display:none; z-index:100; } .dropbtn{width:20%} .show{display:block;} .bgcolor{ background-color:rgba(0,0,0,0.4); } <div class="dropdown"> <button class="dropbtn" onclick="toggleDropDown('openContent')">open</button> <div class="dropdown-content" id="openContent">Hello, Div</div> </div> <h1>Hello World, Heading 1</h1>