CSS 部分滚动对齐

Dan*_*ith 6 html javascript css scroll scroll-snap

一直在尝试滚动捕捉,看起来用 JS 编写功能可以省去很多麻烦。

这是一个挑战,有没有人找到一种方法来选择性地选择要捕捉哪些子项以及要自由滚动哪些子项?

我认为这对于内容丰富的页面非常有用,这些页面包含无法从滚动捕捉中受益的部分。

这是问题的示例: https://codepen.io/nodelondon/pen/YzxWqLG

html {
  background: #f2f2f2;
}

.scroll-container,
.scroll-area-none,
.scroll-area {
  max-width: 850px;
  height: 600px;
  font-size: 60px;
}

.scroll-area-none {
  scroll-snap-align: none;
  background-color: black;
}

.scroll-container {
  overflow: auto;
  scroll-snap-type: y mandatory;
}

.scroll-area {
  scroll-snap-align: start;
}

.scroll-container,
.scroll-area-none,
.scroll-area {
  margin: 0 auto;
}

.scroll-area-none,
.scroll-area {
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.scroll-area:nth-of-type(4n+1) {
  background: #49b293;
}

.scroll-area:nth-of-type(4n+2) {
  background: #c94e4b;
}

.scroll-area:nth-of-type(4n+3) {
  background: #4cc1be;
}

.scroll-area:nth-of-type(4n+4) {
  background: #8360A6;
}
Run Code Online (Sandbox Code Playgroud)
<div class="support-scrollsnap"></div>

<div class="scroll-container">
  <div class="scroll-area-none">-1</div>
  <div class="scroll-area-none">0</div>
  <div class="scroll-area">1</div>
  <div class="scroll-area">2</div>
  <div class="scroll-area">3</div>
  <div class="scroll-area">4</div>
  <div class="scroll-area-none">5</div>
  <div class="scroll-area-none">6</div>
</div>
Run Code Online (Sandbox Code Playgroud)

理想情况下,带有 -1、0、5 和 6 的框应该能够自由滚动,但中间的强制框会不断将您拉回来。

如果您正在考虑建议将其更改为接近,这是一个很好的建议,但是,对于 IOS Safari(对我来说也是在 OSX Safari 上),不幸的是,它仍然强制滚动捕捉滚动捕捉对齐设置为无论您在页面上的哪个位置都可以开始。

Gle*_*sky -1

我提出以下逻辑:

  1. 定义哪个子块位于滚动容器的顶部边框。我正在使用Element.getBoundingClientRect()方法来比较滚动容器及其子容器的位置。
  2. 检查哪个scroll-snap-align属性有这个子块。
  3. scroll-snap-type将容器的属性设置为y proximityy mandatory
  4. scroll在桌面上处理该事件,在移动设备上,此事件在滚动结束时起作用,因此我们需要其他用于移动设备的东西(可能是jQuery Mobile)。

这是一个工作草案解决方案。但它需要优化和改进,例如滚动事件限制

https://codepen.io/glebkema/pen/zYdPqeY

let scrollContainers = document.getElementsByClassName('scroll-container');
for (let sc of scrollContainers) {
  sc.addEventListener('scroll', updateSnapType);
  sc.addEventListener('touchstart', updateSnapType);
}

function updateSnapType(event) {
  let parent = event.currentTarget;
  let parentRect = parent.getBoundingClientRect();
  for (let child of parent.children) {
    let childRect = child.getBoundingClientRect();
    if (childRect.top <= parentRect.top && parentRect.top < childRect.bottom) {
      let childStyle = window.getComputedStyle(child);
      let scrollSnapAlign = childStyle.getPropertyValue('scroll-snap-align');
      console.log(child.innerText, scrollSnapAlign);
      parent.style.scrollSnapType = "none" === scrollSnapAlign ? 'y proximity' : 'y mandatory';
      break;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)
html {
  background: #f2f2f2;
}

.scroll-container,
.scroll-area-none,
.scroll-area {
  height: 100px;
  font-size: 60px;
}

.scroll-container {
  max-width: 850px;
  margin: 15px auto;
  overflow: auto;
  scroll-snap-type: y mandatory;
}

.scroll-area {
  scroll-snap-align: start;
}

.scroll-area-none {
  scroll-snap-align: none;
  background-color: black;
}

.scroll-area-none,
.scroll-area {
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.scroll-area:nth-of-type(4n+1) {
  background: #49b293;
}

.scroll-area:nth-of-type(4n+2) {
  background: #c94e4b;
}

.scroll-area:nth-of-type(4n+3) {
  background: #4cc1be;
}

.scroll-area:nth-of-type(4n+4) {
  background: #8360A6;
}
Run Code Online (Sandbox Code Playgroud)
<div class="scroll-container">
  <div class="scroll-area-none">1. -1</div>
  <div class="scroll-area-none">1. 0</div>
  <div class="scroll-area">1. 1</div>
  <div class="scroll-area">1. 2</div>
  <div class="scroll-area">1. 3</div>
  <div class="scroll-area">1. 4</div>
  <div class="scroll-area-none">1. 5</div>
  <div class="scroll-area-none">1. 6</div>
</div>

<div class="scroll-container">
  <div class="scroll-area-none">2. -1</div>
  <div class="scroll-area-none">2. 0</div>
  <div class="scroll-area">2. 1</div>
  <div class="scroll-area">2. 2</div>
  <div class="scroll-area">2. 3</div>
  <div class="scroll-area">2. 4</div>
  <div class="scroll-area-none">2. 5</div>
  <div class="scroll-area-none">2. 6</div>
</div>
Run Code Online (Sandbox Code Playgroud)