首页 > 解决方案 > 如何在滚动时显示时间线的背景

问题描述

我有一些特定时间轴的代码,问题是:滚动时时间轴中的背景项目没有在正确的时间显示(顶部和底部)

当相关项目垂直居中时,我需要显示背景,例如,在最后一个和倒数第二个背景中有一个显示偏移量。

请看一下 GIF:https ://gfycat.com/possiblesadcowbird

JS 代码(我取自:https ://codepen.io/knyttneve/pen/bgvmma?editors= 0010 并根据我的项目进行了编辑):

var fn_timeline = function() {
  $.fn.timeline = function() {
    var selectors = {
      id: $(this),
      item: $(this).find(".timeline-item"),
      activeClass: "timeline-item--active",
      img: ".o-timeline__img > img"
    };
    selectors.item.eq(0).addClass(selectors.activeClass);
    selectors.id.css("background-image", "url(" + selectors.item.first().find(selectors.img).attr("src") + ")");

    var itemLength = selectors.item.length;
    $(window).scroll(function() {
      var max, min;
      var pos = $(this).scrollTop();
      selectors.item.each(function(i) {
        min = $(this).offset().top;
        max = ($(this).height() + $(this).offset().top);
        var that = $(this)
        if (i == itemLength - 2 && pos > min + $(this).height() / 2) {
          selectors.item.removeClass(selectors.activeClass);
          selectors.id.css("background-image", "url(" + selectors.item.last().find(selectors.img).attr('src') + ")");
          selectors.item.last().addClass(selectors.activeClass)
        } else if (pos <= max - 40 && pos >= min) {
            selectors.id.css("background-image", "url(" + $(this).find(selectors.img).attr('src') + ")");
            selectors.item.removeClass(selectors.activeClass);
            $(this).addClass(selectors.activeClass);
          }
      });
    });
  }
  $("#timeline-1").timeline();
}

HTML 代码:

<div class="timeline-wrapper  container-content container-content--smaller container-content--fake-col   timeline1col  ">
  <div class="timeline-container" id="timeline-1" style="background-image: url(&quot;img/tl-3.jpg&quot;);">
    <div class="timeline">
      <div id="fullpage">
        <div class="section timeline-item-wrapper timeline-item">
          <div class="timeline-marker"></div>
          <div class="timeline__content">
            <div class="timeline-minature">
              <div class="o-timeline__img timeline-img">
                <img src="img/tl-1.jpg" style="width: 350px">
              </div>
            </div>

            <h2 class="timeline__content-title">Le premier ordinateur</h2>

            <div class="wysiwyg">
              He was born in 1881 (probably in the spring) in Salonica, then an Ottoman city, now inGreece. His father Ali Riza, a customs official turned lumber merchant, died when Mustafawas still a boy. His mother Zubeyde, adevout and strong-willed woman, raised him and his sister.
            </div>

            <a href="#" class="a-link--border-effect timeline-link">
              * Qu’est-ce que la géodésie ?
            </a>
          </div>
        </div>
        <div class="section timeline-item-wrapper timeline-item">
          <div class="timeline-marker"></div>
          <div class="timeline__content">
            <div class="timeline-minature">
              <div class="o-timeline__img timeline-img">
                <img src="img/tl-2.jpg" style="width: 350px">
              </div>
            </div>

            <p class="timeline__content-date">1991</p>

            <div class="wysiwyg">
              He was born in 1881 (probably in the spring) in Salonica, then an Ottoman city, now inGreece. His father Ali Riza, a customs official turned lumber merchant, died when Mustafawas still a boy. His mother Zubeyde, adevout and strong-willed woman, raised him and his sister.
            </div>

          </div>
        </div>
        <div class="section timeline-item-wrapper timeline-item timeline-item--active">
          <div class="timeline-marker"></div>
          <div class="timeline__content">
            <div class="timeline-minature">
              <div class="o-timeline__img timeline-img">
                <img src="img/tl-3.jpg" style="width: 350px">
              </div>
            </div>

            <h2 class="timeline__content-title">Le premier ordinateur</h2>

            <div class="wysiwyg">
              He was born in 1881 (probably in the spring) in Salonica, then an Ottoman city, now inGreece. His father Ali Riza, a customs official turned lumber merchant, died when Mustafawas still a boy. His mother Zubeyde, adevout and strong-willed woman, raised him and his sister.
            </div>

            <a href="#" class="a-link--border-effect timeline-link">
              * Qu’est-ce que la géodésie ?
            </a>
          </div>
        </div>
        <div class="section timeline-item-wrapper timeline-item">
          <div class="timeline-marker"></div>
          <div class="timeline__content">
            <div class="o-timeline__img timeline-bg">
              <img src="img/tl-4.jpg" alt="">
            </div>

            <h2 class="timeline__content-title">just bg</h2>

            <div class="wysiwyg">
              He was born in 1881 (probably in the spring) in Salonica, then an Ottoman city, now inGreece. His father Ali Riza, a customs official turned lumber merchant, died when Mustafawas still a boy. His mother Zubeyde, adevout and strong-willed woman, raised him and his sister.
            </div>

          </div>
        </div>
      </div>
    </div>
  </div>
</div>

标签: javascripthtmljquerytimeline

解决方案


这是数学和用户体验设计问题的混合。(正是我喜欢的那种问题!)

首先,你要考虑的是用户是向上还是向下滚动。那是关键。
根据滚动方向,您检查item.

例如,如果您只比较项目的顶部,则用户必须向上滚动整个项目,直到顶部穿过中间,然后它才会变得模糊。那是不行的。

所以这真的是关于用户体验方面:当用户向下滚动时(所以内容向上移动),他需要在“某个点”显示下一个项目。因为他可能还在看图片下方的文字,所以我觉得那个“点”在视口中间有点高……但不要太高。

当用户向上滚动时(因此内容向下移动),他当然希望在视口中间之前让来自上方的内容不模糊。

所以...您需要考虑两个不同的视口位置。此后我将这些点称为“触发点”。

  • 略高于中间(向下滚动)
  • 略低于顶部(向上滚动)

============

这变得越来越复杂......
   两个滚动方向和两个视口位置与项目的顶部底部进行比较。

所以我做了两个变量来保存基于4个方面的条件结果:

  1. 向上或向下滚动
  2. 滚动像素小于项目的顶部或底部
  3. “触发器”大于项目的顶部
  4. “触发器”+ 20px 小于项目的底部(这是为了避免闪烁......记住你在一个循环中)

我将两个“视口位置”定义为5/163/16...
但是您可能更喜欢一些百分比值,例如0.310.19...您可以使用它。

(function ($) {
  $.fn.timeline = function () {
    var selectors = {
      id: $(this),
      item: $(this).find(".timeline-item"),
      activeClass: "timeline-item--active",
      img: ".timeline__img"
    };

    // Onload, set first item as active
    selectors.item.eq(0).addClass(selectors.activeClass);

    // The viewport height
    var winHeight = $(window).height();

    // For the scrolling direction
    var lastPos = 0;

    // Scroll event handler
    $(window).scroll(function () {
      var item_bottom,
        item_top,
        item_height,
        scrollDown,
        trigger_top,
        trigger_bottom;

      // The window scrolled pixels
      var pos = $(this).scrollTop();

      // Scroll direction
      // true: user is scrolling down
      // false: user is scrolling up
      scrollDown = pos > lastPos;

      // items loop
      selectors.item.each(function (i) {
        var this_item = $(this);
        item_top = this_item.offset().top;
        item_height = this_item.height();
        item_bottom = item_height + this_item.offset().top;

        // You can play with those triggers...
        trigger_top = pos + (5 / 16) * winHeight;
        trigger_bottom = pos + (3 / 16) * winHeight;

        // Just for the console.log
        var item_date = this_item.find(".timeline__content-title").text();

        // The conditions
        var scroll_down_condition =
          scrollDown &&
          pos < item_top &&
          trigger_top >= item_top &&
          trigger_top + 20 <= item_bottom;

        var scroll_up_condition =
          !scrollDown &&
          pos < item_bottom &&
          trigger_bottom >= item_top &&
          trigger_bottom + 20 <= item_bottom;

        // If one or the other condition is true
        // Unblur the item and set the background
        if (scroll_down_condition || scroll_up_condition) {
          console.log(
            `Date ${item_date} is in view - `,
            `Scrolling ${scrollDown ? "down" : "up"}`
          );

          // Set background
          selectors.id.css(
            "background-image",
            "url(" + this_item.find(selectors.img).attr("src") + ")"
          );

          // Remove the active class (unblur) on all items
          selectors.item.removeClass(selectors.activeClass);

          // Unblur
          this_item.addClass(selectors.activeClass);
        }
      }); // END item each

      // For the scrolling direction
      lastPos = pos;
    });
  };
})(jQuery);

代码笔


推荐阅读