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
JavaScript
x
36
36
1
// horizontal drag scroll for items
2
const itemScroll = document.querySelector('#itemScroll');
3
var isDown = false;
4
var startX;
5
var scrollLeft;
6
7
itemScroll.addEventListener('mousedown', (e) => {
8
isDown = true;
9
itemScroll.classList.add('active');
10
startX = e.pageX - itemScroll.offsetLeft;
11
scrollLeft = itemScroll.scrollLeft;
12
});
13
itemScroll.addEventListener('mouseleave', () => {
14
isDown = false;
15
itemScroll.classList.remove('active');
16
});
17
itemScroll.addEventListener('mouseup', () => {
18
isDown = false;
19
itemScroll.classList.remove('active');
20
});
21
itemScroll.addEventListener('mousemove', (e) => {
22
if (!isDown) return;
23
e.preventDefault();
24
const x = e.pageX - itemScroll.offsetLeft;
25
itemScroll.scrollLeft = scrollLeft - (x - startX);
26
});
27
28
// click an item to change bg-color
29
const items = document.querySelectorAll('.item');
30
31
for (var i = 0; i < items.length; i++) {
32
items[i].addEventListener('click', function (e) {
33
this.classList.toggle('active');
34
});
35
}
36
Advertisement
Answer
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.
JavaScript
1
40
40
1
// horizontal drag scroll for items
2
const itemScroll = document.querySelector('#itemScroll');
3
var isDown = false;
4
var startX;
5
var scrollLeft;
6
var isMoved = false;
7
8
itemScroll.addEventListener('mousedown', (e) => {
9
isDown = true;
10
isMoved = false;
11
itemScroll.classList.add('active');
12
startX = e.pageX - itemScroll.offsetLeft;
13
scrollLeft = itemScroll.scrollLeft;
14
});
15
itemScroll.addEventListener('mouseleave', () => {
16
isDown = false;
17
itemScroll.classList.remove('active');
18
});
19
itemScroll.addEventListener('mouseup', () => {
20
isDown = false;
21
itemScroll.classList.remove('active');
22
});
23
itemScroll.addEventListener('mousemove', (e) => {
24
if (!isDown) return;
25
isMoved = true;
26
e.preventDefault();
27
const x = e.pageX - itemScroll.offsetLeft;
28
itemScroll.scrollLeft = scrollLeft - (x - startX);
29
});
30
31
// click an item to change bg-color
32
const items = document.querySelectorAll('.item');
33
34
for (var i = 0; i < items.length; i++) {
35
items[i].addEventListener('click', function(e) {
36
if (!isMoved) {
37
this.classList.toggle('active');
38
}
39
});
40
}
JavaScript
1
51
51
1
* {
2
box-sizing: border-box;
3
margin: 0;
4
padding: 0;
5
}
6
7
.mainCont {
8
width: 100%;
9
max-width: 100vw;
10
height: 100vh;
11
display: flex;
12
flex-direction: column;
13
align-items: flex-start;
14
justify-content: center;
15
scroll-snap-align: center;
16
}
17
18
#itemScroll {
19
cursor: pointer;
20
overflow-x: hidden;
21
}
22
23
#itemScroll.active {
24
cursor: grabbing;
25
}
26
27
.itemRow {
28
width: max-content;
29
min-width: 100%;
30
height: 100%;
31
max-height: 400px;
32
padding: 0 5vw;
33
display: flex;
34
flex-direction: row;
35
align-items: center;
36
justify-content: center;
37
gap: 5rem;
38
transform-style: preserve-3d;
39
}
40
41
.item {
42
width: 100px;
43
height: 100px;
44
max-width: 400px;
45
max-height: 100%;
46
background-color: red;
47
}
48
49
.item.active {
50
background-color: green;
51
}
JavaScript
1
13
13
1
<div class="mainCont" id="itemScroll">
2
<div class="itemRow">
3
<div class="item"></div>
4
<div class="item"></div>
5
<div class="item"></div>
6
<div class="item"></div>
7
<div class="item"></div>
8
<div class="item"></div>
9
<div class="item"></div>
10
<div class="item"></div>
11
<div class="item"></div>
12
</div>
13
</div>