2017-02-24 81 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)) 

而且同樣在功能上的其餘部分。