Fix SlimSelect scroll chaining in sticky event filter
This commit is contained in:
@@ -81,6 +81,11 @@
|
|||||||
#eventfilters .eventfilter-reset[hidden] {
|
#eventfilters .eventfilter-reset[hidden] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#eventfilters .ss-content,
|
||||||
|
#eventfilters .ss-list {
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/slim-select@3/dist/slimselect.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/slim-select@3/dist/slimselect.css">
|
||||||
@@ -332,5 +337,74 @@
|
|||||||
applyFilter({ type: 'all', value: 'all' });
|
applyFilter({ type: 'all', value: 'all' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getDropdownFromTarget = (target) => {
|
||||||
|
if (!(target instanceof Element)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target.closest('#eventfilters .ss-content, #eventfilters .ss-list');
|
||||||
|
};
|
||||||
|
|
||||||
|
const shouldBlockBoundaryScroll = (dropdown, delta) => {
|
||||||
|
if (!dropdown || dropdown.scrollHeight <= dropdown.clientHeight) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const top = dropdown.scrollTop;
|
||||||
|
const height = dropdown.clientHeight;
|
||||||
|
const scrollHeight = dropdown.scrollHeight;
|
||||||
|
|
||||||
|
const atTop = top <= 0;
|
||||||
|
const atBottom = top + height >= scrollHeight - 1;
|
||||||
|
|
||||||
|
return (atTop && delta < 0) || (atBottom && delta > 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
let lastTouchY = null;
|
||||||
|
|
||||||
|
document.addEventListener('wheel', (event) => {
|
||||||
|
const dropdown = getDropdownFromTarget(event.target);
|
||||||
|
|
||||||
|
if (shouldBlockBoundaryScroll(dropdown, event.deltaY)) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}, { passive: false, capture: true });
|
||||||
|
|
||||||
|
document.addEventListener('touchstart', (event) => {
|
||||||
|
const dropdown = getDropdownFromTarget(event.target);
|
||||||
|
|
||||||
|
if (!dropdown || event.touches.length === 0) {
|
||||||
|
lastTouchY = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTouchY = event.touches[0].clientY;
|
||||||
|
}, { passive: true, capture: true });
|
||||||
|
|
||||||
|
document.addEventListener('touchmove', (event) => {
|
||||||
|
const dropdown = getDropdownFromTarget(event.target);
|
||||||
|
|
||||||
|
if (!dropdown || event.touches.length === 0 || lastTouchY === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentTouchY = event.touches[0].clientY;
|
||||||
|
const delta = lastTouchY - currentTouchY;
|
||||||
|
|
||||||
|
if (shouldBlockBoundaryScroll(dropdown, delta)) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTouchY = currentTouchY;
|
||||||
|
}, { passive: false, capture: true });
|
||||||
|
|
||||||
|
document.addEventListener('touchend', () => {
|
||||||
|
lastTouchY = null;
|
||||||
|
}, { passive: true, capture: true });
|
||||||
|
|
||||||
|
document.addEventListener('touchcancel', () => {
|
||||||
|
lastTouchY = null;
|
||||||
|
}, { passive: true, capture: true });
|
||||||
|
|
||||||
applyFilter(currentFilter);
|
applyFilter(currentFilter);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user