0

I'm having trouble repositioning elements that sometimes should have transitions, sometimes not.

The actions works fine isolated but the view doesn't seem to update half-way in the combined action. What's the solution?

$(document).ready(function() {
  $('#goLeft').on('click',function() {
    $('#box').removeClass('soft');
    $('#box').css('left','300px');
  });
  $('#goRight').on('click',function() {
    $('#box').addClass('soft');
    $('#box').css('left','400px');
  });
  $('#goLeftAndRight').on('click',function() {
    //copy
    $('#box').removeClass('soft');
    $('#box').css('left','300px');
    //Need for timeout?
    //copy
    $('#box').addClass('soft');
    $('#box').css('left','400px');    
  });
});
h2 {
  cursor:pointer;
}

#box {
  position: fixed;
  top:100px;
  left:400px;
  height:100px;
  width:100px;
  background-color:#358;
}

#box p {
  padding:5px;
  color:#fff;
  text-align:center;
}

.soft {
  transition: all 0.3s ease-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
  <body>
    <h2 id="goLeft">jump left</h2>
    <h2 id="goRight">slide right</h2>
    <h2 id="goLeftAndRight">jump left and slide right</h2>
    <div id="box"><p>use headers to move</div>
  </body>
</html>
      

0

7 Answers 7

2

There is 2 ways you can do it -

1# - Combining your function with CSS animation

$(document).ready(function() {
  $('#goLeft').on('click', function() {
    $('#box').removeClass('soft left-right');
    $('#box').css('left', '300px');
  });
  $('#goRight').on('click', function() {
    $('#box').addClass('soft').removeClass('left-right');
    $('#box').css('left', '400px');
  });
  $('#goLeftAndRight').on('click', function() {
    $('#box').addClass('left-right').removeClass('soft');
  });
});
h2 {
  cursor: pointer;
}

#box {
  position: fixed;
  top: 100px;
  left: 400px;
  height: 100px;
  width: 100px;
  background-color: #358;
}

#box p {
  padding: 5px;
  color: #fff;
  text-align: center;
}

.soft {
  transition: all 0.3s ease-out;
}
@keyframes leftRight{
  0%{left:300px}
  100%{left:400px}
}

.left-right{
  left:400px
  animation: leftRight 0.3s forwards ease-in-out;
  -webkit-animation: leftRight 0.3s forwards ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>

<body>
  <h2 id="goLeft">jump left</h2>
  <h2 id="goRight">slide right</h2>
  <h2 id="goLeftAndRight">jump left and slide right</h2>
  <div id="box">
    <p>use headers to move</div>
</body>

</html>

2# - Combining your function with setTimeout function.

$(document).ready(function() {
  $('#goLeft').on('click',function() {
    $('#box').removeClass('soft');
    $('#box').css('left','300px');
  });
  $('#goRight').on('click',function() {
    $('#box').addClass('soft');
    $('#box').css('left','400px');
  });
  $('#goLeftAndRight').on('click',function() {
    //copy
    $('#box').removeClass('soft');
    $('#box').css('left','300px');
     setTimeout(function() {
       $('#box').addClass('soft');
       $('#box').css('left','400px'); 
     }, 300);

       
  });
});
h2 {
  cursor:pointer;
}

#box {
  position: fixed;
  top:100px;
  left:400px;
  height:100px;
  width:100px;
  background-color:#358;
}

#box p {
  padding:5px;
  color:#fff;
  text-align:center;
}

.soft {
  transition: all 0.3s ease-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
  <body>
    <h2 id="goLeft">jump left</h2>
    <h2 id="goRight">slide right</h2>
    <h2 id="goLeftAndRight">jump left and slide right</h2>
    <div id="box"><p>use headers to move</div>
  </body>
</html>

Sign up to request clarification or add additional context in comments.

3 Comments

I very much like your use of animation & keyframes here. Good job!
Glad to know that. If there is anything more I can help you with please do free to ask.
@Teson if it was helpful please mark it as Answer
2

You do not need jQuery for this setup.

If you write one CSS class which contains the .jump-left transition:

.jump-left {
transform: translateX(-100px);
}

and one CSS class which contains the .slide-right animation:

.slide-right {
animation: slide-right-animation 1s ease-out;
}

@keyframes slide-right-animation {
  0% {transform: translateX(-100px);}
100% {transform: translateX(0);}
}

you can use an onclick event listener to apply one class or the other - or one followed by the other.

Working Example:

var box = document.getElementsByClassName('box')[0];
var buttons = document.getElementsByTagName('button');

function buttonPress() {

    switch (true) {

        case (this.classList.contains('go-left')) :   
            box.setAttribute('class', 'box');
            box.classList.add('jump-left');
            break;
            
        case ((this.classList.contains('go-right')) && (box.classList.contains('jump-left'))) : 
            box.setAttribute('class', 'box');
            box.classList.add('slide-right');
            break;
        
        case (this.classList.contains('go-left-then-right')) :
            box.setAttribute('class', 'box');
            box.classList.add('jump-left');
            setTimeout(function(){
                box.classList.remove('jump-left');
                box.classList.add('slide-right');
            }, 300);
            break;
    }
}

for (var i = 0; i < buttons.length; i++) {
    buttons[i].addEventListener('click', buttonPress, false);
}
button {
cursor:pointer;
}

.box {
  position: fixed;
  top:50px;
  left:400px;
  height:100px;
  width:100px;
  background-color:#358;
}

.box p {
  padding:5px;
  color:#fff;
  text-align:center;
}

.jump-left {
transform: translateX(-100px);
}

.slide-right {
animation: slide-right-animation 1s ease-out;
}

@keyframes slide-right-animation {
  0% {transform: translateX(-100px);}
100% {transform: translateX(0);}
}
<button type="button" class="go-left">jump left</button>
<button type="button" class="go-right">slide right</button>
<button type="button" class="go-left-then-right">jump left and slide right</button>

<div class="box"><p>Use buttons to move.</p></div>

Comments

1

add soft class by default and use timeout in leftright

$(document).ready(function() {
    $('#goLeft').on('click', function() {
        $('#box').css('left', '300px');
    });
    $('#goRight').on('click', function() {
        $('#box').css('left', '400px');
    });
    $('#goLeftAndRight').on('click', function() {
        //copy
        $('#box').css('left', '300px');
        setTimeout(function() {
            $('#box').css('left', '400px');
        }, 300);
        //Need for timeout?
        //copy
    });
});

h2 {
cursor:pointer;
}
#box {
position: fixed;
top:100px;
left:400px;
height:100px;
width:100px;
background-color:#358;
}
#box p {
padding:5px;
color:#fff;
text-align:center;
}
.soft {
transition: all 0.3s ease-out;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
   <body>
      <h2 id="goLeft">jump left</h2>
      <h2 id="goRight">slide right</h2>
      <h2 id="goLeftAndRight">jump left and slide right</h2>
      <div id="box" class="soft">
         <p>use headers to move
      </div>
   </body>
</html>

Refer this demo

Comments

1

Fixing the delay is quite simple. You just need to wrap the secondary part of your jump left and slide right function inside a setTimeout() function like this:

setTimeout(function(){
    $('#box').addClass('soft');
    $('#box').css('left','400px');
}, 100);

Below is a working snippet:

$(document).ready(function() {

  $('#goLeft').on('click',function() {
    $('#box').removeClass('soft').css('left','300px');
  });
  
  $('#goRight').on('click',function() {
    $('#box').addClass('soft').css('left','400px');
  });
  
  $('#goLeftAndRight').on('click',function() {
    $('#box').removeClass('soft').css('left','300px');
    
    //wait 100ms
    setTimeout(function(){
    	$('#box').addClass('soft').css('left','400px');
    }, 100);
          
  });
});
h2 {
  cursor:pointer;
}

#box {
  position: fixed;
  top:100px;
  left:400px;
  height:100px;
  width:100px;
  background-color:#358;
}

