首页 > 解决方案 > 在垂直鼠标滚动上水平滑动

问题描述

如果鼠标在其上垂直滚动,我制作了一个水平滚动的滑块。

// move slider horizontally on vertical scroll
const target = document.querySelector('.slider')

target.addEventListener('wheel', event => {
  const toLeft  = event.deltaY < 0 && target.scrollLeft > 0
  const toRight = event.deltaY > 0 && target.scrollLeft < target.scrollWidth - target.clientWidth

  if (toLeft || toRight) {
    event.preventDefault()
    target.scrollLeft += event.deltaY
  } 
})
.box {
  background: #ccc;
  height: 800px;
}

.slider {
  border: 5px solid black;
  background: #fff;
  overflow-x: scroll;
}

.item-wrap {
  height: 1000px;
  display: flex;
}

.item {
  min-width: 240px;
  height: 240px;
  font-size: 140px;
  border: 2px solid #d1d1d1;
  border-radius: 5px;
  padding: 5px;
  margin: 5px;
  line-height: 1.6;
  text-align: center;
}

/* add classes */
.test {
  position: fixed;
}
<div class="box"></div>
<div class="slider">
  <div class="item-wrap">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
  </div>
</div>
<div class="box"></div>

从页面顶部向下滚动到滑块顶部时,我希望滑块保持固定,直到所有元素都滚动。当最后一项滚动时(在这种情况下9),我希望窗口继续滚动到页面底部。

然后当用户从页面底部滚动到滑块底部时,我希望滑块保持固定,直到所有元素都滚动。当最后一项滚动时(在这种情况下1),我希望窗口继续滚动直到页面顶部。

滚动到此链接上的页面底部显示我正在尝试模仿的内容。

我注意到他们一直在监听窗口滚动,直到滑块的顶部到达视口的顶部。然后滑块的位置为fixed。当用户从页面底部滚动到滚动条底部时的概念相同。

但我不确定如何实现动态fixed位置。

标签: javascripthtmlcss

解决方案


您需要使用css位置属性并JavaScript有条件地检查offsetTopscrollY幻灯片使用 csstranslate3d属性。 在计算每个滑块项目后,
将需要一个额外的 div(#pan)来动态定义高度。有用的链接:https ://www.w3schools.com/cssref/css3_pr_transform.asp注意:也检查一下total width


Full Page

我希望下面的代码片段对你有很大帮助。

window.onbeforeunload = function () {
    window.scrollTo(0, 0);
}

window.onload = function() {
    var wh = window.innerHeight;
    var ww = window.innerWidth;
    var slider = document.getElementById('slider');
    var pan = document.getElementById('pan');
    var item_wrap = document.getElementById('item_wrap').scrollWidth + wh/1.25;
    pan.style.height = item_wrap + 'px';

    window.addEventListener('scroll', function (event) {
        if (event.path[1].scrollY >= slider.offsetTop ) {
            if (event.path[1].scrollY < pan.offsetTop + pan.clientHeight) {
                slider.style.position = 'fixed'; //set position fixed
                let aa = event.path[1].scrollY - pan.offsetTop;
                document.getElementById('item_wrap').style.transform = 'translate3d(-' + aa + 'px, 0px, 0px)';   
            }
        }
        if (event.path[1].scrollY <= pan.offsetTop) {
            slider.style.position = 'relative'; //set position relative
        }
    });
}
*{box-sizing: border-box;}
body{
    font-size: Arial;
    padding: 0;
    margin: 0;
}
.box {
    background: #ccc;
    height: 100vh;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #fff;
    font-size: 10vw;
}

.slider {
    background: #fff;
    width: 100%;
    min-height: 100vh;
    padding: 10px 0;
    top: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.item-wrap {
    display: flex;
    background: #fff;
    width: 100%;
    position: relative;
    transition: 0.5s cubic-bezier(0.05, 0.82, 0.165, 1);
}
.item {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    min-width: 240px;
    width: 240px;
    height: 240px;
    font-size: 800%;
    border: 2px solid #d1d1d1;
    border-radius: 5px;
    padding: 5px;
    margin: 5px;
    line-height: 1;
}
.bg-tomato{
    background-color: tomato;
}
.bg-teal{
    background-color: teal;
}
.bg-thistle{
    background-color: thistle;
}
.bg-violet{
    background-color: violet;
}
<div class="box bg-tomato">Box - #1</div>
<div class="box bg-thistle">Box - #2</div>
<div class="slider" id="slider">
    <h2>Box - #3 (Slider)</h2>
    <div class="item-wrap" id="item_wrap">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
        <div class="item">6</div>
        <div class="item">7</div>
        <div class="item">8</div>
        <div class="item">9</div>
        <div class="item">10</div>
        <div class="item">11</div>
        <div class="item">12</div>
        <div class="item">13</div>
    </div>
</div>
<div id="pan"></div>

<div class="box bg-teal">Box - #4</div>
<div class="box bg-violet">Box - #5</div>


推荐阅读