Tengo un menú de página completa que se abre con un clic de botón con dos secciones diferentes. El contenido de #terms no cambia, pero el contenido de #links sí, según el botón en el que haga clic. El código en sí funciona bien, pero jQuery se siente increíblemente voluminoso y me preguntaba si alguien podría sugerir alguna forma de hacerlo un poco más limpio. Además, la estructura HTML tiene que permanecer bastante bien como está porque es un poco quisquilloso con el estilo.
También debo señalar que no soy el más experimentado con jQuery, así que...
Este es el código en cuestión y el HTML relevante (los botones en la parte superior están en otra parte del HTML, pero los incluí aquí para ver cómo están estructurados):
$("#codes-launch, #gfx-launch, #tuts-launch, #menu-close").click(function() { $("#menu").slideToggle("slow"); $("body").toggleClass("scroll-lock"); }); $("#codes-launch").click(function() { $("#codes").show(); $("#gfx, #tuts").hide(); }); $("#gfx-launch").click(function() { $("#gfx").show(); $("#codes, #tuts").hide(); }); $("#tuts-launch").click(function() { $("#tuts").show(); $("#codes, #gfx").hide(); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button id="codes-launch">Codes</button> <button id="gfx-launch">Graphics</button> <button id="tuts-launch">Resources</button> <div id="menu"> <div id="terms">SOME STUFF</div> <div id="links"> <button id="menu-close">Close</button> <div id="codes">Codes</div> <div id="gfx">Graphics</div> <div id="tuts">Resources</div> </div> </div>
Usando un atributo de datos y un selector común, puede reemplazar todos los clics en uno.
$("button[data-toggles]").on("click", function(evt) { evt.preventDefault(); $("#links > div").hide(); const selector = $(this).data('toggles'); $(selector).show(); $("#menu").slideDown("slow"); $("body").addClass("scroll-lock"); }); $("#menu-close").on("click", function() { $("#menu").slideUp("slow"); $("body").removeClass("scroll-lock"); });
#menu { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button id="codes-launch" data-toggles="#codes">Codes</button> <button id="gfx-launch" data-toggles="#gfx">Graphics</button> <button id="tuts-launch" data-toggles="#tuts">Resources</button> <div id="menu"> <div id="terms">SOME STUFF</div> <div id="links"> <button id="menu-close">Close</button> <div id="codes">Codes</div> <div id="gfx">Graphics</div> <div id="tuts">Resources</div> </div> </div>
Veo que no tiene estilo, probablemente algo allí que pueda abordarse como una pregunta separada, probablemente solo un CSS extraño con una solución fácil.
Aquí usé clases e hice algunos cambios menores en la estructura para facilitar alguna "agrupación": configuré y borre un valor de datos para hacer que el código sea un poco menos y no impacte tanto en el DOM de la página como no alterna las clases (a menudo interfiere con el estilo a bit cuando se alterna)
Totalmente fuera del alcance, pero agregué Mostrar / Ocultar solo por diversión en el que también se puede hacer clic y establecer un estado inicial para que "Mostrar" se oculte en eso. También noté que no hay un filtro/grupo "inicial", pero lo dejé e hice un comentario en el código para ilustrar que se configuró en la carga de la página.
$("#lanchers, #menu-close").on('click', function() { $("#menu").slideToggle("slow"); $("body").toggleClass("scroll-lock"); var h = $(".up-down").filter(":hidden"); h.show(); $(".up-down").not(h).hide(); }); // just to set up the initial state $("#lanchers").find(".up-down").first().hide(); // we could trigger on one of these on startup to set some initial target as the "visible" one $("#lanchers").on('click', '.launcher-thing', function() { const $targ = $(this.dataset.target); $(".target-thing").not($targ).each(function(event) { this.dataset.show = "nope"; }); $targ.get(0).dataset.show = "yep"; });
.scroll-lock { border: 1px solid lime; } #links { border: solid blue 1px; background-color: #ffeeee; } [data-show="yep"] { display: block; } [data-show="nope"] { display: none; } .up-down { background-color: #eeffee; padding: 0.5em; display: inline-block; border: solid 1px #ccffcc; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="lanchers"> <button class="launcher-thing" data-target="#codes">Codes</button> <button class="launcher-thing" data-target="#gfx">Graphics</button> <button class="launcher-thing" data-target="#tuts">Resources</button> <span class="toggle-thing"> <span class="up-down">Show</span> <span class="up-down">Hide</span></span> </div> <div id="menu"> <div id="terms">SOME STUFF</div> <div id="links"> <button id="menu-close">Close</button> <div id="codes" class="target-thing">Codes</div> <div id="gfx" class="target-thing">Graphics</div> <div id="tuts" class="target-thing">Resources</div> </div> </div>