I want to implement a functionality wherein on clicking the back button, i come back to the same position. A good example may be http://www.jabong.com/men/clothing/mens-t-shirts/ . Here, if you scroll down and hit on a product, and click back from the product page, you reach the same position of the page where that product is.
The example shown here doesn't append anything in the url to remember the position. Also, it doesn't use pushstate or history.js (not loading through ajax).
Any insights into how I can do this?
EDIT: Im using infinite scrolling pagination (like pinterest), and the pages keep loading on scrolling down. When I go back, the query runs again and reloads the page. If I was on the 4th page before, after going back, the pages don't load until page 4 and so there's a break, thus I cant reach that position.
So my question is how do I do this with infinite scrolling?
You can use history.replaceState to store the scroll position just before the page is left. When the user comes back you can check if there is some scroll position present in history.state, and if, scroll to that position.
One more thing to consider is that browers can as well persist the page when leaving (if cache policy allows them) and restore it when returning, including scroll position. In that case no browser events will be fired when coming back, besides the pageshow event (check browser support) which will tell you via event.persisted whether the page is served from cache or not. You maybe want to listen to that event to clear the scroll position from the stored state, again via history.replaceState.
Finally, you want to consider that browsers do scroll restoration on their own and you probably need to disable it via history.scrollRestoration (but check browsers support)
If you can use JQuery in your application. You can try WayPoint Plugin its very simple to use and from your question, I think that is what your looking for.
here is an example Infinite Scrolling and of how it functions:
http://imakewebthings.com/jquery-waypoints/shortcuts/infinite-scroll/
Also take a look at these tutorials for infinite scrolling using various other plugins, you can use which ever one suits your needs the best.
http://www.jquery4u.com/tutorials/jquery-infinite-scrolling-demos/
EDIT:
If your looking to restore the location where the user left off with infinite scroll using the back button, this is a little bit more tricky and requires some more work on your part and how your data is being generated. Please take a look at a similar question here:
Is it possible to write an "Infinite Scroll" javascript that can handle the back button?
I got the same problem and the situation was pretty similar: no bookmark or parameters changed on the url.
Here is my solution and it works:
1) You can use window.history.go(-1) or window.history.back(), which is the same as back button on the browser, to navigate to previous page.
2) When you use this function, for some reason it might not be back to the position on your last page (eg. you select a picture on the bottom of page and it redirects to next page. When you click 'back' button, it goes back to the top of the previous page). In this case, you need to set the current scrollY value var currentScrollYonSession = window.scrollY on the session or other place, depending on your code, when the app redirects to the next page (normally it's onClick() or onChange() event). When you click the 'back' button and the app loads the previous page, firstly check the session that the scrollY value is null or not. If it's null, just load the page as it is; otherwise, retrieve the scrollY value, load the page and set the scrollY value to the current page: window.scroll(0, currentScrollYonSession).
I came up with a solution for my app to achieve this:
$(document).on('click', 'a', function() {
var scrollpos = $(window).scrollTop();
localStorage.setItem('scrollpos', scrollpos);
});
This uses LocalStorage to save how many pixels we are down from the top of the page.
var scrollplan = function() {
var foo = true
if ((foo == true) && $('.box').length > 30) {
var bar = localStorage.getItem('scrollpos')
$("html, body").animate({ scrollTop: bar}, 500);
}
$('.photosbtn').on('click', function(){
var foo = false
});
};
The initial page load has 30 photos with class boxes. My pagination begins by clicking a btn with class photosbtn.
Related
I am using the scrollRestoration feature of Next.js to restore the page position when a back button is pressed. The problem, is that it doesn't restore the horizontal scroll position of the carousels on that page. So I have created my own session variables to track the position of each carousel and restore them on page load. The problem, is that I ONLY want to restore these scroll positions if the back/forward button was pressed. If there is an indicator that scrollRestoration was used on the page I could use that, otherwise, if there is an indication that the page was visited using the forward/back buttons that would also solve it.
Any ideas?
Never done this but my instinct would be:
Make a wrapper component, expose the next/router in your component
Set up an useEffect that updates on router.pathName changes
Set up a condition in the effect that watches History.back()
That kind of goes around the framework, but it doesn't look like Next exposes what you're looking for.
i have figured out how to determine if scrollRestoration is set for a page.
React.useEffect(() => {
const hasScrollHistory = sessionStorage.getItem(`__next_scroll_${window.history.state.idx}`);
if (hasScrollHistory) {
// do your restore logic here
}
}, []);
I have a web page which is dynamically built by the client. It generates dozens of list items each with its own named anchor. The side of the page has a fixed table of contents (TOC) with hyperlinks that point to the named anchors. This allows the user to click a TOC entry a jump to the item.
The trouble I am encountering is that on the initial page load the page is dynamically generated and so it cannot scroll to the item in the initial hash of the URL using the default behavior of a browser. Additionally, when the user switches to a different book the page is completely regenerated with new content and a new starting hash. Same problem: since the hash preexists the content, it doesn't situate itself with the item already in view.
I nearly solved this with JavaScript by awaiting the rendering and then jumping to the hash using scrollIntoView method on the appropriate element.
The next problem is that the stylesheet is not fully applied by the time scrollIntoView is called and so the final position of the item is unknown. I see the unstyled item scroll into view, but once styling is applied the positioning is lost. I put a 1 second setTimeout in place to delay the scrollIntoView call. This works but feels fragile.
Are there reliable techniques for jumping to a named anchor when the content comes after the hash is in place? If I knew when the CSS was done styling content that might help. Alternately, it might be useful to trigger an event once the height of the page stabilizes (thus signaling the finalization of CSS styling).
I had a similar problem, although in my case only the table of contents and named anchors were autogenerated in the onload handler - not the rest of the page content. I solved the initial hash problem by adding the following code to my onload handler after generating the anchors:
if (location.hash)
{
var requested_hash = location.hash.slice(1);
location.hash = '';
location.hash = requested_hash;
}
I had to set the hash to '' before setting it back to the requested name to make the browser respond. This seemed to work in all the browsers I tried (Opera, Chrome, Edge, IE, FF).
You can use jQuery if you will always know the name of the element you want to set focus to. You can run this after your page has loaded:
$( "#targetElementGoesHere" ).focus();
Edit: To scroll to that, check out https://github.com/flesler/jquery.scrollTo
I think the answer you require was answered by this guy...
How to wait until a web page is loaded with javascript?
So, something like this...
document.onload = function(){
scrollIntoView...
}
I am loading results in with ajax with an infinite scroll, however, when you click an item in the list and navigate away from the page, then click the back button, you are back at the top of the list.
I can't figure out how to make the user return to the position they left off.
See the site I am working on:
https://www.studenthouses.com/search/manchester/
Scroll down a few times, then click a property, then click back and you will see what I mean.
I can't remember the result position and load them in because it would take too long, so really I need the browser to remember the DOM when it comes back to the page, or cache it some how.
Is there a solution to this?
Many thanks
Sure there is and it's a piece of cake. Well, it's a cookie, actually :)
You don't need much to solve this problem.
First, get some cookie here: Cookie API
Second, you'll have to encode the data in the cookie somehow. If you have multiple pages like that one, you'll have to separate them somehow or use a key-value pair and store something like this:
manchester=3522
Whenever you enter the page, load the cookie, wait the page to be fully unrolled (you use AJAX or similar, you'll have to wait for the page being unrolled, window.onload won't do).
If there is no cookie, skip this step:
scroll the page down to the offset you have loaded from the cookie: scrollTo
Next, whenever the page is scrolled, modify the cookie. To avoid thrashing you'll want to do this in a polling manner. Use setInterval() at maybe 500 milliseconds and check if the user changed the scrolling position. If he did, save the cookie with the new value.
Sorry...can't show any significant code because it is too deeply buried within an app but I think I can describe the problem easily. I have a 2 page form that has a large amount of content on page 1 and just a very small amount on page 2. Switching to page 2 is handled by the following:
$('#B2').on('click', function () {
if ($('#page1').valid()) {
// code to show page 2
$('#page1').hide();
$('#page2').show();
All works very well except that when the user is presented page 2 it is very far down the page...the same "relative spot" as they were on with page 1 but it seems to the user as if they are seeing a blank page. If they scroll up they will eventually see the page 2 content. I want to somehow force this window scroll. (Another little "gotcha" is that all of this is in a "wrapped" container within a CMS.) The only thing that seems to work is to actually press the up arrow several times or scroll the mouse wheel.
I have tried to add each of the following lines (individually) immediately after the $('#page2').show();
window.scrollBy(0,-400);
window.scrollTo(0,0);
Any ideas as to what else I can try?
You need to target something on the page. Target id=page2. Execute the code below after your show/hide logic.
$('html, body').animate({
scrollTop: $("#page2").offset().top
}, 2000);
I appreciate the help given...I finally just made a workaround by adding a page before my long page and forcing it to be artificially long (past the "Continue" button) so that it keeps that relative position when the real page is shown. Not exactly an elegant solution but the page added has some information that needed to be shown anyway so no big deal.
I'm building a little CoffeeScript application with 10 buttons and a container (simple). When the user press on one of the button : the container change.
The buttons look like a navbar and instead of using links (that will reload the entire page), I used javascript (Coffeescript, jquery or whatever) to change the content of the page (with some Ajax query to load data).
The problem is that the back and forward button of the browser can't work with that solution... and I need to find a solution for that. Routing maybe ?
I really like the way Asana.com resolved this issue: actually the address change but the content seems not to be entirely reloaded.
What do you suggest ? Thanks for the help
Hashes. The simplest solution is to define an URL hash every time the user clicks on a button. For example:
location.href = "#" + button.id;
With that, you create a history entry, and the user can press back or forward in the browser.
But how can you check when this happens? There's the hashchange event:
window.onhashchange = function() {
var state = location.hash.substring(1); // chomps the initial #
...
};
Basing your code on the state variable, you can trigger your AJAX calls from there.
By the way, you can change your code altogether, using links instead of buttons with an hash as the href property, which does not reload the page, but creates an history entry and fires the hashchange event.
The hashchange event is supported by every modern browser (that support history.pushState too, a more flexible and powerful way to control your history) and IE8-9.