Attaching a section when scrolling to a demonstration of functions

I'm trying to fix Section 2 as soon as it appears in the viewport, and each time I scroll through the next paragraph, another is highlighted on the left, and the phone screen on the right will move to the next.

So, on each scroll, I want to highlight the following text and change the saxophone inside the phone, as you see on many of the applicationโ€™s landing pages.

Here is a demo

enter image description here

+6
source share
3 answers

Check it out - here is a summary of what I'm doing here:

  • I absolutely position section2 ( pin ) relative to the wrapper that I added to it.

  • On the resize listener, I set the height of the buffer in the same way as the phone container to match the heights.

  • On the scroll listener, I figure out if section2 comes into play / shows out of view.

See the demo below:

 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> 
+1
source

Edit:

I updated the code and here is the new JSFiddle .

Old answer: (similar to fullpage.js)

Since your HTML includes sections, you set the height of each section to 100vh, and you tagged a message with the parallax tag. I assumed the following:

  • You need each section to scroll and fill the entire screen.
  • The scrollbar seems useless in this setting.
  • Each scroll of the mouse needs to display the entire section.
  • After you see the section with the mobile phone, you will need to scroll to the children element, and not to the sections.

So, based on this, I changed your code to the following:

 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> 

I commented on the code to understand it, and also here jsfiddle with the same code: https://jsfiddle.net/8zgsdzy0/ .

+2
source

Similar to this? 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; } 

Disclaimer: I found this JSFiddle: https://jsfiddle.net/cse_tushar/Dxtyu/141/ and founded my Codepen.

+1
source

Source: https://habr.com/ru/post/1012650/


All Articles