Skip to content
Advertisement

how to delay an insertBefore?

It is possible to stop an insertBefore, inside an addEventListener, to add a smooth css, so that the movement produced by the insertion of the div is not abrupt for the user?

I have read many questions, i have tried using settimeout in various ways, without success:

const gallery = document.getElementById('gallery');

const frames = gallery.querySelectorAll('.frame');

for (var i = 0; i < frames.length; ++i) {

  frames[i].addEventListener('click', function() {

    if (this.className == "frame b") {

      //setTimeout( function(){

      gallery.insertBefore(this, this.previousElementSibling);

      //}, 1000 );

    } else {

      //setTimeout( function(){

      gallery.insertBefore(this, this.previousElementSibling);

      //}, 1000 );

    };

  });

};
.frame {
  width: 200px;
  height: 100px;
  font: bold 400% sans-serif;
  color: white;
  float: left;
}

.frame.a {
  background-color: brown;
}

.frame.b {
  background-color: purple;
}
<div id="gallery">
  <div class="frame a">A</div>
  <div class="frame b">B</div>
</div>

Advertisement

Answer

this refers to a different context inside your setTimeout callback; it doesn’t refer to the element for which the event is dispatched anymore.

There are a few ways you could do this, here are 3:

Use an arrow function, where this doesn’t get bound to a new context:

setTimeout( () => {
    gallery.insertBefore(this , this.previousElementSibling);
}, 1000 );

Store a reference to this for use inside the callback:

const _self = this;

setTimeout( function(){
    gallery.insertBefore(_self , _self.previousElementSibling);
}, 1000 );

Manually bind the current context to the callback function:

setTimeout( function(){
    gallery.insertBefore(this, this.previousElementSibling);
}.bind(this), 1000 );
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement