14

I'm using the infinite scroll jquery plugin for a website ( https://github.com/paulirish/infinite-scroll )

Everything is fine except that my page is a search so...what happen is:

1) you go on the page, browser auto-locates you and give you back a list of items (eg. bars) around you...Infinite scroll is needed to avoid pagination for this list. Everything works until here...except the fact that i could reache the "end-of-the-infinite-page" and the plugin "unbinds" itself from the scroll.

2) Now....when you want to manually insert an address in the input text, you are free to do it...you write your address, and press enter...and with ajax (no page refresh)...i'll look for lat/lon, locate the address, change the navigation link for the infinite scroll....and,i feel dumb, BUT i can't figure out a way to "reactivate" or "re-bind" the plugin to the event....So my "new search results" do not have a fresh "infinite scroll" instance...

(page "split" correctly and correctly returns a json trying changing "page=NUMBER")

This is what happens in the console:

["math:", 0, 468]
jquery.infinitescroll.min.js:20["heading into ajax", 
Array[2]
    0 : "/ajax/getCoworkings/?page="
    1 : "&latitude=52.5234051&longitude=13.4113999&distance=12"
    length : 2
    __proto__ : Array[0]
]
jquery.infinitescroll.min.js:20["Using JSON via $.ajax() method"]
jquery.infinitescroll.min.js:20["Error", "end"]
jquery.infinitescroll.min.js:20["Binding", "unbind"]

After the "unbind" i'm not able to bind it again and therefore have the infinit scroll on my next search results........

John Slegers
  • 38,420
  • 17
  • 182
  • 152
ricricucit
  • 2,028
  • 2
  • 14
  • 18

8 Answers8

28

infinitescroll stores all of its instance data on the element itself via $.data, so removing that instance data is the only sure-fire way to totally reset infinitescroll.

These two lines should do the trick of cleanly destroying infinitescroll.

$elem.infinitescroll('destroy');
$elem.data('infinitescroll', null);

// now infinite scroll may be reinitialized normally without any conflicts or cruft lying around from the previous instance.

NOTE that as of June 2012, none of the previous answers worked for me with the latest version of jquery.infinitescroll (v2.0)

Pranav 웃
  • 8,094
  • 5
  • 36
  • 48
fisch0920
  • 396
  • 5
  • 8
  • 5
    I'm using v2 also, and this is the only solution that has worked for me. – Nathan Hurst Jul 11 '12 at 01:32
  • 3
    For anybody else reading this in 2019. This was only working for me with v3.0.5 when i used `$elem.infiniteScroll('destroy');` and `$elem.data('infiniteScroll', null);`. Case sensitive that is. – Florian Feb 11 '19 at 09:46
5

Solved.

i've added:

if (xhr == 'destroy') {
    $.removeData(this.element[0]);
}

in function

_error: function infscr_error(xhr) {

on line 228.

Probably that's not the best way of doing this, but it's exactly what i needed.

And what i do -now- is basically what you suggested:

1.

$("#myelement").infinitescroll("destroy");

2.

$("#myelement").infinitescroll(WHATEVER_SETTINGS);

...without the need to modify the "pathParse" values
but that's because i'm modifying the selectors (next/nav)
before, with jQuery.

ricricucit
  • 2,028
  • 2
  • 14
  • 18
  • i had also to comment this line //$(opts.navSelector).hide();, for it to work correctly, it was giving incorrect results for opts.pixelsFromNavToBottom since we're hiding the element, this didn't matter before if you was creating the plugin once, but in our case it's created more than and causes a wrong value for pixelsFromNavToBottom – Yehia A.Salam Apr 09 '12 at 22:44
  • NOTE: this solution doesn't appear to work anymore as of June 2012. – fisch0920 Jun 22 '12 at 07:26
3

After trying the other solutions to no avail, this worked for me:

$(window).unbind('.infscr');

Reference 1/4 down the docs: http://www.infinite-scroll.com/infinite-scroll-jquery-plugin/

Stephen Saucier
  • 1,635
  • 15
  • 17
3

It isn't mentioned here, but (in my version of Infinite Scroll anyway) you also have to set two variables for the re-instantiaion of InfiniteScroll to work. You also have to Rebind it. Here is the code:

$('#cardContainer').infinitescroll('destroy'); // Destroy

// Undestroy
$('#myContainer').infinitescroll({                      
    state: {                                              
        isDestroyed: false,
        isDone: false                           
}
});

InitInfiniteScroll(); // This is a wrapper for the standard initialization you need

// Re-initialize
$('#myContainer').infinitescroll('bind');
vannorman
  • 134
  • 1
  • 12
2

I've had to do something similar since my code updates the destination url depending on user action rather than just relying on a counter.

I ended up implementing the following reset method that I can then call using $container('reset');

reset: function infrscr_reset() {
        this.options.state.isDone = false;
        this.options.state.isDuringAjax = false; // I needed this, others may not
        this._resetmsg();
        this._binding('bind');
    },

I also implemented a private method to reset the hover message since otherwise it would continue to give a "no more pages" notification.

_resetmsg: function infscr_resetmsg() {
        var opts = this.options;
        opts.loading.msg = $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>');
        this._debug('Reset loading message');
    },
Dan Goldin
  • 867
  • 12
  • 31
1

The item 3)

