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:
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>
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);
}());