I am using this code for dragging container left / right. This works well. User can also click on the "thumb". The problem is that click happens also after drag. It should be either drag or click. How can I isolate one or another? It has to work on tablets of course.
var thumbContainer = document.querySelector('.aplbox-thumb-container'),
thumbContainerWrap = document.querySelector('.aplbox-thumb-container-wrap'),
startXThumb,
startTouchThumb
if ("ontouchstart" in window) {
thumbContainer.addEventListener("touchstart", dragStartThumb);
}
thumbContainer.addEventListener("mousedown", dragStartThumb);
function dragStartThumb(e) {
if (e.preventDefault) e.preventDefault();
e.stopPropagation()
if (!startTouchThumb) {
startTouchThumb = true;
document.addEventListener('mousemove', dragMoveThumb)
document.addEventListener('mouseup', dragEndThumb);
if ("ontouchstart" in window) {
document.addEventListener('touchmove', dragMoveThumb)
document.addEventListener('touchend', dragEndThumb);
}
var point;
if (e.type == 'touchstart') {
var touches = e.changedTouches;
if (touches.length > 1) {
return false;
}
point = touches[0];
e.preventDefault();
} else {
point = e;
e.preventDefault();
}
var currX = thumbContainer.style.transform.replace(/[^\d.]/g, '');
currX = parseInt(currX) || 0;
startXThumb = point.pageX currX;
}
}
function dragMoveThumb(e) {
if (startTouchThumb) {
var point;
if (e.type == 'touchmove') {
var touches = e.changedTouches;
if (touches.length > 1) {
return false;
}
point = touches[0];
e.preventDefault();
} else {
point = e;
e.preventDefault();
}
var diff = point.pageX - startXThumb;
if (diff > 0) diff = 0;
else if (diff < -thumbContainer.offsetWidth thumbContainerWrap.offsetWidth) diff = -thumbContainer.offsetWidth thumbContainerWrap.offsetWidth;
thumbContainer.style.transform = 'translateX(' diff 'px)';
}
}
function dragEndThumb(e) {
e.stopPropagation()
if (startTouchThumb) {
startTouchThumb = false;
document.removeEventListener('mousemove', dragMoveThumb)
document.removeEventListener('mouseup', dragEndThumb);
if ("ontouchstart" in window) {
document.removeEventListener('touchmove', dragMoveThumb)
document.removeEventListener('touchend', dragEndThumb);
}
}
}
//click thumb
thumbContainerWrap.addEventListener('click', function(e) {
if (e.target.closest('.aplbox-thumb')) {
console.log('click')
}
})
.aplbox-thumb-container-wrap {
position: absolute;
top: 0;
left: 0;
background-color: #ccc;
width: 100%;
height: 100px;
overflow: hidden;
box-sizing: border-box;
}
.aplbox-thumb-container {
position: relative;
padding: 5px 0;
height: 100%;
display: flex;
flex-direction: row;
transform: translateX(0);
touch-action: none;
}
.aplbox-thumb {
width: 100px;
height: 70px;
margin-right: 5px;
box-sizing: border-box;
background: #333;
flex-shrink: 0;
overflow: hidden;
margin-bottom: 5px;
}
<div >
<div style="width: 1300px;">
<div data-id="0"></div>
<div data-id="1"></div>
<div data-id="2"></div>
<div data-id="3"></div>
<div data-id="4"></div>
<div data-id="5"></div>
<div data-id="6"></div>
<div data-id="7"></div>
<div data-id="8"></div>
<div data-id="9"></div>
<div data-id="10"></div>
<div data-id="11"></div>
</div>
</div>
CodePudding user response:
Declare the variable moved
. In the dragStartThumb
function set this variable to false, and in the dragMoveThumb
function set it to true and in the onclick
event check this variable. Like below.
Something like @Amirhoseinh73 wrote, but instead of setting the flag to true in the touchend
function we set the flag to true in the mousemove
function, because we don't want have always variable set to true.
var thumbContainer = document.querySelector('.aplbox-thumb-container'),
thumbContainerWrap = document.querySelector('.aplbox-thumb-container-wrap'),
startXThumb,
startTouchThumb
let moved = false;
if ("ontouchstart" in window) {
thumbContainer.addEventListener("touchstart", dragStartThumb);
}
thumbContainer.addEventListener("mousedown", dragStartThumb);
function dragStartThumb(e) {
moved = false;
//if (e.preventDefault) e.preventDefault();
e.stopPropagation()
if (!startTouchThumb) {
startTouchThumb = true;
document.addEventListener('mousemove', dragMoveThumb)
document.addEventListener('mouseup', dragEndThumb);
if ("ontouchstart" in window) {
document.addEventListener('touchmove', dragMoveThumb)
document.addEventListener('touchend', dragEndThumb);
}
var point;
if (e.type == 'touchstart') {
var touches = e.changedTouches;
if (touches.length > 1) {
return false;
}
point = touches[0];
//e.preventDefault();
} else {
point = e;
//e.preventDefault();
}
var currX = thumbContainer.style.transform.replace(/[^\d.]/g, '');
currX = parseInt(currX) || 0;
startXThumb = point.pageX currX;
}
}
function dragMoveThumb(e) {
moved = true;
if (startTouchThumb) {
var point;
if (e.type == 'touchmove') {
var touches = e.changedTouches;
if (touches.length > 1) {
return false;
}
point = touches[0];
e.preventDefault();
} else {
point = e;
e.preventDefault();
}
var diff = point.pageX - startXThumb;
if (diff > 0) diff = 0;
else if (diff < -thumbContainer.offsetWidth thumbContainerWrap.offsetWidth) diff = -thumbContainer.offsetWidth thumbContainerWrap.offsetWidth;
thumbContainer.style.transform = 'translateX(' diff 'px)';
}
}
function dragEndThumb(e) {
e.stopPropagation()
if (startTouchThumb) {
startTouchThumb = false;
document.removeEventListener('mousemove', dragMoveThumb)
document.removeEventListener('mouseup', dragEndThumb);
if ("ontouchstart" in window) {
document.removeEventListener('touchmove', dragMoveThumb)
document.removeEventListener('touchend', dragEndThumb);
}
}
}
//click thumb
thumbContainerWrap.addEventListener('click', function(e) {
if (e.target.closest('.aplbox-thumb') && !moved) {
console.log('click')
}
})
.aplbox-thumb-container-wrap {
position: absolute;
top: 0;
left: 0;
background-color: #ccc;
width: 100%;
height: 100px;
overflow: hidden;
box-sizing: border-box;
}
.aplbox-thumb-container {
position: relative;
padding: 5px 0;
height: 100%;
display: flex;
flex-direction: row;
transform: translateX(0);
touch-action: none;
}
.aplbox-thumb {
width: 100px;
height: 70px;
margin-right: 5px;
box-sizing: border-box;
background: #333;
flex-shrink: 0;
overflow: hidden;
margin-bottom: 5px;
}
<div >
<div style="width: 1300px;">
<div data-id="0"></div>
<div data-id="1"></div>
<div data-id="2"></div>
<div data-id="3"></div>
<div data-id="4"></div>
<div data-id="5"></div>
<div data-id="6"></div>
<div data-id="7"></div>
<div data-id="8"></div>
<div data-id="9"></div>
<div data-id="10"></div>
<div data-id="11"></div>
</div>
</div>