Как запустить функцию обратного вызова внутри прототипа в JavaScript? - PullRequest
0 голосов
/ 10 мая 2019

В соответствии с этими вопросами и mdn.doc статьями, я даю функцию Callback внутри prototype для управления следующей строкой кода после того, как она будет завершена.

Но даже если я создаю Callback, браузер продолжает игнорировать его и запускать следующую строку кода независимо от того, завершен Callback или нет.

Это код:

'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>

Я ожидаю, что .orange перемещения блока после .purple перемещения блока завершены.

Я пропустил или сделал что-то не так с кодом?

1 Ответ

1 голос
/ 10 мая 2019

Проблема в том, что они вызываются один за другим без задержки, поскольку JavaScript не будет ждать завершения перехода CSS, прежде чем перейти к следующей строке.

Я исправил ожидание завершения первого перехода перед вызовом обратного вызова bound. Таким образом, фиолетовая коробка переместится, дождитесь окончания перехода, затем оранжевая коробка переместится.

'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>
...