Search code examples
javascripthtmleventsprototypedisable

How would I disable the event temporarily in plain JavaScript?


I'm making my own slider system with plain JavaScript. The issue is every time when I redo a touch-starting before its animation is done, the event and the animation are going to override like this:

enter image description here

My expectation is to get rid off the overriding, and disabling the touchevents temporarily until the CSS animation(adding, removing the CSS classes by using .classList in JS) is over.

I've tried to resolve this issue by myself but have no idea how would I do this.

I attach the basis code structure which what I used in the GIF above as simplify as possible. Please excuse that couldn't upload the full code on this snippet because the question would be too long and unreadable:

'use strict';
(function () {
  function Card($el) {
    this.$el = $el;
    this.$el.addEventListener('touchstart', (e) => this.start(e));
    this.$el.addEventListener('touchmove', (e) => this.move(e));
    this.$el.addEventListener('touchend', (e) => this.end(e));
  }
  Card.prototype = {
    start: function(e) {
      this.active = false;
      this.coordX = e.touches[0].clientX;
      this.coordY = e.touches[0].clientY;
    },
    move: function(e) {
      this.active = true;
      var x = e.touches[0].clientX,
          y = e.touches[0].clientY,
          dist = Math.sqrt(x + this.coordX);
    },
    end: function(e) {
      let distAmount = e.changedTouches[0].clientX - this.coordX;
      if (distAmount > 200) {
        this.create(this.direction * -1, this.swipe);
      } else if (distAmount < -200) {
        this.create(this.direction, this.swipe);
      }
    },
    create: function(direction, callback) {
      let bound = callback.bind(this);
      console.log(`Disable the whole events (touchstart, move, end)`);
      setTimeout(bound, 100, direction, this.resize);
    },
    swipe: function(direction, callback) {
      let binding = callback.bind(this);
      console.log('Disabling the events');
      setTimeout(binding, 800, direction);
    },
    resize: function() {
      console.log(`Allow the events after this function is end`);
    }
  }

  /********************************************************************/

  let news_box = document.getElementById('box1');
  const newsCard = new Card(news_box);
}());
      * {
        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;
      }
      .purple {
        background-color: purple;
      }
    <div id="box1">
      <div class="contents purple">
        box content
      </div>
    </div>


Solution

  • You can introduce a boolean this.allowTriggering = true; inside function Card($el)

    in create you should put it to false this.allowTriggering = false;

    in resize you should revert it back to true this.allowTriggering = true;

    Then you wrap your functions start, move and end with an if condition to check if this.allowTriggering is true.

    Full Code:

    'use strict';
    (function () {
        function Card($el) {
            this.$el = $el;
            this.$el.addEventListener('touchstart', (e) => this.start(e));
            this.$el.addEventListener('touchmove', (e) => this.move(e));
            this.$el.addEventListener('touchend', (e) => this.end(e));
            this.allowTriggering = true;
        }
    
        Card.prototype = {
            start: function (e) {
                if (this.allowTriggering) {
                    this.active = false;
                    this.coordX = e.touches[0].clientX;
                    this.coordY = e.touches[0].clientY;
                }
            },
            move: function (e) {
                if (this.allowTriggering) {
                    this.active = true;
                    var x = e.touches[0].clientX,
                        y = e.touches[0].clientY,
                        dist = Math.sqrt(x + this.coordX);
                }
            },
            end: function (e) {
                if (this.allowTriggering) {
                    let distAmount = e.changedTouches[0].clientX - this.coordX;
                    if (distAmount > 200) {
                        this.create(this.direction * -1, this.swipe);
                    } else if (distAmount < -200) {
                        this.create(this.direction, this.swipe);
                    }
                }
            },
            create: function (direction, callback) {
                let bound = callback.bind(this);
                console.log(`Disable the whole events (touchstart, move, end)`);
                this.allowTriggering = false;
                setTimeout(bound, 100, direction, this.resize);
            },
            swipe: function (direction, callback) {
                let binding = callback.bind(this);
                console.log('Disabling the events');
                setTimeout(binding, 800, direction);
            },
            resize: function () {
                console.log(`Allow the events after this function is end`);
                this.allowTriggering = true;
            }
        };
    
        /********************************************************************/
    
        let news_box = document.getElementById('box1');
        const newsCard = new Card(news_box);
    }());