Hacker News new | past | comments | ask | show | jobs | submit login
Retain Scroll Position in Infinite Scroll (artsy.github.io)
60 points by craigspaeth on July 10, 2014 | hide | past | favorite | 45 comments



If the page isn't infinitely tall, but instead has a known (but very tall height), having an invisible page element hundreds of thousands of pixels tall makes the scrollbar work perfectly. What content to load is determined based on the scroll position.

It also works well to let users jump halfway through a large page, or scroll through a large list faster than the content can be generated. In my implementation, I have some text that pops up (like the alphabet letter that pops up on android when scrolling quickly) with the date so that the user can scroll fast.

Note that you also need to remove elements from the DOM that are offscreen (typically above the current position) so that you don't cause the page to be too heavy.

I have a photo gallery where the search results can be viewed this way. Even with hundreds of thousands of search results, this approach works very smoothly.

I know exactly how many search results the page will have. The images are square and 200px by 200px. I display them tiled. Based on the window size I can calculate how many pixels tall to make the invisible element.

The relevant code is https://github.com/jewel/hypercheese/blob/master/app/assets/.... I've been meaning to extract this out and make it a separate library, and also create a demo page.


Things unfortunately get more complicated if you allow children of varying heights. Then, in order to know what content should be visible at a particular scroll position, you must first fetch and lay out all content that appears above it. Or cheat by storing that information in a cache somewhere.


I have tried a similar technique and discovered browser limitations in the millions or tens-of-millions pixel height range (depending on the browser), for a scrollable div. Chrome, Safari, and Firefox all refuse to add scrollable height beyond a certain limit, even when the content is taller. Have you run into the same limitations?


The site where I had all the photos needs them to be reimported at the moment, so I can't check, but I estimate it was at least 8 million pixels tall. Instead of putting the photos IN the div, I just used the div to make the page tall. It was 1px wide and 8,000,000 pixels tall. If there is some limitation, you could have multiple divs of a million pixels each, or you could set the height of the body tag.


Maybe someone can summarize why this is a problem for web developers (I'm not a web dev)?

The demo at the link seems (to me) to operate exactly like any other infinite-scroll page I've been on before...


The problem is you don't want to generate all the DOM nodes with a long list, ideally you want to have only the visible ones created.

On iOS for example, the default implementation of table, UITableView does this by reusing cells which are no longer in view to show new cells.

On web, there are some libraries that do this (airbnb had one I think, implementations for react, angular etc can be found too) but there is no clear winner.


You definitely should get on that :) That approach has been in the back of my mind for a while and I'd love to leverage a library for it.


So not only are we ignoring how scrolling is supposed to work and implementing our own version, we're now 'fixing' the browser by layering full 'screen' iframes on top of the content?

Lovely. All this to solve what issue, exactly? I've yet to see a site where infinite scrolling was an improvement. Hard to navigate, stutter, and losing my place (I know) are not improvements.

This isn't getting cleaner, this is getting more complicated by piling on 'fixes' to the 'bugs'. That should be a sign.


That's a fair point. I think there are arguments for both pagination and infinite scroll and one is not necessarily better than the other. Jeff Atwood has an interesting post on this http://blog.codinghorror.com/the-end-of-pagination/ where I think he makes a good point about "[...] once you have thousands of items to paginate, who the heck is visiting page 964 of 3810?". On the other hand infinite scroll has a slew of quirks with it too, so there are arguments both ways.


The argument that nobody is visiting page 964 of 3810 on a paginated UI seems somewhat compelling at first until you realize that nobody is scrolling down to the 964th screenful out of 3810 either, and even if they do, your infinite scrolling implementation made it more painful than necessary and is probably making them scared of clicking anything lest the whole thing get reset to 0 all over again.


Infinite scrolling is a solution required by pages that take years to load all their assets and ads where clicking the fiddly often impossible to find next link or the even hard page number: 2

The thought pattern of developers could probably be summarized as: that scroll, so infinite, much scroll.

A better solution would be to use infinite scroll technique to navigate and load pages using the history apis, correctly and changing the page URL. You end up with a seamless pageless experience with all the benefits of traditional paging but no longer have that "nightmare" usability issue of next buttons and links. I've seen this done only once, I can't quite recall but it was on something like tumblr or medium.

As for the articles approach, I have no fucking idea, a modal iframe? Seriously?


Oh boy, another discussion about infinite scroll and the way things were before JavaScript coming up...

But anyway, I spent a few minutes trying to break it on the live site, and was surprised at how graceful things worked, even with knowing what's behind it. I see that it "breaks" when you click from search, to an art piece, then to a related link...and then attempt to go back to search...but after some thought, I think that's totally reasonable. When a user goes down the rabbit hole of 2+ links, how likely is it they're going to care where they were on an infinite scroll, or any other pagination system? And of course, it's probably a minefield of browser errors if the behavior was to keep persisting the iframes and original search window.

