skip to Main Content

Please watch the video to see the strange behavior of the script and how it interacts with the stylesheet, you can recreate the bug with the codepen. I’m not sure whats causing the glitch. I added a timeout in the code of 400ms, which was intended to stop users from accidentally triggering the scroll in both directions at once. It is intended to function by allowing users to scroll to the next element only once the current element is in view.

When scroll-snap is disabled, the scrollBy function does not work, only moving slightly (instead of the full window.innerWidth)

Video of bug

Link to CodePen

var waiting

if (waiting == null) {
        waiting = 0      
    }

  document.querySelector(".main-nav").addEventListener("wheel", (event) => {
    event.preventDefault();                   
    if (waiting === 0) {
        waiting = 1 
        console.log("started wait");
        if (event.deltaY > 0) {
                scrlFF();
                setTimeout(finishedWaiting, 400);
        } else if (event.deltaY < 0) {                         
                scrlFR();
                setTimeout(finishedWaiting, 400);
        } 
    }
});
    function finishedWaiting() { console.log("finished wait"); waiting = 0 }
    function scrlFF() { document.querySelector(".main-nav").scrollBy({ left: window.innerWidth, behavior: 'smooth' }); }
    function scrlFR() { document.querySelector(".main-nav").scrollBy({ left: -window.innerWidth, behavior: 'smooth' }); }
.a { background: red;
min-width: 100vw; height: 100vh; display: flex; scroll-snap-align: center; scroll-snap-stop: always;}
.a ~ .a { background: blue;}
.a ~ .a ~ .a { background: red;}
.a ~ .a ~ .a ~ .a { background: blue;}
* { overflow-y: hidden }
.main-nav {display: flex;flex-direction: row;height: 100%;scroll-snap-type: x mandatory;overflow-x: scroll;scroll-behavior: smooth;scrollbar-width: none;width: inherit;}
<div class="main-nav"><div class="a"></div><div class="a"></div><div class="a"></div><div class="a"></div></div>

2

Answers


  1. Chosen as BEST ANSWER

    While the snippet embedded seems to function smoothly on stackoverflow with adding "html, body" in querySelector for the event listener, the same code does not function properly on codepen or my website?

      document.querySelector("html, body, .main-nav").addEventListener("wheel", (event) => {
    

    var waiting
    
    if (waiting == null) {
            waiting = 0      
        }
    
      document.querySelector("html, body, .main-nav").addEventListener("wheel", (event) => {
        event.preventDefault();                   
        if (waiting === 0) {
            waiting = 1 
            if (event.deltaY > 0) {
                    scrlFF();
                    setTimeout(finishedWaiting, 400);
            } else if (event.deltaY < 0) {                         
                    scrlFR();
                    setTimeout(finishedWaiting, 400);
            } 
        }
    });
        function finishedWaiting() { waiting = 0 }
        function scrlFF() { document.querySelector(".main-nav").scrollBy({ left: window.innerWidth, behavior: 'smooth' }); }
        function scrlFR() { document.querySelector(".main-nav").scrollBy({ left: -window.innerWidth, behavior: 'smooth' }); }
    .a { background: red;
    min-width: 100vw; height: 100vh; display: flex; scroll-snap-align: center; scroll-snap-stop: always;}
    .a ~ .a { background: blue;}
    .a ~ .a ~ .a { background: red;}
    .a ~ .a ~ .a ~ .a { background: blue;}
    * { overflow-y: hidden }
    .main-nav {display: flex;flex-direction: row;height: 100%;scroll-snap-type: x mandatory;overflow-x: scroll;scroll-behavior: smooth;scrollbar-width: none;width: inherit;}
    <div class="main-nav"><div class="a"></div><div class="a"></div><div class="a"></div><div class="a"></div></div>


  2. I’m not marking this question resolved yet, because I still don’t understand what is causing the issue.
    However, I was able to find a working but less than ideal solution for codepen and my website.

    CSS:

    .main-nav { pointer-events:var(--handlePointer) }
    

    Javascript:

    function finishedWaiting() { console.log("finished wait"); document.querySelector(':root').style.setProperty('--handlePointer', "all"); waiting = 0 }
    function scrlFF() { document.querySelector(':root').style.setProperty('--handlePointer', "none"); document.querySelector(".main-nav").scrollBy({ left: window.innerWidth, behavior: 'smooth' }); }
    function scrlFR() { document.querySelector(':root').style.setProperty('--handlePointer', "none"); document.querySelector(".main-nav").scrollBy({ left: -window.innerWidth, behavior: 'smooth' }); }
    

    For some reason, adding pointer-events:none; during the scroll fixed the glitching. I added a css variable to control the property of pointer-events in the function so it reverts back to pointer-events:all; when the delay finishes.

    When you are hovering over the child element .a (or any child) inside .main-nav, scrolling does not work properly. It fails to scroll to the next position and produces the glitching shown in the video unless pointer-events has property none

    If anyone has an explanation for what’s actually going on, I appreciate any advice?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search