简体   繁体   中英

Looking for a more efficient way to write this jquery menu

I'm pretty new to Jquery, so I've been going through some examples on w3schools.com, to get some ideas how to write better code. Out of more curiosity than anything, I came up with this pretty simple menu, which has four divs, a main div called #main-slide which contains three links that points to three sub slides sub-slide-one , sub-slide-two , sub-slide-three . By the way none of these actually slide in or out I just for whatever reason named them that way.

Here is the HTML:

<body>


  <div id="main-slide">

    <a class="Subone" href="#">SUB ONE</a>
    <a class="Subtwo" href="#">SUB TWO</a>
    <a class="Subthree" href="#">SUB THREE</a>

  </div>


  <div id="sub-slide-one">

    <h1>SUB ONE</h1>

    <a class="BackMain1" href="#">BACK TO MAIN</a>

  </div>

  <div id="sub-slide-two">

    <h1>SUB TWO</h1>

    <a class="BackMain2" href="#">BACK TO MAIN</a>

  </div>



  <div id="sub-slide-three">

    <h1>SUB THREE</h1>

    <a class="BackMain3" href="#">BACK TO MAIN</a>

  </div>

</body>

Here is the CSS:

body {
  background-color: antiquewhite;
}

h1 {
  text-align: center;
  padding-top: 30px;
}

a {
  text-decoration: none;
  color: #fff;
  font-family: arial;
  font-weight: bold;
  text-align: center;
  display: block;
  padding-top: 30px;
}

#sub-slide-one,
#sub-slide-two,
#sub-slide-three {
  display: none;
  width: 90%;
  height: 600px;
  position: relative;
  margin: 0 auto;
  margin-top: 30px;
}

#main-slide {
  width: 90%;
  height: 600px;
  position: relative;
  margin: 0 auto;
  margin-top: 30px;
  background-color: aliceblue;
  display: block;
}

#sub-slide-one {
  background-color: cadetblue;
}

#sub-slide-two {
  background-color: crimson;
}

#sub-slide-three {
  background-color: cornflowerblue;
}

.Subone,
.Subtwo,
.Subthree {
  width: 100%;
  height: 200px;
  display: block;
}

.Subone {
  background-color: dodgerblue;
}

.Subtwo {
  background-color: darkkhaki;
}

.Subthree {
  background-color: darkgoldenrod
}

For the JavaScript each link has a fadein/fadeout click function on it. For example when Subone is clicked the #main-slide is faded out and sub-slide-one is faded in. Each sub slide contain a back link which links back to the main slide. This is where I ultimately run into problems, the menu works as intended, although when I click the SubThree link it jumps to the top first for whatever reason.

But to get the back links to fadein/out the divs properly I had to create each back link with a separate class, and separate function to get the desired result.

Here is the Jquery:

$(document).ready(function() {


  $(".Subone").click(function() {
    $("#main-slide").fadeOut(1200);
    $("#sub-slide-one").delay(1200).fadeIn(1200);

  });

  $(".Subtwo").click(function() {
    $("#main-slide").fadeOut(1200);
    $("#sub-slide-two").delay(1200).fadeIn(1200);

  });

  $(".Subthree").click(function() {
    $("#main-slide").fadeOut(1200);
    $("#sub-slide-three").delay(1200).fadeIn(1200);

  });


  $(".BackMain1").click(function() {
    $("#sub-slide-one").fadeOut(1200);
    $("#main-slide").delay(1200).fadeIn(1200);

  });

  $(".BackMain2").click(function() {
    $("#sub-slide-two").fadeOut(1200);
    $("#main-slide").delay(1200).fadeIn(1200);

  });

  $(".BackMain3").click(function() {
    $("#sub-slide-three").fadeOut(1200);
    $("#main-slide").delay(1200).fadeIn(1200);

  });


});

I have to believe there is a much more efficient way to do this, but I can't seem to figure out how. Here's a link to JSfiddle to see this in action https://jsfiddle.net/Dylancougar/k9f53wpp/

Define a common class for parent menu and also an ID to use it as a relation between parent and children menu. Get the ID on Click and use it to decide which submenu has to react :

 <div id="main-slide">

    <a class="topmenu" id="1" href="#">SUB ONE</a>
    <a class="topmenu" id="2" href="#">SUB TWO</a>
    <a class="topmenu" id="3" href="#">SUB THREE</a>

  </div>


  <div id="sub-slide-1">

    <h1>SUB ONE</h1>

    <a class="Back" id="1" href="#">BACK TO MAIN</a>

  </div>

jquery:

  $(".topmenu").click(function() {
    var id=$(this).attr("id");
    $("#main-slide").fadeOut(1200);
    $("#sub-slide-"+id).delay(1200).fadeIn(1200);
  });

and use same method for closing the proper submenu.

  $(".back").click(function() {
    var id=$(this).attr("id");
    $("#sub-slide-"+id).fadeOut(1200);
    $("#main-slide").delay(1200).fadeIn(1200);
  });

Please consider that repeating and ID within a single page is not suggested. So you can define more complex IDs eg open1 or close1 and remove the extra words before calculations.

var id=$(this).attr("id").replace("open","");

You can achieve what you want like this . So you will have to change your HTML structure by adding a common class for every same elements and add an id for each of them. It will change your CSS a bit.

JS

$(function () {
  $(".sub").on('click', function (e) {
    let number = $(this).attr('id').split('-')[1];

    $("#main-slide").fadeOut(1200);
    $("#sub-slide-" + number).delay(1200).fadeIn(1200);

    e.preventDefault();
  });

  $(".backMain").on('click', function (e) {
    let number = $(this).attr('id').split('-')[1];

    $("#sub-slide-" + number).fadeOut(1200);
    $("#main-slide").delay(1200).fadeIn(1200);

    e.preventDefault();
  });
});

Add e.preventDefault() will avoid to go to top when clicking on a link. It's pretty the same solution than Ali Sheikhpour gave you. By this way it's easy to maintain and very understandable (with no repetitions).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM