滚动显示功能时固定部分

时间:2016-11-25 11:49:04

标签: jquery html scroll parallax sticky

我试图修复Section 2一旦到达视口,在每个滚动条上,左边的下一个段落突出显示另一个,右侧的电话屏幕滑到下一个。

因此,在每个卷轴上,我想突出显示下一个文字并更改手机内部的方式,就像您在许多应用程序着陆页上看到的一样。

Here's a demo

enter image description here

3 个答案:

答案 0 :(得分:2)

修改

我已更新代码,这是一个新的JSFiddle

旧答案:(类似于fullpage.js)

由于您的HTML包含部分,因此您将每个部分的高度设置为100vh并使用视差标记标记您的帖子我假设如下:

  • 您需要每个部分滚动并填充整个屏幕。
  • 此设置中的滚动条似乎没用。
  • 每个鼠标滚轮需要将整个部分带到屏幕上。
  • 一旦看到带有移动电话div的部分,您需要滚动到子元素,而不是部分。

基于此,我将您的代码更改为以下内容:

var lastScrollPos = 0;
var scrollFired = false;

var textConainersElement = jQuery('.text-container p');
var mainElem = jQuery("[data-main='true']");
var firstElem = jQuery("section:first-child");
var lastElem = jQuery("section:last-child");
var wrapper = jQuery(".wrapper");

jQuery(document).on('DOMMouseScroll mousewheel', function(e) {

  // if the scroll has occrued already then dont fire it again until transition ended
  if (scrollFired == true) {
    jQuery(window).scrollTop(lastScrollPos);
    return false;
  }

  var inviewElem = jQuery("[data-inview='true']");
  var nextElem = inviewElem.next();
  var prevElem = inviewElem.prev();
  var currentTop = parseInt(firstElem.attr('data-top'));



  if (e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) {
    // Scrolling down 
    // if viewed element is last element do nothing
    if (inviewElem.index() >= lastElem.index())
      return false;

    // if main section is inview then scroll through its elements
    if (inviewElem.index() == mainElem.index()) {
      // if the active child is not the last element then process
      var active = jQuery('.text-container .active');
      if (active.index() != textConainersElement.length - 1) {
        jQuery('.text-container .active').removeClass('active').next().addClass('active');

        // Dont scroll further
        return false;
      }
    }

    var top = currentTop + 100;
    firstElem.css("margin-top", "-" + top + "vh").attr("data-top", top);
    nextElem.attr("data-inview", 'true');
    inviewElem.attr("data-inview", 'false');

  } else {
    // Scrolling up 
    // if viewed element is first element do nothing
    if (inviewElem.index() <= firstElem.index())
      return false;

    // if main section is inview then scroll through its elements
    if (inviewElem.index() == mainElem.index()) {
      // if the active child is not the last element then process
      var active = jQuery('.text-container .active');
      if (active.index() != 0) {
        jQuery('.text-container .active').removeClass('active').prev().addClass('active');

        // Dont scroll further
        return false;
      }
    }

    var top = currentTop - 100;
    firstElem.css("margin-top", "-" + top + "vh").attr("data-top", top);
    prevElem.attr("data-inview", 'true');
    inviewElem.attr("data-inview", 'false');
  }

  // Set values to use for next scrolling event
  lastScrollPos = jQuery(window).scrollTop();
  scrollFired = true;

  // reset scrollFired var after transition ended
  firstElem.one('transitionend', function() {
    scrollFired = false;
  });

  //prevent page fom scrolling
  return false;
});
body {
  margin: 0;
}

