i have a draggable parent with click events on the children. i want to cancel/abort/stop the click event of the child when it's starting to get dragged, but also don't want do stop any parent events. Since i don't use a lot of jQuery, i'd be very thankful for a vanilla javascript solution.
sorry for this newbie question, but i can't wrap my head around it.
here is what i got so far: JSFiddle
// horizontal drag scroll for items
const itemScroll = document.querySelector('#itemScroll');
var isDown = false;
var startX;
var scrollLeft;
itemScroll.addEventListener('mousedown', (e) => {
isDown = true;
itemScroll.classList.add('active');
startX = e.pageX - itemScroll.offsetLeft;
scrollLeft = itemScroll.scrollLeft;
});
itemScroll.addEventListener('mouseleave', () => {
isDown = false;
itemScroll.classList.remove('active');
});
itemScroll.addEventListener('mouseup', () => {
isDown = false;
itemScroll.classList.remove('active');
});
itemScroll.addEventListener('mousemove', (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - itemScroll.offsetLeft;
itemScroll.scrollLeft = scrollLeft - (x - startX);
});
// click an item to change bg-color
const items = document.querySelectorAll('.item');
for (var i = 0; i < items.length; i++) {
items[i].addEventListener('click', function (e) {
this.classList.toggle('active');
});
}
Detect movement and in that case "prevent" the default click behaviour programmatically using a global variable. We reset the is_moved
variable when mousedown, and set it when mousemove.
// horizontal drag scroll for items
const itemScroll = document.querySelector('#itemScroll');
var isDown = false;
var startX;
var scrollLeft;
var isMoved = false;
itemScroll.addEventListener('mousedown', (e) => {
isDown = true;
isMoved = false;
itemScroll.classList.add('active');
startX = e.pageX - itemScroll.offsetLeft;
scrollLeft = itemScroll.scrollLeft;
});
itemScroll.addEventListener('mouseleave', () => {
isDown = false;
itemScroll.classList.remove('active');
});
itemScroll.addEventListener('mouseup', () => {
isDown = false;
itemScroll.classList.remove('active');
});
itemScroll.addEventListener('mousemove', (e) => {
if (!isDown) return;
isMoved = true;
e.preventDefault();
const x = e.pageX - itemScroll.offsetLeft;
itemScroll.scrollLeft = scrollLeft - (x - startX);
});
// click an item to change bg-color
const items = document.querySelectorAll('.item');
for (var i = 0; i < items.length; i++) {
items[i].addEventListener('click', function(e) {
if (!isMoved) {
this.classList.toggle('active');
}
});
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.mainCont {
width: 100%;
max-width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
scroll-snap-align: center;
}
#itemScroll {
cursor: pointer;
overflow-x: hidden;
}
#itemScroll.active {
cursor: grabbing;
}
.itemRow {
width: max-content;
min-width: 100%;
height: 100%;
max-height: 400px;
padding: 0 5vw;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 5rem;
transform-style: preserve-3d;
}
.item {
width: 100px;
height: 100px;
max-width: 400px;
max-height: 100%;
background-color: red;
}
.item.active {
background-color: green;
}
<div class="mainCont" id="itemScroll">
<div class="itemRow">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>