On a related note, has Artsy done a lot of data collection in terms of how their signed-in users navigate the scroll? I figure after awhile, if I were a frequent visitor, I would quickly scroll the search and then "favorite" the things I wanted to check out, rather than visiting pieces one by one, and hoping that the "back" button would maintain my place.

(Of course, power users may opt to pop open new windows for each art piece...but that's untenable on a mobile device. Also, Etsy tried that and it in A/B testing, it apparently failed spectacularly)


I care about coming back precisely where I was. That's how it works on a normal website, that's how it should work here.

And it's very wonky, on Safari OSX. Broke it immediately. Command clicked an image to open in new tab and it did not open a new tab, but loaded it in the same tab. Then going back, it hung or something and I had to refresh the page. When I refresh, it goes back to the beginning. It should go to where I was, at the very least. And yes, opening in tabs should work too.

And it doesn't update the URL to say where I am, can't bookmark my position in the browse view. I want to. If it works on a normal page, it must work in this infinite scroll. Breaks basic user expectations.

Is this new? I remember liking the Artsy site quite a bit. It's still nice and pretty but I cannot depend on that infinite scroll. It is exactly like that xkcd. I remember seeing infinite scrolling done right somewhere, goes back to place, updates URL.


Thanks for checking this out! As you guessed it going down further than one page can cause some state headaches such as navigating into another infinite scroll view and stacking iframes inside of iframes, so I decided to cut it off after the first. I'm trying to log some caveats here: https://github.com/artsy/scroll-frame#caveats

To the data tracking question: We conducted usability tests on our fair pages (artsy.net/the-armory-show) that brought this issue to the forefront. In these tests users consistently would open artwork pages expecting not to lose their place in infinite scroll. However, we haven't dived into our data yet to discover the full range of ways in which people navigate infinite scroll lists.


Back, Forward is still broken.

That is generally the problem of re-implementing functionality that browsers already have. Edge cases are missed.


Tell me about it. If you've ever used iScroll (amazing library btw https://github.com/cubiq/iscroll) to get iPad scrolling support you'll see how deep the rabbit hole goes. I initially used it for 2013.artsy.net (source code: https://github.com/artsy/artsy-2013) and had to eventually decide to toggle it on only for iPad b/c there were too many edge cases in the browser.

But I digress. Thanks for pointing this out, hopefully we'll eventually smooth over the quirks to a reasonable degree. Logged the bug for now: https://github.com/artsy/scroll-frame/issues/12


Additional quirk: Middle-button click to open in a new tab is also broken. Right-click -> open-in-new-tab works though.

This kind of stuff, in addition to being a pain in the ass for you, the developer, is why users hate this kind of trickery. I see that I'm on an infinite-scrolling page and I say to myself "ugh, I wonder which standard browser behavior is broken due to the weird hacks they had to employ to make this crap work." Which, ironically, is one reason I habitually open things in a new tab on pages like this -- I don't want whatever hacks are being employed to cause me to lose my page state.


I think if they used `window.history.back()` instead of whatever they do now when closing the frame, and listened to the popstate event to reopen it, it would work.

That being said, yes, this is why reimplementing browser builtins hard, you have to get all the details right. That being said, hard != don't do it.


Clever. I wanted to point out there's additional issues introduced by infinite scroll; bookmarking, link sharing, etc.

It's a problem we recently tackled on our infinite scrolling page. Combining modals, pushState (on scroll) and waypoints I think we've solved the the most important problems we introduced with infinite scroll on our gallery page. Here's an example [1] and a blog post about the attention we paid to detail [2].

[1] https://current.trovebox.com/photos/page-1/list

[2] https://medium.com/p/636c0ae6e3b1


I'm not a web developer, but why can't you link to an anchor that is slightly below the header, so the view that the user sees is the same view (minus scrollbar position) they would have seen when they were originally on the page, and "infinite scroll" upwards when they scroll up, and down when they scroll down.

_______________ | header | | | | buffered | | images up | |-------------| | | | Viewport | | | | | |-------------| | buffered | | images down | | | | | ---------------

Is this somehow technically very difficult or would this screw with usability in some way that would be unintuitive?


Good questions. You can link to something below the header but I think the more interesting idea is to do the infinite scroll upwards. I agree that this approach is better than the pagination we've implemented when you link to pages 2+. It doesn't seem technically impossible but the amount of work to implement that might be significant. Here's an example...

We do the masonry layout from left to right. This means we start filling out each row from the left and can leave space on the right of the last row of a page so the next page can begin filling in the remainder of that row before starting a new one. To do this the opposite way if we're "backfilling" photos seems like it could be significantly more complex.

In essence when scrolling "up" we'd have to reverse the alignment and fill photos in from right to left. This alone makes my head hurt to think about.

But aside from our implementation I think a bidirectional infinite scroll really is the solution to work towards. It would feel much more natural that way.


I guess you aren't just filling in pictures from a list, are you? you have to find a picture that fits the space you have? If this is the case, it might be best to change the "row height" to justify the images, and ignore the "best fit" image.

Then it is just taking a list of images, and moving the "view" forward or backward on that list, right?


Very cool! Can't believe I hadn't come across this blog post earlier—I'll definitely be reading.

Totally agreed there are other more issues to tackle than scroll position. scrollFrame was a useful little hack born out of a need to solve a glaring problem on a deadline :) I wanted something that we could drop on any existing page with minimal integration effort and so far it's proven pretty useful in that regard.


Completely agreed. I definitely liked your approach. Making infinite scroll work flawlessly will be a combination of a series of "patches".

Great work.


Google's official Webmaster Central blog actually lists out a very good & SEO-friendly method of setting up infinite scrolling that solves the core goal (retaining a scrolling position) of "scrollFrame" and doesn't require iFrames.

http://googlewebmastercentral.blogspot.ca/2014/02/infinite-s...


Love how the demos for "scroll-frame" by @artsy completely blows up

http://artsy.github.io/scroll-frame https://pbs.twimg.com/media/BsNWUa5CIAECV5s.png:large


I think I've fixed the problem. I had to move the url to work around the Github cache so the new demo can be found here: http://artsy.github.io/scroll-frame/demo.html

Please let me know if you're still getting this problem. Thanks for reporting this!


Odd, what link did you click to get to that url? If you follow this link http://artsy.github.io/scroll-frame/ it should show a bunch of cute little kittens infinitely adding themselves to your page: http://cl.ly/image/1d2z2h0G3Z1U


Same here, if I follow your link I get redirected to http://artsy.github.io/scroll-frame/undefined which 404s, obviously...


I have a repro thanks to github.com/ilyakava! Looks like installing the Buffer chrome extension can expose this bug. https://github.com/artsy/scroll-frame/issues/11 Probably something weird I'm doing with pushState.


Ahh, thanks for report. Looks like I have a little way to go to ensure cross-modern-browser support. I noticed some odd things going on in Firefox. What browser/version are you using?


Same here, Firefox 30.0 on Linux Mint 16.

Clicking on one of the kittens gives me a blank page, and then clicking back brings up the list again but it has the "Loading..." overlay indefinitely.

This experience definitely didn't sway my opinion that infinite scrolling is really annoying.


This specific issue with FF should be fixed now. Check http://artsy.github.io/scroll-frame/demo.html to see if it works on your end. Thanks for checking it out :)


Chrome edge on Windows 8.1 :/


This is great. A lot of non-savvy people probably don't know how to open links in a tab to prevent this on current 'infinite' scrolling sites


FYI - clicking through to the demo pages appear be NSFW.


A recommendation: test well on iphones/ipads.

We use a similar approach in our website, and we struggled a lot with iphones/ipads for the way Safari manages the iframe height. A common solution is to use -webkit-overflow-scrolling:touch; but this made the iframe almost unusable in our settings.


Doesn't appear to work at all in Firefox 30 on Linux. Clicking one of the images after scrolling a bit (triggering the loading of additional content) leads to an infinitely spinning bar - no content ever loads. The same STR works without issue in Chrome.


Yeah I noticed that too :( Logged here: https://github.com/artsy/scroll-frame/issues/10. Hopefully there's a way around this.


Seems like a very clever workaround!

I wonder how well it works on mobile, and/or with things like jquery-mobile. Does it dramatically increase memory consumption with more content loaded simultaneously?


We use a separate mobile website for almost all of our web views so I have yet to integrate it on mobile. I assume one would have to be more careful about the performance of embedding an iframe in that context.


I love to complain about infinite scrolling, but this... is actually pretty clever. I'm not a huge fan of the everything-in-a-modal approach or URL manipulation (i.e. Discourse, which involves a lot of scroll listening and only gives you an approximation of your scroll position), so I think this is a good alternative.

Now for something a bit more ranty, in keeping with tradition: why the heck does the infinite scrolling interface at https://artsy.net/browse/artworks have a footer?


Thanks for checking it out! To the footer question—I think you just caught a bug :) Logging it!

We usually try to remove the footer e.g. on our posts page https://artsy.net/posts/featured


Ah, good to hear it wasn't intentional. =) I realized shortly after posting that comment that I'm a terrible hypocrite, cause we're actually guilty of the same thing in a couple places on our platform. Granted, we repeat the footer links in the sidebar, but still, it's something I'd like to fix.

Anyway, good work on the library, and thanks for open sourcing it!


Just open in new tab. Even on mobile it works well because the back button just closes the tab and puts you back into the other window (on android at least, not sure about iOS)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: