5
\$\begingroup\$

I'm trying to toggle a dropdown box that will appear and disappear upon clicking the button.

var clickState = false;

$("#show").on("click", function() {
  if (!clickState) {
    $(".animated").removeClass("off");
    renewElement($(".animated"));
    $(".animated").addClass("on");
    clickState = true;
  } else if (clickState) {
    $(".animated").removeClass("on");
    renewElement($(".animated"));
    $(".animated").addClass("off");
    clickState = false;
  }
});

function renewElement(e) {
  var newElement = e.clone(true);
  e.remove();
  $(".container").append(newElement);
}
.controls {
  text-align: center;
}
button {
  display: inline-block;
}
.textbox {
  width: 280px;
  margin: 0 auto;
  background: tomato;
  padding: 10px;
}
.animated {
  max-height: 0;
  overflow: hidden;
  animation-name: none;
  animation-duration: 0.5s;
  animation-fill-mode: forwards;
}
.triangle {
  content: " ";
  width: 0;
  height: 0;
  border: 10px solid;
  border-color: transparent transparent tomato transparent;
  position: relative;
  left: 50%;
  top: -9px;
  margin-left: -7px;
}
.on {
  animation-name: slideOpen;
  animation-direction: normal;
}
.off {
  animation-name: slideOpen;
  animation-direction: reverse;
}
@keyframes slideOpen {
  0% {
    max-height: 0px;
    padding: 0px;
  }
  100% {
    max-height: 150px;
  }
}
<div class="controls">
  <button id="show">Show div</button>
</div>
<div class="container">
  <div class="animated">
    <span class="triangle"></span>
    <div class="textbox">text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

  • I'm using a clickState boolean to keep track of the on and off presses, creating the toggle.

  • I'm also cloning the entire div and recreating it so that the animation will refresh properly. It seems that without this, the animation will only run once.

  • The animation is connected to the element with the .addClass() method.

I'm new to animation, but I can't help but feel I'm writing some really hideous code here. For starters, the code is clearly not reusable. I would also like to know if there is a better way of repeating the animation without cloning and then appending the element.

Feel free to fork my pen on CodePen to test any changes.

\$\endgroup\$
3
\$\begingroup\$

This is what I've come up with, which is nicer than the if/else if statement I was originally using.

$("#show").on("click", function() {
  renewElement($(".animated"));
  var $animated = $(".animated");
  var shown = $animated.hasClass('on');
  $animated.toggleClass('on', !shown).toggleClass('off', shown);
});

function renewElement(e) {
  var newElement = e.clone(true);
  e.remove();
  $(".container").append(newElement);
}
.controls {
  text-align: center;
}

button {
  display: inline-block;
}

.textbox {
  width: 280px;
  margin: 0 auto;
  background: tomato;
  padding: 10px;
}

.animated {
  max-height: 0;
  overflow: hidden;
  animation-name: none;
  animation-duration: 0.5s;
  animation-fill-mode: forwards;
}
.triangle {
  content: " ";
  width: 0;
  height: 0;
  border: 10px solid;
  border-color: transparent transparent tomato transparent;
  position: relative;
  left: 50%;
  top: -9px;
  margin-left: -7px;
}

.on {
  animation-name: slideOpen;
  animation-direction: normal;
}

.off {
  animation-name: slideOpen;
  animation-direction: reverse;
}

@keyframes slideOpen {
  0% {
    max-height: 0px;
    padding: 0px;
  }
  100% {
    max-height: 150px;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="controls">
  <button id="show">Show div</button>
</div>
<div class="container">
  <div class="animated">
    <span class="triangle"></span>
    <div class="textbox">text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  </div>
</div>

As you can see, I've kept the renewElement() function. After reading this article it seems that there isn't much you can do.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.