0

Here the transition works just fine. But if I don't use setTimeout and straightforwardly make the transform the div is already at the end of transition.

function move(x, y, delay) {
  let el = document.getElementById('myDiv');
  el.style.transform = `translateX(${x}%)`
  el.style.transition = `transform ${delay}s linear`

  setTimeout(() => {
    el.style.transform = `translateX(${y}%)`
  }, 1000)
}


move(100, 200, 1)
.myDiv {
  height: 50px;
  width: 50px;
  background: blue;
}
<div class="myDiv" id="myDiv">
  Content
</div>

In This case div is already at the end of transition. But js being synchronous all these instructions should be executed sequentially then why the entire transition is not taking place in this case?

function move(x, y, delay) {
  let el = document.getElementById('myDiv');
  el.style.transform = `translateX(${x}%)`
  el.style.transition = `transform ${delay}s linear`
  el.style.transform = `translateX(${y}%)`
}


move(100, 200, 1)
.myDiv {
  height: 50px;
  width: 50px;
  background: blue;
}
<div class="myDiv" id="myDiv">
  Content
</div>
Justinas
  • 41,402
  • 5
  • 66
  • 96

2 Answers2

1

It is kinda weird to me still but you need to "refresh" the CSS changes. To do that, you need to read an element's property, for example el.innerText, before applying your new style.

 function move(x,y,delay){
    let el = document.getElementById('myDiv');
    el.style.transform = `translateX(${x}%)`
    el.style.transition = `transform ${delay}s linear`
    el.innerText;
    el.style.transform = `translateX(${y}%)`    
}

move(100,200,1)
 .myDiv{
      height: 50px;
      width: 50px;
      background: blue;
 }
<div class="myDiv" id="myDiv">
  Content
</div>

I don't know what's causing this however, maybe someone here could explain it.

  • 2
    `innerText` is probably one of the most obscure "properties" you could read. With others like `offsetX` it sounds more obvious why the browser would have to recalc all the box positions to be able to calculate that value. (`innerText` also needs it because it basically only returns the "selectable" text of the element when it's rendered). – Kaiido Apr 17 '21 at 04:57
  • I see, thanks for the info. I chose innerText because it's the first that came to my mind at the time and it worked so I kept it. – Titouan Le Floch Riche Apr 17 '21 at 05:12
  • Thank you for all the help. Wasn't familiar with reflow and repaint concepts. So we are forcing reflow with el.innerText . – Daksh Sharma Apr 18 '21 at 09:34
  • Just to make sure it's clear, ```el.innerText``` OR others like ```offsetX``` as Kaiido mentioned. Glad we helped you :) and make sure to mark the question as answered. – Titouan Le Floch Riche Apr 19 '21 at 10:42
0

CSS keyframes can be used here as:

#myDiv{
animation: slidein 1s forwards

}
@keyframes slidein {
  from {
   transform: translateX(100%);
  }

  to {
    transform: translateX(200%);
  }
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
    .myDiv{
      height: 50px;
      width: 50px;
      background: blue;
    }
</style>
</head>
<body>

  <div class="myDiv" id="myDiv">
  Content
  </div>
    
</body>
</html>
Shivaji Mutkule
  • 1,020
  • 1
  • 15
  • 28