Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to write an "Infinite Scroll" javascript that can handle the back button?

Go here: http://www.infinite-scroll.com/ Play with the infinite scroll. Notice that you can't click a link and then hit "back". It has glitches when you do that.

So, I plan on writing my own Infinite scroll.

  • When the user gets to the bottom, load an AJAX call. Then do a JQuery "append" the result to the div. Then, call my other functions on those elements. (I set the background images of all those elements in javascript).

Will this work? If I do that...will I be able to handle the back button?

like image 582
TIMEX Avatar asked Dec 10 '10 09:12

TIMEX


2 Answers

I considered the very same thing on a project I worked on. One option I thought about was to allow the back button to return to the place where the link was clicked (just like normal browsing).

Firstly, you need to record what page of the infinite scrolling your on so that you can load up to that section again. You can do this with some clever playing around with the window.location.hash value. If you look at my answer to this question, I explain in more detail how to do it in plain JavaScript or jQuery using Asual's address plugin.

The basic part of it would like like this:

// Whatever you're using to load the next page
function scrollToNextPage(page){
   // Your infinite scrolling stuff
   $.address.parameter("currentPage", page);
}

$.address.externalChange(function(){
   var page = $.address.parameter("currentPage"),
       top = $.address.parameter("linkTop");

   loadAjaxUpTo(page);   
   $('html, body').animate({ scrollTop: top }, 500);
});

// Set a parameter for the location of a clicked link
$("a").live('click', function(){
   $.address.parameter("linkTop", $(this).scrollTop());
});

I didn't implement the last bit (getting the position of the link clicked) but I can't see why it wouldn't work. It would cause the window to scroll nicely to where you where. You can always set it with an anchor to the loaded page instead (but when you scroll to it, it will always go to the top of the page).

A couple of points though, I wouldn't recommend this. At least for the project I was doing, it wasn't really necessary. In my project, we expected the user to go back to change their options and figured that scrolling wouldn't be a problem (although we didn't have that many pages to scroll through). The AJAX (and your JavaScript to set the images) needs to be loaded and executed again which takes a lot of time depending on how many pages you need to reload. On top of the time to scroll to the link (you could just window.scrollTo but you don't get animation so everything is very jerky. You could always just load the page the person was on and forget about the previous pages, but you're still breaking the user experience that way. Or (what I tried) was to implement a two way infinite scroll. So it would load the page the user clicked from and prepend the previous pages if they scrolled up - this was too much work for what it was though.

Another point is that, if you were to still do it, you want to use a GET request to get your pages (and make sure the cache isn't set to expire immediately). I found that pages requested by Ajax with the GET request would take from the cache (at least on some of the browsers I tried). Sending your details over a POST will always ignore the cache.

like image 143
Jonathon Bolster Avatar answered Nov 14 '22 23:11

Jonathon Bolster


The only way to be able to handle the back button is to alter the location hash (the bit after the # symbol). Handling pressing of the back and forward buttons can be done in two ways:

  1. Have an <a name="bookmark1"></a> which is unique to each section added, and change the location.hash to match it.
  2. Use a setInterval with a short time like 100ms to watch the location.hash for changes and go to the required part of the page. You have to do this because you can't actually detect when the back/forward buttons are clicked.

This is an implementation of the second method to show you how it works. In this, each ajax request contains <a name="ajax-section-1"></a> and ajax-section-2 etc.

function addToBottom(htmlToAdd) {
    $('#main-div').append(htmlToAdd);
    window.location.hash = $('#main-div a[name^=ajax-section-]').last().attr('name');
}
like image 37
Nathan MacInnes Avatar answered Nov 15 '22 00:11

Nathan MacInnes