Home > database >  Cleaner Way to Write This jQuery?
Cleaner Way to Write This jQuery?

Time:07-07

I have a full-page menu that opens on a button click with two different sections. The content in #terms doesn't change, but the content in #links does, based on which button you click. The code itself works fine, but the jQuery feels incredibly bulky and I was wondering if anyone could suggest any ways to make it a bit cleaner. Also, the HTML structure has to pretty well stay as-is because its kind of finnicky with the styling.

I should also note that I'm not the most experienced with jQuery, so...

This is the code in question and the relevant HTML (the buttons at the top are in another part of the HTML, but I included them here to see how they're structured):

$("#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>

CodePudding user response:

Using a data attribute and a common selector, you can replace all the clicks into one.

$("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>

CodePudding user response:

I see your not on style, probably something there that can be addressed as a separate question - probably just some odd CSS with an easy fix.

Here I used classes and did some minor structure changes to facilitate some "grouping" - I set and clear a data value to make the code slightly less and not impact the page DOM as much as it does not toggle classes (often messes with style a bit when toggled)

Totally out of scope but I added a Show/Hide just for fun that can be clicked also and set an initial state for "Show" to be hidden on that. I also note there is no "initial" filter/group but left that out and made a comment in the code to illustrate it being set on page load.

$("#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  data-target="#codes">Codes</button>
  <button  data-target="#gfx">Graphics</button>
  <button  data-target="#tuts">Resources</button>
  <span >
  <span >Show</span>
  <span >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" >Codes</div>
    <div id="gfx" >Graphics</div>
    <div id="tuts" >Resources</div>
  </div>
</div>

  • Related