.wrapper {
  display: block;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

section {
  display: block;
  width: 100%;
  height: 100vh;
  border-bottom: 2px dashed black;
  position: relative;
  transition: all 0.5s;
  background-color: #c4c4c4;
}

section[data-inview="true"] {
  background-color: #929292;
}

.phone-container {
  align-items: center;
  background: #dedede none repeat scroll 0 0;
  border-left: 5px solid black;
  display: flex;
  float: right;
  height: 100vh;
  justify-content: center;
  width: 500px;
}

.phone {
  width: 200px;
  height: 500px;
  background: #A6A6A6 none repeat scroll 0 0;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 5px;
}

section.long-scroll {
  height: auto;
}

p {
  margin-top: 80px;
}

p:first-child {
  margin-top: 0px;
}

.text-container {
  float: left;
  width: 200px;
}

.spacer {
  display: block;
  width: 100%;
}

p.active {
  color: #C1E7FF;
}

.clearfix:after {
  visibility: hidden;
  display: block;
  font-size: 0;
  content: " ";
  clear: both;
  height: 0;
}

.clearfix {
  display: inline-block;
}


/* start commented backslash hack \*/

* html .clearfix {
  height: 1%;
}

.clearfix {
  display: block;
}


/* close commented backslash hack */

.stuck {
  position: fixed;
  top: 0;
}

.fixed {
  position: fixed;
  top: 0;
}

.sticky-wrapper {
  height: auto !important;
}

.text-container {
  padding-left: 40px;
  padding-top: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='wrapper'>
  <section data-inview='true' data-top='0'>
    Scroll-down
  </section>
  <section class="long-scroll clearfix" id="pin" data-main='true'>
    <div class="text-container">
      <p class="active">Text - 1</p>
      <p>Text - 2</p>
      <p>Text - 3</p>
      <p>Text - 4</p>
    </div>

    <div class="phone-container">
      <div class="phone">Slide-1</div>
    </div>
  </section>
  <section id="unhook"></section>
</div>

我对代码进行了评论,以便明确理解,这里也是一个使用相同代码的jsfiddle:https://jsfiddle.net/8zgsdzy0/

答案 1 :(得分:1)

检查一下 - 这里是我在这里做的总结:

  1. 我绝对将section2(pin)放在我添加到它的包装器上。

  2. resize监听器上,我将引脚的高度设置为与phone容器相同,以便高度匹配。

  3. scroll监听器上,我计算第2节是否进入播放/滑出视野。

  4. 请参阅下面的演示:

    var found = false, last = false;;
    var lockedScrollTop = 0, step = 0, slide = 1;
    
    var wrapper = $('#wrap');
    var pin = $('#pin');
    var box = $('#phone');
    
    $(document).resize(function() {
      pin.outerHeight(box.innerHeight());
    });
    
    $(document).scroll(function() {
      var offsetTop = -wrapper.offset().top + $(window).scrollTop();
      
      // conditions on scroll from top down
      if(offsetTop >= 0 && offsetTop < wrapper.outerHeight() && !last) {
        slide = 2;
      } else if(offsetTop >= 0 && offsetTop >= wrapper.outerHeight()) {
        if(!last) {
          $(window).scrollTop(lockedScrollTop);
          last = true;
          slide = 3;
        } else {
          slide = 4;
        }
      } 
      
      // conditions of scroll from bottom up
      if(offsetTop >= 0 && offsetTop < wrapper.outerHeight() && slide === 4) {
        last = true;
        slide = 3;
      } else if(offsetTop < 0 && last) {
        last = false;
        $(window).scrollTop(lockedScrollTop + wrapper.outerHeight() - 1);
        slide = 2;
      } else if(offsetTop < 0 && !last) {
        slide = 1;
        // reset
        found = false;
        lockedScrollTop = 0;
        step = 0;
      }
      
      // console.log(slide);
      
      if (slide == 2) {
        if(offsetTop < 0)
          offsetTop = 0;
        pin.css({'top': offsetTop + 'px'});
        if (!found) {
          // calculate step
          lockedScrollTop = wrapper.offset().top;
          step = wrapper.outerHeight() / 4;
          found = true;
        }
        // set/unset active text
        var index = Math.floor(($(window).scrollTop() - lockedScrollTop) / step);
        $('#pin .text-container > p').removeClass('active');
        $('#pin .text-container > p').eq(index).addClass('active');
      } else {
        pin.css({'top': 0});
      }
    });
    section {
      display: block;
      width: 100%;
      height: 100vh;
      border-bottom: 1px solid red;
    }
    .phone-container {
      height: 100vh;
      width: 500px;
      background: red;
      display: flex;
      align-items: center;
      justify-content: center;
      float: right;
    }
    .phone {
      width: 200px;
      height: 500px;
      background: #000;
      color: #fff;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    section.long-scroll {
      height: auto;
    }
    p {
      margin-top: 80px;
    }
    p:first-child {
      margin-top: 0px;
    }
    .text-container {
      float: left;
      width: 200px;
    }
    .spacer {
      display: block;
      width: 100%;
    }
    p.active {
      color: pink;
    }
    .clearfix:after {
      visibility: hidden;
      display: block;
      font-size: 0;
      content: " ";
      clear: both;
      height: 0;
    }
    .clearfix {
      display: inline-block;
    }
    /* start commented backslash hack \*/
    
    * html .clearfix {
      height: 1%;
    }
    .clearfix {
      display: block;
    }
    /* close commented backslash hack */
    
    .stuck {
      position: fixed;
      top: 0;
    }
    .fixed {
      position: fixed;
      top: 0;
    }
    .sticky-wrapper {
      height: auto !important;
    }
    .text-container {
      padding-left: 40px;
      padding-top: 40px;
    }
    
    /*NEW STYLES ADDED*/
    #pin {
      position: absolute;
      right: 0;
      top: 0;
    }
    #pin.transition {
      transition: top ease 1s;
    }
    #wrap {
      position: relative;
      border: none;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <section>
      Scroll-down
    </section>
    <section id="wrap">
      <section class="long-scroll clearfix" id="pin">
        <div class="text-container">
          <p class="active">Text - 1</p>
          <p>Text - 2</p>
          <p>Text - 3</p>
          <p>Text - 4</p>
        </div>
        <div class="phone-container" id="phone">
          <div class="phone">Slide-1</div>
        </div>
      </section>
    </section>
    <section id="unhook"></section>

