Maintaining scroll position after height of body is changed - javascript

I am working on a page that has two states: edit mode and normal mode. The user switches between these states by clicking on a toggle button. Triggering edit mode adds more elements to the page (buttons, etc) and thus forces the body element to increase its height.
My issue arises when a user has scrolled down the page and then triggers edit mode - since the page's height has now increased, their current scroll position is lost. I have been trying to find a way through which I can calculate what the new scrollTop should be, but have not been successful.
I've got a jsFiddle as an example of my issue. It automatically scrolls to the third "entry", to simulate a user having scrolled down that far. Clicking the "trigger change" button in the top right hand corner will add more elements to the page, and the scroll position of having the third entry at the top of the page is lost.
I am aware that I could just redo $('body').scrollTop($('.entry:nth-child(3)').offset().top); after the new contents have been added, but I want the scroll position to be remembered for no matter where the user has scrolled to on the page.
http://jsfiddle.net/Jn8wq/2/
Any help is greatly appreciated!

Check this fiddle.
http://jsfiddle.net/Jn8wq/4/
I added this
var tempScrollTop = $(window).scrollTop();
//your append logic
$(window).scrollTop(tempScrollTop+9);
You would notice that I added '9' to the scroll position. It suits your requirement in the given fiddle. But when you implement this on your actual site, you would have to calculate the height of new appended divs dynamically and add that height instead of '9'.

To keep an element where it is in the window after something changes above it, try this:
var tmp = $('#element').offset().top - $(document).scrollTop();
// add stuff
$(document).scrollTop($('#element').offset().top - tmp);

Related

Vertical Chat scrolling is not working in VueJs

I am using chat scrolling in VUE JS. I want to have message scroll at the bottom of the page at every time when new message come or page load. I am trying to have a page scroll code in a function which works little bit surprisingly.
var container = this.$el.querySelector(".messages");
container.scrollTop = container.scrollHeight;
It is working but it cannot fully scroll down to the full bottom. With this, scroll remains at some position between top and bottom. When i trigger this one more time then it takes scroll to the full bottom. I want to have scroll on the bottom on first click not on two clicks. Please help me.
Are you sure your 'container' is full-filled on body or root element?
your code looks just fine...
You may better check:
1) URL bar height issue (on mobile)
2) HTML hierarchy and its css
3) CSS box model and default css values of html.
But still probs are following, If I were you,
I'll add a MAGIC PIXEL NUMBER (which bigger than the margin) like a boss!
Bigger (than its document height) value of scrollTop isn't throw any error. (but watch its cumulation..)

Inability to scroll after turning div from absolute to fixed positioning using jquery

I have a div that gets a 'fixed' class added to it once the user scrolls past a certain point in the parent div. The fixed class simply changes the child div from absolute positioning to fixed positioning.
However, a problem occurs when the user scrolls to a certain point when the 'fixed' class is added (as specified by the 'begin variable' in the js). The user loses the ability to scroll up or down for a number of seconds. And to make matters more complicated, this problem only occurs on the first of six parent divs that uses this code.
Here's the jquery code that adds the 'fixed' class:
var begin = 164;
$("#portfolio_window").scroll(function () {
var y = $(this).scrollTop();
if (y >= begin) {
$('.details').addClass('fixed');
} else {
$('.details').removeClass('fixed');
}
});
If I change the 'begin' variable to something like 600, the user loses the ability to scroll around 600px from the top of the div.
You can try to reproduce the problem at http://dev.zachboth.com/
Here's the easiest way that I've been able to reproduce the problem:
Use Safari
Clicking 'Various Logos' in the 'Work' section
Scrolling down quickly once the 'Various Logos' section appears
It may take several attempts to actually have the problem occur
I can explain your problem:
The problem is that on the "page" you mention being broken has you scrolling in div#portfolio_window. The position:fixed element you mentioned is positioned relative to the window. When you scroll on that element, it's trying to scroll the window (not the parent div).
http://jsfiddle.net/NThY7/
The solution is a bit more involved. I'll hop back on later with a solution.

Issues with Fixed div on bottom of page that stops at given place