#box p {
  padding:5px;
  color:#fff;
  text-align:center;
}

.soft {
  transition: all 0.3s ease-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
    <h2 id="goLeft">jump left</h2>
    <h2 id="goRight">slide right</h2>
    <h2 id="goLeftAndRight">jump left and slide right</h2>
    <div id="box"><p>use headers to move</div>
  </body>

EDIT:

Thanks to Mohammad for pointing out a simpler way to do the jQuery functions. I have adjusted the snippet above to show that.

2 Comments

Also you can shorten the code using chaining feature like $('#box').addClass('soft').css('left','400px')
@Mohammad Thanks! Will add that to the code snippet to showcase - thanks for pointing that out :)
0

Adding timeout of 100 ms is working fine.

Below is the code which i have used to recreate your mentioned scenario and tested.

<html>
<head>
<style>
h2 {
  cursor:pointer;
}

#box {
  position: fixed;
  top:100px;
  left:400px;
  height:100px;
  width:100px;
  background-color:#358;
}

#box p {
  padding:5px;
  color:#fff;
  text-align:center;
}

.soft {
  transition: all 0.3s ease-out;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
  $('#goLeft').on('click',function() {
    $('#box').removeClass('soft');
    $('#box').css('left','300px');
  });
  $('#goRight').on('click',function() {
    $('#box').addClass('soft');
    $('#box').css('left','400px');
  });
  $('#goLeftAndRight').on('click',function() {
    //copy
    $('#box').removeClass('soft');
    $('#box').css('left','300px');
    //Need for timeout?
    //copy
    setTimeout(function(){
       $('#box').addClass('soft');
       $('#box').css('left','400px'); 
    }, 100);

  });
});
</script>
</head>
  <body>
    <h2 id="goLeft">jump left</h2>
    <h2 id="goRight">slide right</h2>
    <h2 id="goLeftAndRight">jump left and slide right</h2>
    <div id="box"><p>use headers to move</div>
  </body>
</html>

Please mark it as an answer if it is as per your need.

1 Comment

Ohh its exactly same, Seems we both pasted at the same time, Some how i miised seeing your response.
0

$('#goLeftAndRight').on('click',function() {
  //that part actually sets the initial position
  $('#box').removeClass('soft');
  $('#box').css('left','300px');

  // see below
  setTimeout(function() {
    $('#box').addClass('soft');
    $('#box').css('left','400px'); 
  },0);
});

The setTimeout here just wait for the next browser available time

If you plan to do advanced animation with different cue points, you might be interested by something like https://greensock.com/timelinelite

Comments

-1

addClass should be done when animation is starting.

$(document).ready(function() {
  $('#goLeft').on('click',function() {
    $('#box').removeClass('soft');
    $('#box').stop().animate({left:'300px'},{queue: false, duration:0});
  });
  $('#goRight').on('click',function() {
    $('#box').addClass('soft');
    $('#box').stop().animate({left:'400px'},{queue: false});
  });
  $('#goLeftAndRight').on('click',function() {
    //copy
    $('#box').removeClass('soft');
$('#box').stop().animate({left:'300px'}, { 
    queue: false, duration:0}).animate({left:'400px'},{ queue: false, start:
 function(){$('#box').addClass('soft'); } });


  });

});
h2 {
  cursor:pointer;
}

#box {
  position: fixed;
  top:100px;
  left:400px;
  height:100px;
  width:100px;
  background-color:#358;
}

#box p {
  padding:5px;
  color:#fff;
  text-align:center;
}

.soft {
  transition: all 0.3s ease-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
  <body>
    <h2 id="goLeft">jump left</h2>
    <h2 id="goRight">slide right</h2>
    <h2 id="goLeftAndRight">jump left and slide right</h2>
    <div id="box"><p>use headers to move</div>
  </body>
</html>
      

2 Comments

Question is about jumping left and slide right but your code slide left and then slide right.
@Teson. to make it jump use duration as 0 (as default is 400) and add the soft class in start function of animation. start: function(){$('#box').addClass('soft'); }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.