Seamless pagination with "pjax"

Not sure, assume it is probably part of the pjax internal routing

A working clonable example would be great for using Barba JS and a simple page transition and webflow interaction Reintialize. In this forum article everyone is also looking for a solution.

@iwan_r and @steelwool you guys are only working with barba v1 right?

Maybe youā€™ve already seen this: https://barba-js-base-transition-webflow-reinit.webflow.io
Itā€™s a working Barba JS sample using V1 (but not the new V2).

Iā€™ve actually just found a really elegant, easy solution for page transitions/preloading etc. using Swup JS. All page and Webflow animations/interactions seem to be working, along with lightbox, collections etc. Itā€™s slightly different from Barba, but has similar capabilities through some added plugins. Itā€™s actually much easier to implement (at least has been for me). Hoping to publish a clone-able sample in the next couple days!

1 Like

Im not using Barba, just Pjax GitHub - MoOx/pjax: Easily enable fast Ajax navigation on any website (using pushState + xhr)

Iā€™ve implemented the original solution on a client site of mine, works great even within multiple tabs:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>

<script>

  var containerSelector1 = '#seamless-replace1';  
    $(document).pjax(
    '#w-pagination-wrapper1 a',
    containerSelector1,
    {
      container: containerSelector1, 
      fragment: containerSelector1,
      scrollTo: false,
      timeout: 2500,
    }
  );
  
    var containerSelector2 = '#seamless-replace2';  
    $(document).pjax(
    '#w-pagination-wrapper2 a',
    containerSelector2,
    {
      container: containerSelector2, 
      fragment: containerSelector2,
      scrollTo: false,
      timeout: 2500,
    }
  );
  
    var containerSelector3 = '#seamless-replace3';
  
  $(document).pjax(
    '#w-pagination-wrapper3 a',
    containerSelector3,
    {
      container: containerSelector3, 
      fragment: containerSelector3,
      scrollTo: false,
      timeout: 2500,
    }
  );

    var containerSelector4 = '#seamless-replace4';

$(document).pjax(
  '#w-pagination-wrapper4 a',
  containerSelector4,
  {
    container: containerSelector4, 
    fragment: containerSelector4,
    scrollTo: false,
    timeout: 2500,
  }
);

  // These 3 lines should reinitialize interactions
  $(document).on('pjax:end', function() {
    Webflow.require('ix2').init();
  });
</script>

However, Iā€™m trying to implement a function on mobile that scrolls back up to the top of the collection list (tabs menu) since Iā€™m showing 3 list items at a time, which are taller than the mobile device viewport:

<script>
$("#next-seamless").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $("#tabs").offset().top
    }, 2000);
});

$("#back-seamless").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $("#tabs").offset().top
    }, 2000);
});
</script>

It works the first time you call it, but never a second timeā€¦ anybody got any idea on what Iā€™m missing?

Hereā€™s the read-only link: https://preview.webflow.com/preview/udc2?utm_medium=preview_link&utm_source=designer&utm_content=udc2&preview=d88d261764d5b131e3557909f3301b1b&mode=preview

Here is the section in question on the page: ęŸć‚¢ćƒ¼ćƒćƒ³ćƒ‡ć‚¶ć‚¤ćƒ³ć‚»ćƒ³ć‚æćƒ¼ (UDC2) | 惈惃惗 (ā€œAND MOREā€¦ā€ button)

Cheers everyone and thanks to @forresto for the original solution

/ John

Edit:
Helloā€¦
Guysā€¦?
Does javascript guru @samliew still roam around here?

Edit2:
Is there a Webflow discord channel or something thats active?

I assume what you are missing is that you have to rebind your event listeners when you paginate or navigate with pjax. It is possible that pjax replaces the target elements $("#next-seamless") when it loads new content.

What I do is have a function called onPageChange() within the global site scripts that I call whenever pjax completes a request. In that function I bind everything dependent on dynamic elements of the DOM.

$(document).on('pjax:end', function() {
   Webflow.require('ix2').init();
   onPageChange();
});

// executed every time pjax makes a request
function onPageChange() {
   $('#next-seamless').click(...) 
}
1 Like

@steelwool Thank you so much for reaching out! I was beginning to lose hope there for a secondā€¦

Okay, so at first I didnā€™t get that I was supposed to replace the ā€œā€¦ā€ inside the brackets in your example with my own code, but once I figured that out, some progress was made.

Now the scrolling works each time the BACK-button (#back-seamless) is pressed, but not the ā€œ#next-seamlessā€ buttonā€¦ This is the code I came up with, what have I done wrong with it?

// These lines should reinitialize interactions
$(document).on('pjax:end', function() {
   Webflow.require('ix2').init();
   onPageChange();
});

// executed every time pjax makes a request
function onPageChange() {
   $('#next-seamless').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
};

// executed every time pjax makes a request
function onPageChange() {
   $('#back-seamless').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
};

You are overwriting the ā€œonPageChangeā€ function by defining it twice. Just defining it once with both click listeners inside it and it should work.

// executed every time pjax makes a request
function onPageChange() {
   $('#next-seamless').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 

   $('#back-seamless').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
};
1 Like

@steelwool Wow, thanks for the super-quick response! That makes sense! I did the change and while it didnā€™t work on the first click now, I added the original next-seamless snippet on the top of the script to make sure it is ready once before pjax initializes and now it seems to work beautifully! Thanks again for your help, itā€™s really appreciated!!

The full script if anyone else encounters the same scenario in the future:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>

<script>

$("#next-seamless").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $("#tabs").offset().top
    }, 2000);
});

  var containerSelector1 = '#seamless-replace1';  
    $(document).pjax(
    '#w-pagination-wrapper1 a',
    containerSelector1,
    {
      container: containerSelector1, 
      fragment: containerSelector1,
      scrollTo: false,
      timeout: 2500,
    }
  );
  
    var containerSelector2 = '#seamless-replace2';  
    $(document).pjax(
    '#w-pagination-wrapper2 a',
    containerSelector2,
    {
      container: containerSelector2, 
      fragment: containerSelector2,
      scrollTo: false,
      timeout: 2500,
    }
  );
  
    var containerSelector3 = '#seamless-replace3';
  
  $(document).pjax(
    '#w-pagination-wrapper3 a',
    containerSelector3,
    {
      container: containerSelector3, 
      fragment: containerSelector3,
      scrollTo: false,
      timeout: 2500,
    }
  );

    var containerSelector4 = '#seamless-replace4';

$(document).pjax(
  '#w-pagination-wrapper4 a',
  containerSelector4,
  {
    container: containerSelector4, 
    fragment: containerSelector4,
    scrollTo: false,
    timeout: 2500,
  }
);

// These lines should reinitialize interactions
$(document).on('pjax:end', function() {
   Webflow.require('ix2').init();
   onPageChange();
});

// executed every time pjax makes a request
function onPageChange() {
   $('#next-seamless').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 

   $('#back-seamless').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
};

</script>

Update:

I was able to make it work for all the other tabs as well, but I had to add separate IDā€™s for the buttons in the other tabs. Full code for future reference!:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>

<script>

$("#next-seamless").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $("#tabs").offset().top
    }, 2000);
});

$("#next-seamless2").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $("#tabs").offset().top
    }, 2000);
});

$("#next-seamless3").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $("#tabs").offset().top
    }, 2000);
});

$("#next-seamless4").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $("#tabs").offset().top
    }, 2000);
});

  var containerSelector1 = '#seamless-replace1';  
    $(document).pjax(
    '#w-pagination-wrapper1 a',
    containerSelector1,
    {
      container: containerSelector1, 
      fragment: containerSelector1,
      scrollTo: false,
      timeout: 2500,
    }
  );
  
    var containerSelector2 = '#seamless-replace2';  
    $(document).pjax(
    '#w-pagination-wrapper2 a',
    containerSelector2,
    {
      container: containerSelector2, 
      fragment: containerSelector2,
      scrollTo: false,
      timeout: 2500,
    }
  );
  
    var containerSelector3 = '#seamless-replace3';
  
  $(document).pjax(
    '#w-pagination-wrapper3 a',
    containerSelector3,
    {
      container: containerSelector3, 
      fragment: containerSelector3,
      scrollTo: false,
      timeout: 2500,
    }
  );

    var containerSelector4 = '#seamless-replace4';

$(document).pjax(
  '#w-pagination-wrapper4 a',
  containerSelector4,
  {
    container: containerSelector4, 
    fragment: containerSelector4,
    scrollTo: false,
    timeout: 2500,
  }
);

// These lines should reinitialize interactions
$(document).on('pjax:end', function() {
   Webflow.require('ix2').init();
   onPageChange();
});

// executed every time pjax makes a request
function onPageChange() {
   $('#next-seamless').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 

   $('#back-seamless').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
   
      $('#next-seamless2').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
   
      $('#back-seamless2').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
   
         $('#next-seamless3').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
   
         $('#back-seamless3').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
   
            $('#next-seamless4').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
   
         $('#back-seamless4').click(function() {
       $([document.documentElement, document.body]).animate({
           scrollTop: $("#tabs").offset().top
       }, 2000);
   }) 
   
};

</script>
1 Like

Thank you @forresto !!! Amazing! This should be built-in to Webflow. Bugged me for years!

Also nice trick to set scroll to number, then it jumps to the position on the page without reloading it. Useful if you have many items on the page.

  {
      container: containerSelector, 
      fragment: containerSelector,
      scrollTo: 250,
      timeout: 2500,
    }

Hi @forresto!

I have recently set up the seamless pagination on a webpage, but am having some issues with the functionality of the code. When someone clicks on the next button, the content loads in the appropriate place, but the website loses all functionality. The buttons are no longer clickable and the site has to be completely reloaded.

You can see the issue here: https://www.bennyhoertnagl.at/ - the paginated list is at the very bottom of the page under Shows.

Anybody have any idea what the problem could be or how i might be able to fix it? Many thanks in advance!

1 Like

Is there a reason why this isnā€™t built in to Webflow now? Activated with a checkbox on pagination for ā€˜keep scroll position on refreshā€™.

6 Likes

Had the exact problem, for me the custom preloader I created was causing it. Removing the page load, page trigger from interactions fixed it.

Still trying to find a way to have the preloader and the seamless pagination together.

Hey all,

@forresto Thank you for this solution but my interactions dont seem to to be reinitializing even with the extra 3 lines of code added. Specifically, after i paginate through a page my nav bar drop downs stop working. Any updated solution for this?

Thank you!

Hi,

Any reason why this would work on the webflow.io domain but not on the custom domain on Desktop? For mobile it works on both (webflow.io and custom).

The pagination reload fix in the designer doesnā€™t work currently. However!! I figured out whyā€¦ As far as I can tell there is a bug in the Designer. ā€¦ In the Designer if you go to the ā€œhome page settingsā€ and paste the code in to there, as @PixelGeek does at 10:00 it DOES NOT WORK. It seems the code placed there isnā€™t actually added to the page. (or at least mine wasnā€™t) My guess, this was broken when the Ui was updated to the new UI?, as in the video he is using the old UI in this session).
To Get This To Work, for me:

  • I had to go to the Dashboard

  • Click on the Project Settings.

  • In there, on the far right, you will find a tab for ā€œCustom Codeā€ Click it.

  • On that screen at the bottom you have the two fields similar to what was shown at 10:00 paste your code in the bottom one (ā€œAdd code before tag:ā€)

  • Click Save

  • Republish the webpage

  • You can then verify the code is in your page by (using Chrome) right click on the browser, while looking at your page, and ā€œInspectā€ the page at the bottom of the page before the tag you should find a section that contains the code that was pasted in.

1 Like

I figured this out tooā€¦ Add a refresh to the last line of the scriptā€¦ EG The last lines of your code should look like this :

  // These 4 lines should reinitialize interactions
  $(document).on('pjax:end', function() {
    Webflow.require('ix2').init();
    location.reload();
  });
</script>
2 Likes