We needed a footer toolbar that stays at the bottom of the page, and sticks to some area when page is scrolled below that area.
We did achieved this using following script:
fixed div on bottom of page that stops in given place
But there is an issue on some page where the footer toolbar just disappears from the page, and then appear again when page is scrolled down further.
We found that this particular issue appears only on few page, when the page has some contents like Images, Video, or Ajax load other content where the content is filled in (or space is being filled) after page has loaded.
I have no clue how to fix this.
Here is the link from live site with problem page.
http://www.sandiegopchelp.com/services/cellphone-repair/htc/
http://www.sandiegopchelp.com/top-10-tips-to-help-secure-your-computer/
http://www.sandiegopchelp.com/notes-on-the-phablet-does-the-world-need-one/
It is usually more visible on blog posts with many comments. May be due to Disqus comments being loaded after the page has loaded completely.
How does this look?
http://jsfiddle.net/LukeGT/NxSc3/
$(window).scroll(function() {
$('#bar').css('position', 'static');
console.log($('#bar').position().top);
console.log($(window).scrollTop() + $(window).height());
if ($(window).scrollTop() + $(window).height() < $('#bar').position().top + $('#bar').height()) {
$('#bar').css('position', 'fixed');
}
});
setTimeout(function() {
$('#extra').show();
}, 1000);​
I simulated the late loading of images by just showing a few extra divs after 1 second. I believe the problem arises from the fact that the height of the page changes after the code for the bar runs, so it's behaving as it should if the page were shorter (without the images/ajax etc).
What I do instead is position the bar in it's place at the bottom of the page each time the page is scrolled, calculate its height from the top there, and compare this with the scroll height. If we're too far up, it positions the bar in a fixed position at the base of the page, and otherwise leaves it alone. It works smoothly in Chrome, but I haven't tested elsewhere.
I guess this is a problem with the $(window).height() function. Check here. For all the dynamic contents like Images, Video or Ajax-loaded content the height is not added to the result of $(window).height() unless it is specified somewhere in the HTML or CSS (and from the referred link I see this happens only in Chrome. You might want to confirm on this though). To those dynamic contents you can either try adding the height attribute in html or height attribute in the corresponding style.
This is not the answer but i have found something while inspecting your website...
This is you actual HTML when its working fine as you want..
<div class="footer-toolbar-container" id="sticky_for_a_while" style="position: fixed; ">
but when it is not working, the Position attribute is changing from Fixed to Relative .
<div class="footer-toolbar-container" id="sticky_for_a_while" style="position: relative; ">
you can check you script for that or post you script here...
At initial state, your div is in position: relative so its offset is based on the container element, not on the total height of the page. The variable stickyOffset is set based on that relative offset, that is why it gets clip down sooner than expected while scrolling and also why it works in your JSFiddle as the container there is the page (Iframe) itself.
In your $(document).ready function, you'll need to add the offset of not only the footer but also the rest of the offset on top of the containing element so that the offset is based on the total page instead of the containing div.
Hope that helps.
By looking at your example on http://www.sandiegopchelp.com/services/cellphone-repair/htc/ using chrome, I can see that your footer disappears when it gets at the "related links" section. At this moment, you set the position of the footer to "relative" so it will replace it in the regular flow of the document and its position is actually below the "related links" section which is why it disappears off screen (below "related links").
but you calculated the position at which it should become relative on page load only where you should have recalculated it after having added the "related links" section as it changes the page height (I understood that you added afterward, am I right?).
Try adding a zero height div just above the position of the sticky div, which will remain at that position as the page resizes, then check that position as you scroll to determine the position where the sticky div should stop.
Finally got it fixed by two techniques, setting explicit height wherever possible using CSS and delaying jQuery function after all images are loaded. Refer this: Delay some jQuery function until all images are loaded completely

jQuery - move to a specific element location

I have a pagination system like this:
[content]
1 2 3 Next >
when you click on 1/2/3/next the [content] element gets replaced trough ajax.
the problem is that the screen focus moves up if the new height of the [content] is larger than the previous one.
can I force the screen to stay focused where where the pagination links are?
You need to find the position of the element and scroll to that position each time the height changes. Something like:
var p = $(".links").position();
$(window).scrollTop(p.top);
To make the page transparently appear to stay in the same place, you'll need to find out where the links are before you load in the new content.
var before = $(".links").offset().top;
Then after the new content is loaded, get the link's new height.
var after = $(".links").offset().top;
Then do the math to find out how much it's moved.
var difference = after - before
And update your window's scroll location accordingly
$(window).scrollTop( $(window).scrollTop() + difference )
You can probably fix this without jQuery or javascript... Just create a named anchor where you want the top of the page to be after the user clicks the navigation links, put the name of the anchor in the fragment identifier of the nav links, and don't cancel the event so the page navigates to the anchor.
<a name="contentTop"></a>
[content]
Next

How to see if an element in offscreen

I have a list of divs, and everytime I want to go to the next div I press a key. I need to check if that div is offscreen, and if so, I need to move the screen to show that div either using anchors or another method.
What is my best option for doing this?
Just to clairify, offscreen in my case means something that can't be seen right now without scrolling down. So if you are on the StackOverflow Home Page at the top, the last question on the entire page is offscreen.
Best option is to scroll your page to the element by getting its y-offset, and checking window height and calculating where to scroll page and then you can animate your page to that point.
//height of your div
var scroll = 250;
//animate from actual position to 250 px lower in 200 miliseconds
$(window).animate({"scrollTop": "+="+scroll+"px"}, 200);
so this is not the complete code but it might give you the idea.
check out jquery scrollTop
hope it helps,
Sinan.

Categories

Resources