答案 2 :(得分:1)

与此类似? http://codepen.io/jkochis/pen/ZBxgKd

<强> JS

$(document).ready(function () {
    $(document).on("scroll", onScroll);

    //smoothscroll
    $('a[href^="#"]').on('click', function (e) {
        e.preventDefault();
        $(document).off("scroll");

        $('a').each(function () {
            $(this).removeClass('active');
        })
        $(this).addClass('active');

        var target = this.hash,
            menu = target;
        $target = $(target);
        $('html, body').stop().animate({
            'scrollTop': $target.offset().top+2
        }, 500, 'swing', function () {
            window.location.hash = target;
            $(document).on("scroll", onScroll);
        });
    });
});

function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#menu-center a').each(function () {
        var currLink = $(this);
        var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
            $('#menu-center ul li a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
      console.log($('#menu-center ul li a.active').attr("href"), $('#menu-center a:eq(0)').attr("href"));
      if($('#menu-center ul li a.active').attr("href") !== $('#menu-center a:eq(0)').attr("href")) {
        $('body').addClass('fixed-product');
      } else {
        $('body').removeClass('fixed-product');
      }
    });
}

<强> HTML

<div class="m1 menu">
    <div id="menu-center">
        <ul>
            <li><a class="active" href="#section1">Section 1</a>

            </li>
            <li><a href="#section2">Section 2</a>

            </li>
            <li><a href="#section3">Section 3</a>

            </li>
            <li><a href="#section4">Section 4</a>

            </li>
        </ul>
    </div>
</div>
<div id="section1"></div>
<div id="section2">
  <div class="product">PRODUCT</div>
</div>
<div id="section3"></div>
<div id="section4"></div>

<强> CSS

body, html {
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
}
.menu {
    width: 200px;
    height: 400px;
    background-color: rgba(0, 0, 0, 1);
    position: fixed;
    background-color:rgba(4, 180, 49, 0.6);
    -webkit-transition: all 0.3s ease;
    -moz-transition: all 0.3s ease;
    -o-transition: all 0.3s ease;
    transition: all 0.3s ease;
}
.light-menu {
    width: 100%;
    height: 75px;
    background-color: rgba(255, 255, 255, 1);
    position: fixed;
    background-color:rgba(4, 180, 49, 0.6);
    -webkit-transition: all 0.3s ease;
    -moz-transition: all 0.3s ease;
    -o-transition: all 0.3s ease;
    transition: all 0.3s ease;
}
#menu-center {
    width: 980px;
    height: 75px;
    margin: 0 auto;
}
#menu-center ul {
    margin: 15px 0 0 0;
}
#menu-center ul li {
    list-style: none;
    margin: 0 30px 0 0;
    display: block;
}
.active {
    font-family:'Droid Sans', serif;
    font-size: 14px;
    color: #fff;
    text-decoration: none;
    line-height: 50px;
}
a {
    font-family:'Droid Sans', serif;
    font-size: 14px;
    color: black;
    text-decoration: none;
    line-height: 50px;
}
#section1 {
    background-color: grey;
    height: 100%;
    width: 100%;
    overflow: hidden;
}
#section2 {
    height: 100%;
    width: 100%;
}
#section3 {
    background-color: blue;
    height: 100%;
    width: 100%;
}
#section4 {
    background-color: red;
    height: 100%;
    width: 100%;
}
.product {
  background: yellow;
  float: right;
  padding: 100px
}
.fixed-product .product {
  position: fixed;
  top: 0;
  right: 0;
}

免责声明:我发现这个JSFiddle:https://jsfiddle.net/cse_tushar/Dxtyu/141/并且基于我的Codepen。