2017-02-24 283 views
2

我正在通过万维网寻找javascript函数“pin parallax scroll event”或任何你想称之为的东西。如何改善此javascript电梯/视差/ pin-it元素功能

Scrollmagic有一个解决方案,但它有一个设定值。很多时候你不会知道内容的实际高度。

找不到符合我需求的解决方案,所以我在jQuery中构建了自己的解决方案。

虽然我的解决方案并不完美。当滚动事件被触发时,它会感觉迟缓,你可以看到升降机元件被移动了一小段时间(在200ms期间)。

任何人都有线索如何改善?

 $(window).scroll(function(){ 

     var currentPos = $(document).scrollTop(); // Our current position 

     console.log(currentPos); //So we can se our current position in the console 

     var targetElemTopPos = $("#elevator .right").offset().top; //Value of our targets top position 
     var targetElemenBotPos = $("#elevator .right").outerHeight(); //Total of our targets height 
     var targetLeftBosPos = $("#elevator .left").outerHeight(); //Total value of our elevator 

     var amountOfTop = targetElemenBotPos - targetLeftBosPos; //Calc the difference from sections top to elevators top 

     //The elevator algorithm 
     if ((currentPos > targetElemTopPos) && (currentPos < targetElemenBotPos)) { 
      //If the current position is greater than targets top position 
      //AND if the current position is less than targets bottom position 
      //Start the elevator 
      console.log('Elevator in movement'); 
      $('#elevator .left').addClass('fixed'); 
      $('#elevator .left').css('top', 0); 
     } else if (currentPos > targetElemTopPos) { 
      //Howeaver if the current position is greater than targets bottom position 
      // Stop the elevator and push it down so we can take the elevator up later if we want to 
      console.log('Elevator has reached the destination'); 
      $('#elevator .left').removeClass('fixed'); 
      $('#elevator .left').css('top', amountOfTop); 
     } else { 
      //Else just let the elevator wait on a passanger 
      console.log('Elevator on standby'); 
      $('#elevator .left').removeClass('fixed'); 
      $('#elevator .left').css('top', 0); 
     } 
     }); 

https://codepen.io/jeffdesign/pen/jBOdgE

(该LAGG是在全屏和Safari中更明显)

回答

0

我没有把JQuery的,但你可以试试这个香草代码: 它alsow处理的情况下当粘性元素的内容高度大于屏幕并且仅为多个实例使用一个滚动侦听器时。

(function(global, document, undefined) { 
 
    'use strict'; 
 
    const SCROLL_DIRECTION = { 
 
    UP: -1, 
 
    DOWN: 1 
 
    }; 
 
    var ticking = false; 
 
    var currentScrollPosition = 0; 
 
    var lastScrollPosition = 0; 
 
    var scrollDirection = 1; 
 
    var stickies = []; 
 
    
 
    function StickyScroll(selector, options) { 
 
    var self = this; 
 
    var target = null; 
 
    var parent = null; 
 

 
    options = options || {}; 
 
    options = Object.assign({}, self.defaults, options); 
 
    
 
    target = document.querySelector(selector); 
 
    if(!target) return; 
 
    self.targetSnapshot = target.getBoundingClientRect(); 
 
    parent = target.parentNode; 
 
    
 
    if(options.boundTo) { 
 
     parent = document.querySelector(options.boundTo); 
 
    } 
 

 
    self.uid = StickyScroll.UID++; 
 
    
 
    self.target = target; 
 
    self.parent = parent; 
 
    self.options = options; 
 
    stickies[self.uid] = self; 
 
    } 
 
    
 
    StickyScroll.UID = 0; 
 
    StickyScroll.prototype.defaults = { 
 
    boundTo: null, 
 
    directionOffset: 50 
 
    } 
 
    StickyScroll.prototype.update = function() { 
 
     var targetRect = this.target.getBoundingClientRect(); 
 
     var parentRect = this.parent.getBoundingClientRect(); 
 
     var targetHeight = targetRect.height; 
 
     var targetBottom = currentScrollPosition + targetHeight; 
 
     var parentHeight = parentRect.height; 
 
     var parentTop = this.parent.offsetTop; 
 
     
 
     if(currentScrollPosition > lastScrollPosition + this.options.directionOffset) { 
 
     scrollDirection = SCROLL_DIRECTION.DOWN; 
 
     lastScrollPosition = currentScrollPosition; 
 
     } else if(currentScrollPosition < lastScrollPosition - this.options.directionOffset) { 
 
     scrollDirection = SCROLL_DIRECTION.UP; 
 
     lastScrollPosition = currentScrollPosition; 
 
     } 
 
     if(currentScrollPosition > parentTop && targetBottom < parentHeight + parentTop) { 
 
     this.target.style.height = targetHeight + 'px'; 
 
     this.target.style.position = 'fixed'; 
 

 
     if(scrollDirection === SCROLL_DIRECTION.DOWN) { 
 
      this.target.style.top = 0 + 'px'; 
 
      this.target.style.bottom = null; 
 
     } 
 
     else { 
 
      this.target.style.top = null; 
 
      this.target.style.bottom = 0 + 'px'; 
 
     } 
 
     } else if(targetBottom >= parentHeight + parentTop) { 
 
     this.target.style.position = 'absolute'; 
 
     this.target.style.top = null; 
 
     this.target.style.bottom = 0; 
 
     this.parent.style.position = 'relative'; 
 
     } else { 
 
     this.parent.style.position = null; 
 
     this.target.style.position = null; 
 
     this.target.style.top = null; 
 
     this.target.style.bottom = null; 
 
     } 
 
     
 
     ticking = false; 
 
    } 
 
    
 
    global.addEventListener('scroll', function(event) { 
 
    stickies.forEach(function(sticky) { 
 
     if (!ticking) { 
 
     currentScrollPosition = document.body.scrollTop; 
 
     window.requestAnimationFrame(sticky.update.bind(sticky)); 
 
     ticking = true; 
 
     } 
 
    }); 
 
    }); 
 
    
 
    global.StickyScroll = StickyScroll; 
 
    
 
})(window, document) 
 

 
let x = new StickyScroll('#elevator .left'); // init 
 
