html 如何在JS上将滚动轴从Y反转到X?

unguejic  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(130)

我有一个水平滚动的网站,我想把用户的Y滚动输入转换成X滚动。当使用触控板和在X轴上滚动时,该网站已经可以完美地工作,所以我只是希望它以相反的方式工作。谢谢你,谢谢
这就是我想讨论的问题,但我对这个问题很陌生,这可能是非常错误的:

<script>
        let invertedscroll = window.ScrollY;
            
        window.addEventListener('scroll', (scrollY) );
        
        function invertscroll (scrollY) {
            window.scrollY = window.scrollX;
        }
        </script>

字符串

mxg2im7a

mxg2im7a1#

另一种解决方案是在使用wheel事件滚动时将scrollLeft直接设置为<html>。不要忘记调用event.preventDefault()来阻止垂直滚动

document.documentElement.addEventListener('wheel', (event) => {
    event.preventDefault() // prevent vertical scroll
    document.documentElement.scrollLeft += event.deltaY
})
body {
  display: flex;
  margin: 0;
}
section {
  height: 150px;
  min-width: 50vw;
  background: blue;
}
section:nth-child(odd) {
  background: red;
}
<section></section>
<section></section>
<section></section>

更新

你的例子中有一个冲突,但原因是scroll-snap-type属性,它控制你用css的滚动行为。我认为它不适合水平滚动。此外,CSS和JS解决方案的组合控制滚动将是毛刺。所以最好的方法是在这里只使用JS。
保持scroll-snap行为的所有优点可能很棘手,最好的方法是使用一些滑块库。有很多这样的库,但您需要搜索一下才能找到合适的解决方案。
如果你想自己实现这个行为,你可以从类似的东西开始。但目前的例子只适用于鼠标滚轮,它需要大量的改进。
我使用scrollTo进行水平滚动,传递slideIndex乘以slide width。然后我设置isScrolling以防止滚动,直到smooth滚动完成。在requestAnimationFrame方法中,我检查当前滚动,直到它完成并重置isScrolling以允许下一次滚动

const scrollableContainer = document.getElementById("slider")

let slideIndex = 0
let lastSlideIndex = 5
let isScrolling = false

let expectedScrollLeft = 0

const checkScrollEnd = () => {
  // check if current scroll is finished
  if (scrollableContainer.scrollLeft !== expectedScrollLeft) {
    // if the scroll is not finished, run function again recursively
    window.requestAnimationFrame(checkScrollEnd)
  } else {
    // otherwise set isScrolling and allow next scroll to fire
    isScrolling = false
  }
}

scrollableContainer.addEventListener('wheel', (event) => {
  event.preventDefault()
  
  // do nothing until the previous scroll has finished
  if (isScrolling) return

  // check scroll direction and find next slide index
  if (event.deltaY > 0) {
    ++slideIndex
  } else {
    --slideIndex
  }
  
  // some cecks to avoid setting slideIndex less than 0 or more than slides count
  if (slideIndex > lastSlideIndex) {
    slideIndex = lastSlideIndex
    return
  }
  if (slideIndex < 0) {
    slideIndex = 0
    return
  }

  // set isScrolling to prevent excess triggering
  isScrolling = true
  
  // expectedScrollLeftis used to check when current scrolling is finished
    expectedScrollLeft = slideIndex * window.innerWidth

  scrollableContainer.scrollTo({
    top: 0,
    left: slideIndex * window.innerWidth,
    behavior: 'smooth',
  })
  
  // requestAnimationFrame is checking for scroll ending of every frame
  window.requestAnimationFrame(checkScrollEnd)
})
body {
  margin: 0;
}

#slider {
  max-width: 100%;
  display: flex;
  margin: 0;
  overflow-x: hidden;
}

.slide {
  height: 150px;
  min-width: 100vw;
  background: blue;
}

.slide:nth-child(odd) {
  background: red;
}
<div id="slider">
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
</div>
pexxcrt2

pexxcrt22#

使用window.scrollTo和invertScroll代替在你的实现中未定义的“scrollY”:

<script>
    window.addEventListener('scroll', invertScroll);

    function invertScroll(event) {
      event.preventDefault();
      window.scrollTo(window.scrollY, 0);
    }
</script>

字符串

相关问题