Search code examples
javascriptjquerycssslide

jQuery jumpy effect when using .slideToggle()


I was following a Udemy Bootcamp that included coding a Todo list using jQuery. The program required the text input to disappear when pressing a "minimize" button by making it fade, but then all the lower elements would just "jump up" once the input disappeared. I thought I'd improve that by replacing it with a slide effect.

The issue is that the input slides up and mostly disappears, then all of a sudden "jumps" up. I already looked on stackOverflow and it seems to be something related to the size/margin or the container, but by fiddling with it (and even setting it and/or removing it through the console), I was still not able to make this effect go away and I think I need some help.

// Check off todos while clicking. Use on(click) to add event listener 
// to future elements not yet on page when the code first runs. We apply it to the whole ul for
// ("click", "li") means the event listener is applied to the li inside the ul
$("ul").on("click", "li", function() {
  $(this).toggleClass("completed");
});

// Click on X to delete Todo
$("ul").on("click", "span", function(event) {
  $(this).parent().fadeOut(500, function() {
    $(this).remove();
  });
  event.stopPropagation();
});

$("input[type='text']").keypress(function(event) {
  if (event.which === 13) {
    // grab the text of the new todo from the input
    var todoText = $(this).val();
    $(this).val("");
    // create new li to add to the ul
    $("ul").append("<li>" + "<span><i class='fa fa-trash'></i></span> " + todoText + "</li>");
  }
})

// Make the plus sign collapse the text input
$(".fa-plus").click(function() {
  $("input").slideToggle(function() {

  });
});
body {
  background: #2980B9;
  /* fallback for old browsers */
  background: -webkit-linear-gradient(to right, #FFFFFF, #6DD5FA, #2980B9);
  /* Chrome 10-25, Safari 5.1-6 */
  background: linear-gradient(to right, #FFFFFF, #6DD5FA, #2980B9);
  /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}

#container {
  width: 360px;
  margin: 5% auto;
  background: #f7f7f7;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
}

.completed {
  color: gray;
  text-decoration: line-through;
}

.fa-plus {
  float: right;
}

h1 {
  background: #2980b9;
  color: white;
  margin: 0;
  padding: 10px 20px;
  text-transform: uppercase;
  font-size: 24px;
  font-weight: normal;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

li {
  background: white;
  height: 40px;
  line-height: 2.5em;
}

li:nth-child(2n) {
  background: #f7f7f7;
}

input {
  font-size: 18px;
  background-color: #f7f7f7;
  width: 360px;
  padding: 13px 13px 13px 20px;
  box-sizing: border-box;
  border: 3px solid rgba(0, 0, 0, 0);
}

input:focus {
  background: white;
  border: 3px solid #2980b9;
  outline: none;
}

span {
  background: red;
  height: 40px;
  margin-right: 40px;
  text-align: center;
  color: white;
  width: 0;
  display: inline-block;
  opacity: 0;
  transition: 0.2s linear;
}

li:hover span {
  width: 40px;
  opacity: 1;
}

.hidden {
  display: none;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css">
<div id="container">
  <h1>To-Do List<i class="fa fa-plus"></i></h1>
  <input type="text" placeholder="Add new Todo">
  <ul>
    <li><span><i class="fa fa-trash"></i></span> First item</li>
    <li><span><i class="fa fa-trash"></i></span> Second item</li>
    <li><span><i class="fa fa-trash"></i></span> Third item</li>
  </ul>
</div>

This is just a snippet. I uploaded the whole code on Fiddle and would appreciate any help

Thanks!


Solution

  • instead of toggle the input directly, wrap the input with a div. and then toggle the div

    changes to make:

    <div id='input'>
       <input type="text" placeholder="Add new Todo">
    </div>
    
    $(".fa-plus").click(function() {
        $("#input").slideToggle();
    });