let y = new StickyScroll('#dd'); // should not init
body, html, h1, h2, h3, p { 
 
    padding: 0; 
 
    margin: 0; 
 
    font-family: sans-serif; 
 
} 
 
header { 
 
    background-color: #1abc9c; 
 
} 
 
header h1 { 
 
    color: #fff; 
 
    text-align: center; 
 
    font-size: 4em; 
 
    text-align: center; 
 
    position: relative; 
 
    top: 50%; 
 
    -ms-transform: translateY(-50%); 
 
    -webkit-transform: translateY(-50%); 
 
    transform: translateY(-50%); 
 
} 
 
#elevator { 
 
    overflow: hidden; 
 
} 
 
#elevator .left { 
 
    background-color: #e67e22; 
 
    width: 50%; 
 
    color: #fff; 
 
    text-align: center; 
 
    float: left; 
 
    height: 150vh; 
 
} 
 
#elevator .left h2 { 
 
    font-size: 2em; 
 
    text-align: center; 
 
    position: relative; 
 
    top: 50%; 
 
    -ms-transform: translateY(-50%); 
 
    -webkit-transform: translateY(-50%); 
 
    transform: translateY(-50%); 
 
} 
 
#elevator .right { 
 
    background-color: #34495e; 
 
    width: 50%; 
 
    color: #fff; 
 
    float: right; 
 
    line-height: 2em; 
 
} 
 
#elevator .right p { 
 
    padding: 2em; 
 
} 
 
footer { 
 
    min-height: 1200px; 
 
    background-color: #1abc9c; 
 
    clear: both; 
 
    text-align: center; 
 
    padding: 2em; 
 
} 
 
footer h1 { 
 
    color: #fff; 
 
    text-align: center; 
 
    padding: 250px 0; 
 
    font-size: 4em; 
 
} 
 
footer p { 
 
    line-height: 2em; 
 
    color: #fff; 
 
} 
 
.fixed { 
 
    position: fixed !important; 
 
}
<html> 
 
    <head> 
 
    <meta charset="utf-8"> 
 
    <title></title> 
 
    </head> 
 

 
    <body> 
 

 
    <header class="100vh"> 
 
     <h1>I am a header</h1> 
 
    </header> 
 

 
    <section id="elevator"> 
 
     <div class="left 100vh"> 
 
     <h2>I am Mr. Elevator</h2> 
 
     </div> 
 
     <div class="right"> 
 
     <p>Vestibulum id ligula porta felis euismod semper. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p> 
 
     <p>Sed posuere consectetur est at lobortis. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Donec sed odio dui. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p> 
 
     <p>Curabitur blandit tempus porttitor. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur. Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</p> 
 
     <p>Maecenas faucibus mollis interdum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</p> 
 
     <p>Vestibulum id ligula porta felis euismod semper. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p> 
 
     <p>Sed posuere consectetur est at lobortis. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Donec sed odio dui. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p> 
 
     <p>Curabitur blandit tempus porttitor. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur. Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</p> 
 
     <p>Maecenas faucibus mollis interdum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</p> 
 
     <p>Vestibulum id ligula porta felis euismod semper. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p> 
 
     <p>Sed posuere consectetur est at lobortis. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Donec sed odio dui. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p> 
 
     <p>Curabitur blandit tempus porttitor. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur. Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</p> 
 
     <p>Maecenas faucibus mollis interdum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</p> 
 
     <p>Vestibulum id ligula porta felis euismod semper. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p> 
 
     <p>Sed posuere consectetur est at lobortis. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Donec sed odio dui. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p> 
 
     <p>Curabitur blandit tempus porttitor. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur. Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</p> 
 
     <p>Maecenas faucibus mollis interdum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</p> 
 
     </div> 
 
    </section> 
 

 
    <footer> 
 
     <h1>I am bigfooter</h1> 
 
     <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et.</p> 
 
     <p>Donec ullamcorper nulla non metus auctor fringilla. Etiam porta sem malesuada magna mollis euismod. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p> 
 
     <p>Maecenas sed diam eget risus varius blandit sit amet non magna. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p> 
 
     <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et.</p> 
 
     <p>Donec ullamcorper nulla non metus auctor fringilla. Etiam porta sem malesuada magna mollis euismod. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p> 
 
     <p>Maecenas sed diam eget risus varius blandit sit amet non magna. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p> 
 
    </footer> 
 
    </body> 
 
</html>

0

我发现这个问题。

如果在if/ifelse/else中使用“大于”和“小于”,则当该值等于当前值时,条件不会为真。所以解决方案非常简单。

我所做的只是编辑从:

if ((currentPos > targetElemTopPos) && (currentPos < targetElemenBotPos)) 

要:

if ((currentPos >= targetElemTopPos) && (currentPos <= targetElemenBotPos)) 

而且同样在功能上的其余部分。