【问题标题】:CSS scroll-snap-type with Horizontal ScrollingCSS scroll-snap-type 与水平滚动
【发布时间】:2020-06-08 18:49:03
【问题描述】:

我创建了一个使用 Bootstrap 4、水平滚动(通过jquery.mousewheel.js)和原生 CSS Snapping 的网站。我使用的是 Chrome 81,不关心旧的/不受支持的浏览器。

当我将scroll-snap-type: x mandatory; 应用于 CSS 时,水平滚动停止工作(根本不发生滚动)。如果 CSS 属性被移除,则滚动行为正常。这是我的 HTML 结构:

<div class="portfolio_content container-fluid h-100">
  <div class="row h-100 flex-row flex-nowrap scrollx long_content">
    <div class="col-12 h-100 project d-table" id="project1">
      <div class="project_title d-table-cell align-middle">
        <p>
          Project 1
        </p>
      </div>
    </div>
    <div class="col-12 h-100 project d-table" id="project2">
      <div class="project_title d-table-cell align-middle">
        <p>
          Project 2
        </p>
      </div>
    </div>
    <div class="col-12 h-100 project d-table" id="project3">
      <div class="project_title d-table-cell align-middle">
        <p>
          Project 3
        </p>
      </div>
    </div>
    <div class="col-12 h-100 project d-table" id="project4">
      <div class="project_title d-table-cell align-middle">
        <p>
          Project 4
        </p>
      </div>
    </div>
  </div>
</div>

对于 CSS,关键条目在这里:

html, body {
    height: 100%;
}
.portfolio_content .scrollx {
    overflow-x: scroll;
}

.portfolio_content .long_content {
    scroll-snap-type: x mandatory; /* Comment this to make scrolling works */
}
.portfolio_content .project {
    scroll-snap-align: start;
}
.portfolio_content .project_title {
    display: block;
    margin: auto;
    text-align: center;
}
.portfolio_content .project_title h1 {
    font-size: 96px;
    line-height: 0.8;
}

最后,这里是JSFiddle demo。如果您在 CSS 中注释第 9 行,则演示将能够滚动。

我的目标是让“项目”DIV 在滚动时被捕捉,即滚动后将完全显示一个“项目”DIV。

我应该如何更改代码?

【问题讨论】:

  • 您是否注意到text-align: center 规则正在阻止您的.project_title 中的文本显示?
  • 但这与滚动无关。
  • 也许不是直接的,但我删除了 scroll-snap-type 属性,它仍然没有滚动,所以看起来你的 CSS 存在问题,在你担心之前你需要解决滚动捕捉。
  • 即使我注释掉了text-align: center,情况也没有任何改变。 CSS 属性仅用于说明目的,与问题无关。
  • 不要使用任何鼠标滚轮 js 库,它们在 99..9% 中都是像你这样的问题的原因。

标签: jquery css scroll-snap-type


【解决方案1】:

如果你可以用一个简单的脚本来做,你就不需要外部插件了。

$(".portfolio_content .project").on('wheel', function(e) {
    e.preventDefault();        
    if (e.originalEvent.wheelDelta >= 0) {
        if ($(this).prev().length) {
            var prev = "#" + $(this).prev().attr("id");
            document.querySelector(prev).scrollIntoView({behavior: 'smooth'});
        }
    } else {
        if ($(this).next().length) {
            var next = "#" + $(this).next().attr("id");
            document.querySelector(next).scrollIntoView({behavior: 'smooth'});
        }
    }
});
html, body {
    height: 100%;
}
.portfolio_content .scrollx {
    overflow-x: scroll;
}

.portfolio_content .project {
	scroll-snap-align: start;
}
.portfolio_content .project_title {
	display: block;
	margin: auto;
	text-align: center;
}
.portfolio_content .project_title h1 {
	font-size: 96px;
	line-height: 0.8;
}
#project1, #project3 {
    background-color: #EEE;
}
#project2, #project4 {
    background-color: #CCC;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

