Reputation: 4789
You can horizontally scroll my demo page by pressing Space Bar, Page Up / Page Down and Left Arrow / Right Arrow keys. You can also snap scroll with a mouse or trackpad.
But only one or the other works.
Is there a way that keyboard events and CSS scroll snapping can coexist? What am I missing? Any help would be really appreciated, since I’ve been struggling with this problem for over a week.
(Please uncomment the relevant piece of CSS code to enable the scroll snapping effect in order to see that keyboard shortcuts stop working.)
import animate from "https://cdn.jsdelivr.net/npm/animateplus@2/animateplus.js"
const sections = Array.from(document.querySelectorAll("section")).sort(
(s1, s2) => {
return s1.getBoundingClientRect().left - s2.getBoundingClientRect().left
}
)
const getSectionInView = () => {
const halfWidth = window.innerWidth / 2
const index = sections.findIndex(
section =>
section.getBoundingClientRect().left <= halfWidth &&
section.getBoundingClientRect().right > halfWidth
)
return index
}
const getNextSection = dir => {
const sectionInViewIndex = getSectionInView()
const nextIndex = sectionInViewIndex + dir
const numSections = sections.length
const nextSectionIndex =
nextIndex < 0 || nextIndex >= numSections ? sectionInViewIndex : nextIndex
return sections[nextSectionIndex]
}
const container = document.scrollingElement
const animateScroll = dir => {
const from = container.scrollLeft
const { left } = getNextSection(dir).getBoundingClientRect()
return progress => (container.scrollLeft = from + progress * left)
}
window.onload = () => {
document.body.onkeydown = event => {
switch (event.key) {
case " ": // Space Bar
case "PageDown":
case "ArrowRight": {
animate({
easing: "out-quintic",
change: animateScroll(1)
})
break
}
case "PageUp":
case "ArrowLeft": {
animate({
easing: "out-quintic",
change: animateScroll(-1)
})
break
}
}
}
}
Note: I’m using a small and elegant module called Animate Plus for achieving the smooth scrolling animation.
Update: @Kostja’s solution works in Chrome, but not in Safari for Mac or iOS, and it’s crucial to me that it works in Safari.
Upvotes: 13
Views: 1331
Reputation: 355
I guess there is not, the css overwrites the javascript. But you can simply add wheel eventlistener like:
window.addEventListener("wheel", function() {
if(event.deltaY > 0){
animate({
easing: "out-quintic",
change: animateScroll(1)
})
}
if(event.deltaY < 0){
animate({
easing: "out-quintic",
change: animateScroll(-1)
})
}
});
https://codepen.io/kostjaaa/pen/NWWVBKd
Upvotes: 4
Reputation: 17
window.onload = () => {
window.addEventListener("wheel", () => {
const direction = event.deltaY > 0 ? 1 : event.deltaY < 0 ? -1 : false;
if (direction) {
animate({
easing: "out-quintic",
change: animateScroll(direction)
});
}
});
document.body.onkeydown = event => {
switch (event.key) {
case " ": // Space Bar
case "PageDown":
case "ArrowRight": {
animate({
easing: "out-quintic",
change: animateScroll(1)
});
break;
}
case "PageUp":
case "ArrowLeft": {
animate({
easing: "out-quintic",
change: animateScroll(-1)
});
break;
}
}
};
};
This should work.
https://codepen.io/JZ6/pen/XWWQqRK
Upvotes: 0