0

According to this question and mdn.doc articles, I'm giving a Callback function inside of aprototype for managing the next code line after it's done.

But even if I create the Callback, the browser keeps ignoring it and running the next code line no matter the Callback is completed or not.

This is the code:

'use strict';
(function() {

  function Box($el, $frame) {
    // Reassign the Values
    this.$el = $el;
    this.$frame = $frame;

    // Event Register Zone
    this.$el.addEventListener('touchstart', (e) => this.start(e));
    this.$el.addEventListener('touchmove', (e) => this.move(e));
    this.$el.addEventListener('touchend', (e) => this.end(e));
  }

  Box.prototype = {
    start: function(e) {
      console.log('touchstart has been detected');
    },
    move: function(e) {
      console.log('touchmove has been detected');
    },
    end: function(e) {
      console.log('touchend has been detected');
      this.getanAction(this.moveTop);
    },
    getanAction: function(callback) {
      let bound = callback.bind(this);
      bound();
      this.$frame[1].classList.add('leftMover');
      // Expectation: move the purple box first, and move the orange box next
    },
    moveTop: function() {
      this.$frame[0].classList.add('topMover');
    }
  }

  /***************************************************************/
  // Declare & Assign the Original Values

  let _elem = document.getElementById('box');
  let _frame = _elem.querySelectorAll('.contents');

  const proBox = new Box(_elem, _frame);

}());
      * {
        margin: 0;
        padding: 0;
      }
      #box {
        width: auto;
        height: 800px;
        border: 4px dotted black;
      }
      .contents {
        position: absolute;
        width: 200px;
        height: 200px;
        float: left;
        top: 0;
        left: 0;
        transition: 800ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
      }
      .purple { background-color: purple; }
      .orange { background-color: orange; }

      .topMover { top: 600px; }
      .leftMover { left: 600px; }
    <div id="box">
      <div class="contents purple">

      </div>
      <div class="contents orange">

      </div>
    </div>

My expectation is the .orange box moves after the .purple box moves done.

Did I miss or do something wrong from the code?

1 Answer 1

1

The problem is they are being called one after the other with no delay as JavaScript won't wait for the CSS transition to finish before moving to the next line.

I've fixed waiting for the first transition has finished before calling the bound callback. This way the purple box will move, wait for the transition to finish, then the orange box will move.

'use strict';
    (function() {

      function Box($el, $frame) {
        // Reassign the Values
        this.$el = $el;
        this.$frame = $frame;

        // Event Register Zone
        this.$el.addEventListener('touchstart', (e) => this.start(e));
        this.$el.addEventListener('touchmove', (e) => this.move(e));
        // Added mouse up so it works on desktop
        this.$el.addEventListener('mouseup', (e) => this.end(e));
        this.$el.addEventListener('touchend', (e) => this.end(e));
      }

      Box.prototype = {
        start: function(e) {
          console.log('touchstart has been detected');
        },
        move: function(e) {
          console.log('touchmove has been detected');
        },
        end: function(e) {
          console.log('touchend has been detected');
          this.getanAction(this.moveTop);
        },
        getanAction: function(callback) {
          let bound = callback.bind(this);
          // Listen for css transition end
          this.$frame[0].addEventListener('transitionend', function() {
         // Call callback to move orange box
            bound()
          });
          
          // Move the purple box now
          this.$frame[0].classList.add('topMover1')
        },
        moveTop: function() {
          this.$frame[1].classList.add('topMover2');
        }
      }

      /***************************************************************/
      // Declare & Assign the Original Values

      let _elem = document.getElementById('box');
      let _frame = _elem.querySelectorAll('.contents');

      const proBox = new Box(_elem, _frame);

    }());
* {
            margin: 0;
            padding: 0;
          }
          #box {
            width: auto;
            height: 800px;
            border: 4px dotted black;
          }
          .contents {
            position: absolute;
            width: 200px;
            height: 200px;
            float: left;
            top: 0;
            left: 0;
            transition: 800ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
          }
          .purple { background-color: purple; }
          .orange { background-color: orange; }

          .topMover1 { top: 600px; }
          .topMover2 { left: 600px; }
<div id="box">
          <div class="contents purple">

          </div>
          <div class="contents orange">

          </div>
        </div>

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

5 Comments

Using the .setTimeout is the only option to give a delay between the code lines?
I mean, Using the .setTimeout is unavoidable?
At first I thought the callback itself has its own delay. Anyway thank you for answering.
It is possible to detect when the transition has finished. I have updated my answer to use this instead of setTimout
Much appreciated :-)

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.