1
\$\begingroup\$

The code I'm bringing forward is for a vertical menu, where I needed a marker to do the following:

  • When hovering over a link the marker should slide down next to it.

  • When not hovering over a link the marker should return to the side of the current selected link (the default being the first link).

  • When a link is clicked the marker should remain next to the clicked link, unless another link is being hovered over.

What I've done in jQuery is add a class ('.staydown0','.staydown1' or '.staydown2') to the marker div ('#slide') when one one of the links ('#menulink1','#menulink2' or '#menulink3') is clicked, and remove any other classes that would have it be situated next to one of the other links.

Then I've set jQuery to add a class ('.movedown0','.movedown1' or '.movedown2') to the marker div ('#slide') when the mouse hovers over one of the links ('#menulink1','#menulink2' or '#menulink3'), and remove the class when the mouse stops hovering over the link.

The code works, but it is redundant. How could I go about abstracting it?

I've already asked a similar question recently where I only had the "hover" part of the menu set up, and it was solved.

But I am a beginner in javascript and jQuery, and even though I've managed to understand the solution that was offered to me in the previous question, I am at a loss as to how to extrapolate that knowledge to abstracting this more convoluted code.

CODEPEN

HTML(Pug):

.staydown0#slide

#menu
  a.menulink#menulink1(href="#")
    p RED
  a.menulink#menulink2(href="#")
    p BLUE
  a.menulink#menulink3(href="#")
    p GREEN

CSS (Sass)

a
  color: white
  text-decoration: none

#slide
  width: 10px
  height: 30px
  position: absolute
  border-radius: 15px
  transition: 0.3s ease-in-out

#slide.staydown0
  margin-top: 0px
  background-color: red

#slide.staydown1
  margin-top: 40px
  background-color: blue

#slide.staydown2
  margin-top: 80px
  background-color: green

#slide.movedown0
  margin-top: 0px
  background-color: red


#slide.movedown1
  margin-top: 40px
  background-color: blue

#slide.movedown2
  margin-top: 80px
  background-color: green

#menu
  margin-left: 30px

.menulink
  height: 40px
  width: 70px
  display: block

.menulink p
  height: 30px
  width: 70px
  margin: 0px
  border-radius: 15px
  display: flex
  align-items: center
  justify-content: center

#menulink1 p
  background: red
#menulink2 p
  background: blue
#menulink3 p
  background: green

jQuery

$('#menulink1').hover(
  function(){
    $('#slide').addClass('movedown0');
  },
  function(){
     $('#slide').removeClass('movedown0')  

});

$('#menulink2').hover(
  function(){
    $('#slide').addClass('movedown1');
  },
  function(){
    $('#slide').removeClass('movedown1')  

});

$('#menulink3').hover(
  function(){
    $('#slide').addClass('movedown2');
  },
  function(){
    $('#slide').removeClass('movedown2')  

});

///////

$('#menulink1').on(
  'click', function(){
      $('#slide').addClass('staydown0').removeClass('staydown1 staydown2');

});

$('#menulink2').on(
  'click', function(){
    $('#slide').addClass('staydown1').removeClass('staydown0 staydown2');

});

$('#menulink3').on(
  'click', function(){
    $('#slide').addClass('staydown2').removeClass('staydown0 staydown1');

});

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.