CSS Scroll-Snap API?

时间:2019-02-21 00:57:07

标签: javascript css dom-events

我很好奇... CSS滚动快照属性是否具有可通过JavaScript挂接的API(事件)?

我正在考虑创建一个网站,该网站使用滚动快照在100vh的“幻灯片”之间移动。完成每张幻灯片的“滚动捕捉”后,我想触发一个动画。

我敢肯定,我可以通过巧妙的方法检查每个“幻灯片”,以查看它是否占据了100%的视口,但那很烂。滚动事件完成后最好触发一个函数。

这是一个非常简单的示例:

$(document).ready(function() {
  let slideNumber = $('.container > .slide').length;
  if (slideNumber > 0) {
    $('.container > .slide').each(function() {
      $('#dotNav').append('<li><a href="#slide' + $(this).index() + '"></a></li>');
    });
  }

  //DO SOMETHING AFTER SCROLL-SNAP IS COMPLETE. 
});
html {
  scroll-behavior: smooth;
}

body {
  box-sizing: border-box;
  scroll-snap-type: y mandatory;
}

.container {
  width: 100%;
  scroll-snap-type: y mandatory;
  position: relative;
  .slide {
    height: 100vh;
    width: 100%;
    background: #cccccc;
    scroll-snap-align: center;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #000000;
    &:nth-child(odd) {
      background: blue;
      h2 {
        color: #ffffff;
      }
    }
    h2 {
      margin: 0;
      font-size: 40px;
      text-transform: uppercase;
    }
  }
  ul#dotNav {
    position: fixed;
    top: 50%;
    right: 20px;
    list-style: none;
    li {
      width: 20px;
      height: 20px;
      margin-bottom: 10px;
      cursor: pointer;
      a {
        display: block;
        width: 100%;
        height: 100%;
        background: #ffffff;
        border-radius: 50%;
      }
    }
    li.active {
      background: #000000;
    }
  }
}
<div class="container">
  <div class="slide" id="slide0">
    <h2>Slide 1</h2>
  </div>
  <div class="slide" id="slide1">
    <h2>Slide 2</h2>
  </div>
  <div class="slide" id="slide2">
    <h2>Slide 3</h2>
  </div>
  <ul id="dotNav">
  </ul>
</div>

您可以在这里看到它的工作状态

https://codepen.io/trafficdaddy/pen/BMGBBg

希望外面有人回答! :)

1 个答案:

答案 0 :(得分:0)

我在这个例子中监听了滚动事件: https://codepen.io/joosts/pen/MWJBPgo?editors=0010

const setSelected = function() {
    bullets.forEach(function(bullet) {
       bullet.classList.remove('selected');
    });
    let nthchild = (Math.round(ele.scrollLeft/carousel.scrollWidth)+1);
    carousel.querySelector('ol li:nth-child('+nthchild+')').classList.add('selected'); 
}

// Attach the handlers
ele.addEventListener("scroll", setSelected);

Onscroll 我计算了“当前孩子”(nthchild)并在它的项目符号中添加了一个“活动”类(在轮播中)。这既不优雅也不轻量级(CPU 方面),但它确实有效。

也许交叉点观察者会是一个更好的解决方案(仅重新计算来自交叉点观察者的事件)。