<div class="portfolio_content container-fluid h-100">
  <div class="row h-100 flex-row flex-nowrap scrollx long_content">
    <div class="col-12 h-100 project d-table" id="project1">
      <div class="project_title d-table-cell align-middle">
        <p>
          Project 1
        </p>
      </div>
    </div>
    <div class="col-12 h-100 project d-table" id="project2">
      <div class="project_title d-table-cell align-middle">
        <p>
          Project 2
        </p>
      </div>
    </div>
    <div class="col-12 h-100 project d-table" id="project3">
      <div class="project_title d-table-cell align-middle">
        <p>
          Project 3
        </p>
      </div>
    </div>
    <div class="col-12 h-100 project d-table" id="project4">
      <div class="project_title d-table-cell align-middle">
        <p>
          Project 4
        </p>
      </div>
    </div>
  </div>
</div>

【讨论】:

  • 脚本不工作。它不会将垂直滚动转换为水平滚动。
  • 在我的小提琴中,如果您垂直滚动,DIV 内容将水平滚动。但是在您的代码 sn-p 中,没有这样的功能。我必须自己水平滚动。
  • 你用的是什么浏览器?因为我的 sn-p 在所有 Chromiums 浏览器中都可以很好地解决您的问题。在 Firefox 上看起来完全不同,这不是我的错,我复制了你分享的代码。
  • 我使用的是最新的 Chrome。您尝试运行代码 sn-p 并单击完整页面。已经失控了。
【解决方案2】:

简答:去掉javascript代码。

长答案:mousewheel.js 如果您想检查车轮事件或对车轮事件做某事,这很有用。在这种情况下,您只想让浏览器滚动。您正在函数中控制该事件并阻止默认操作,但默认操作正是您想要的。

当您执行this.scrollLeft -= delta; 时,它会做两件事:scroll,然后是end scrollscroll-snap-type 监听 end scroll 并捕捉元素。实际上,如果你只去掉e.preventDefault(); 行,就会发生一件有趣的事情。元件振动然后变化。据我了解,正在发生的事情是:1)默认滚动事件,这需要一些时间。同时,2)wheel 事件,它触发了一个更短的滚动事件。 3)快照。由于 2 中的 deltaX 很小,因此您可以到达起始位置。重复 2 和 3 几次。 4) 默认滚动事件以更大的deltaX 结束。 5) 捕捉。

总而言之,对于您想要的行为,最好让浏览器进行滚动。如果您想做其他事情,则需要避免在每次触发mousewheel 事件时发送end scroll 信号。为此,您可以简单地消除鼠标滚轮函数中的两行代码,然后添加您需要的代码。

评论后编辑:

我应该已经猜到了,你想将 vertical 轮子事件转换为水平轮子事件。如果您发送水平滚轮事件(您可以使用触摸板执行此操作),则前一个答案有效。长答案仍然存在,所以问题是如何绕过这个问题。我想到了几个策略:

  • 取消事件并创建合成WheelEvent。迄今为止最优雅的解决方案,但我无法使其工作。事件被调度,但没有发生滚动:
 let lc = document.querySelector('.long_content');
 lc.addEventListener('wheel', function(e) {
   if (e.deltaY !== 0){
     e.preventDefault();
     let evt = new WheelEvent('wheel', {
       deltaX: e.deltaY
     });
     this.dispatchEvent(evt);
   }
   else{
     // The new event gets captured here
   }
  });

编辑 2

有许多策略可以使这项工作发挥作用,但它们都有其缺点。前一个对您的脚本影响很小,但更改是在轮子事件结束后开始的。此参数和其他参数留给浏览器,不受您的控制。

我添加了另一个策略,它提供了您似乎想要的行为 (https://jsfiddle.net/vhywmdb5/)。我希望它有所帮助,但每个解决方案都需要调整,并且不能保证它适用于每个浏览器。不幸的是,mousewheel.js 中的事件模拟此时已损坏。

【讨论】:

  • 但是我必须将垂直滚动更改为水平滚动,因此我必须使用JS代码。任何替代解决方案?
  • 我已经更新了答案。也许小提琴对你有用。
  • 感谢您的更新。 Fiddle 在滚动时看起来很迟钝,尤其是当我向上滚动时(使内容向左滚动)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 2021-02-11
  • 2022-01-11
  • 2011-06-25
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多