简体   繁体   English

如何改善此JavaScript电梯/视差/ pin-it元素功能

[英]How to improve this javascript elevator / parallax / pin-it element function

I was researching through the world wide web for a javascript function ”pin parallax scroll event” or whatever you'd like to call it. 我正在万维网上搜索javascript函数“ pin视差滚动事件”或任何您想调用的函数。

Scrollmagic has a solution of this, but it has a set value. Scrollmagic对此有一个解决方案,但它具有设定值。 Many times you wont know the actual height of the content. 很多时候,您不会知道内容的实际高度。

Couldn't find a solution that was fitting my needs so I built my own in jQuery. 找不到适合我需求的解决方案,因此我在jQuery中构建了自己的解决方案。

Althought my solution isn't perfect. 虽然我的解决方案并不完美。 When the scroll-event is fired, it feels laggy and you can see the elevator-element being moved for a tiny moment (during like 200ms). 触发滚动事件时,感觉很迟钝,您可以看到电梯元件被移动了一会儿(大约200毫秒)。

Anyone has a clue how to improve this? 任何人都知道如何改善这一点?

      $(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 https://codepen.io/jeffdesign/pen/jBOdgE

(The lagg is more obvious in full-screen and in Safari) (在全屏和Safari中,滞后现象更加明显)

I'm not into JQuery but you could try this vanilla code: It alsow handles the case when the content height of the sticky element is bigger than the screen and only uses one scroll listener for multiple instances. 我不喜欢JQuery,但是您可以尝试以下原始代码:当sticky元素的内容高度大于屏幕且仅对多个实例使用一个滚动侦听器时,它也可以处理这种情况。

 (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> 

I found the problem. 我发现了问题。

When you do use "greater than" and "less than" in if/ifelse/else the condition wont be true when the value equals the current value. 当在if / ifelse / else中使用“大于”和“小于”时,当值等于当前值时,条件将不成立。 So the solution was quite easy. 因此,解决方案非常容易。

All I did was edit from: 我所做的只是编辑自:

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

To: 至:

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

And same on the rest of the function. 其余功能相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM