sniffingdoggo
sniffingdoggo

Reputation: 406

How to run the Callback function inside of the prototype in JavaScript?

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?

Upvotes: 0

Views: 116

Answers (1)

braza
braza

Reputation: 4662

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>

Upvotes: 1

Related Questions