if (xhr == 'destroy') {
    $.removeData(this.element[0]);

}

Did not work as well. At least with the latest version. The masonry complains about 'cannot call methods on masonry prior to initialization; attempted to call method 'reload''

$container.css('display','none');
$container.html(htmlOutput).imagesLoaded( function(){
             $container.css('display','block');
             $container.masonry('reload');
});

// I have to do this in order to "reset" the stage
$container.infinitescroll('destroy'); // Destroy

// Undestroy
$container.infinitescroll({                      
   state: {
      isDestroyed: false,
      isDone: false
   }
});

// Init.
$container.infinitescroll({
   navSelector  : '#page-nav',    // selector for the paged navigation 
   nextSelector : '#page-nav a',  // selector for the NEXT link (to page 2)
   itemSelector : '.tile',     // selector for all items you'll retrieve
   loading: {
     finishedMsg: '',
     msgText: '',
     img: url + 'img/ajax-loader.gif'
   }
},
// trigger Masonry as a callback
function( newElements ) {
    // hide new items while they are loading
    var $newElems = $( newElements ).css({ opacity: 0 });
    // ensure that images load before adding to masonry layout
    $newElems.imagesLoaded(function(){
        // show elems now they're ready
        $newElems.animate({ opacity: 1 });
        $container.append($newElems).masonry('appended', $newElems, true); 
    });
 }
);

// Re-initialize
$container.infinitescroll('bind');
bicatu
  • 85
  • 9
1

Presuming you created infinite scroll like:

//This will initiate with default values for example purpose
$("#myelement").infinitescroll();

Could you not then simply completely destroy the instance:

$("#myelement").infinitescroll("destroy");
//Reset anything else that may cause the page to blow up here
//And then create a new instance with different path variables:
//Note, obviously you'll be initializing it with custom selectors/settings etc so include those as well
$("#myelement").infinitescroll({pathParse:["/ajax/getCoworkings/?page=","&latitude=52.5234051&longitude=13.4113999&distance=12"]});

Essentially if you don't define pathParse, the script tries to work it out itself. If you do then it uses what you provide. Its not very elegent, more of a hack than anything but changing pathParse isn't strictly supported in infinite-scroll at the moment.

Beaver6813
  • 2,090
  • 1
  • 12
  • 6
  • That didn't help, i've still got the same issue, no new ".infinitescroll()" neither after "destroy" :-| – ricricucit Oct 29 '11 at 13:19
  • Ahh good thinking with the removeData() function. I think its something that needs to be brought into the plugin's destroy function. Its difficult because effectively you're trying to destroy the instance from within instance itself! – Beaver6813 Oct 29 '11 at 17:10
  • is this comment related to my answer but placed in the wrong place? :P – ricricucit Oct 29 '11 at 17:36
0

you can do this by just adding the following code into your infinite scroll declaration.

errorCallback : function() {
    isc.getContainer().infinitescroll('destroy');
    $.removeData(this);
},

Note not in infinitescroll.js file, it should be in your custom infinite scroll declaration.

Vijay Shegokar
  • 2,252
  • 1
  • 18
  • 29