Friday, March 17, 2017

Prevent jQuery from jumping to the bottom (when using fadeIn)

Leave a Comment

I've created some divs fading in with jQuery, I have a problem if the user scrolls a bit down though. If you are not at the top of the page, it will always jump to the bottom when a new div fades in.

Here's my code:

<style> #overflowwrap {    overflow:hidden !important; } </style>  <div id="overflowwrap">    <div id="five" style="display: none;">a lot of content</div>    <div id="four" style="display: none;">a lot of content</div>    <div id="three" style="display: none;">a lot of content</div>    <div id="two" style="display: none;">a lot of content</div>    <div id="one" style="display: none;">a lot of content</div> </div>  <script> $('#overflowwrap').css('max-height',$(window).height());  $("#one").fadeIn(500); setTimeout( function show() {    $("#two").fadeIn(500); }, 3000); setTimeout( function show() {    $("#three").fadeIn(500); }, 6000); setTimeout( function show() {    $("#four").fadeIn(500); }, 9000); setTimeout( function show() {    $("#five").fadeIn(500); }, 12000); </script> 

Update: Example fiddle: https://jsfiddle.net/6qj1hbp0/1/

This wouldn't be a problem, if this was the only element on a page and the user couldn't scroll. However, it's integrated on another site (survey software), so the user is able to scroll.

Is there anything I can do to prevent the site from jumping to the bottom?

6 Answers

Answers 1

Try a different approach.

Instead, of display: none on every element, try opacity: 0;

Then instead of:

setTimeout( function show() {     $("#two").fadeIn(500);     }, 5000); 

use:

setTimeout( function show() {     $("#two").addClass('is-visible); }, 5000); 

and add:

.is-visible { opacity: 1 !important; } 

within your <style> tags.

Answers 2

you cannot “freeze” scroll, but you can read and change the scroll position, especially because you are using jQuery.

My solution consists in saving the current position of the scroll immediately before the fadeIn instruction then reassign the same value immediately after, with this function:

function fadeInElement(id, time) {   var currentScroll = $(window).scrollTop();   $('#' + id).fadeIn(time);   $(window).scrollTop(currentScroll); } 

Then you may call the same function several times with different ids and duration time, something like this:

fadeInElement('one', 500); 

or this:

setTimeout(function() {     fadeInElement('two', 500); }, 5000); 

You may look a working example on CodePen or on JSFiddle

Answers 3

  1. Do you need to restrict the overflow with hidden?

    You can just set overflow: auto and browser will automatically take care of ensuring scrollTop remains the same after the fade in. The element user is looking at after scroll will remain at the same offset. If user hasn't scrolled then it will show the latest faded element at the top

    Here's a jsfiddle: https://jsfiddle.net/sm2qaa3c/2/

    enter image description here

  2. After re-reading your comment, it seems you always want to display the latest faded div at the top. In that case you want a function to reset scrollTop to 0. You want to do it on overflowwrap not window since that's where the overflow scrolling will happen.

    ['#one', '#two', '#three', '#four', '#five'].forEach((id, idx) => {     setTimeout(() => {         $(id).fadeIn(500);         $('#overflowwrap').scrollTop(0);     }, idx * 5000); }); 

    enter image description here

See jsfiddle: https://jsfiddle.net/sm2qaa3c/3/

Answers 4

In short, the easiest thing you can do is hide the previous div every time you show a new one.

https://jsfiddle.net/6qj1hbp0/2/

$("#one").fadeIn(500); setTimeout( function() {   $("#one").hide();   $("#two").fadeIn(500); }, 3000); setTimeout( function() {   $("#two").hide();   $("#three").fadeIn(500); }, 6000); setTimeout( function() {   $("#three").hide();   $("#four").fadeIn(500); }, 9000); setTimeout( function() {   $("#four").hide();   $("#five").fadeIn(500); }, 12000); 

If you want to fade from one box to the other (which creates a much smoother looking effect), you will need to do some other stuff - most notably:

  • put the boxes in order, top to bottom, #one to #five (you should do this anyways - it just makes sense congnatively)
  • set the position to absolute for each of the boxes
  • set some other styles (see the fiddle below)
  • use a special class while a box is fading in

https://jsfiddle.net/6qj1hbp0/3/

Answers 5

It's simple. Just reorder your div's to the order you want to show them instead of "five, four, three, two, one". Your browser doesn't have any intention to take you to the bottom, it's just trying to keep your view point fixed on the current hash navigation. As your fading div is always above, your scrollTop will just jump to the bottom.

Another solution - if you don't want to reorder - is to remove all div id's and creating other way to recognize them, something like "data-id".

PS: look for some id's after too!

Answers 6

Thanks for the answers, they didn't work for my purpose though.

However, I've got a solution from another forum which doesn't require changing the functionality. This seems to work:

$('#overflowwrap').css('max-height', $(window).height()); fadeIn("#one", 0) fadeIn("#two", 5000) fadeIn("#three", 10000) fadeIn("#four", 15000) fadeIn("#five", 20000)  function cs() { console.log(document.scrollingElement.scrollTop) } document.scrollingElement.scrollTop = 16  function fadeIn(el, when) { setTimeout(function show() { var t=document.scrollingElement.scrollTop $(el).fadeIn(500); document.scrollingElement.scrollTop = t }, when);  } 

Here is a working example on JSFiddle: https://jsfiddle.net/6qj1hbp0/4/

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment