Seamless pagination with "pjax"

Hi!

Anyone has found a workaround to the page load animation issue?

Thanks!

Hey there.
I was so happy to find this solution, cause the pagination is driving me crazy.
Unfortunately, I can’t make it work.

Are there anyone out there willing to help me out with this?
Please? @forresto ?

That worked for me too. Thanks so much @iwan_r

why this not working with page load animation ?

Hi everyone! This topic resolved my problem with the scroll to top of page after clicking on the “next/previous” button, thanks. But I can’t resolve the problem with lightbox. After click on the “next/previous” button of my lightbox pagination, the lightbox not work anymore.

Someone had resolved this problem?

Thanks

If anyone is using the newer Pjax library and is still having trouble reinitializing page related animations, I was able to get them working by grabbing the destination page “data-wf-page” attribute and setting the current html attribute to match.

/**
   * Pjax navigation grab the attrs from the new page
   */
  pjax._handleResponse = pjax.handleResponse;
  pjax.handleResponse = function(responseText, request, href, options) {

    // get the new data-wf-page within the request text
    var data_wf_page = request.responseText.match(/data-wf-page=\"([a-z 0-9]+)\"/);
    if (data_wf_page && data_wf_page[1]) {
      self.data_wf_page = data_wf_page[1]; 
    } 
    pjax._handleResponse(responseText, request, href, options);
  }

  /**
   * Pjax navigation hooks for webflow interactions
   */
  $(document).on("pjax:complete", function () {
    window.Webflow && window.Webflow.destroy();
    
    // set the current data-wf-page to the new attribute 
    // before reinitializing interactions
    $('html').attr('data-wf-page', self.data_wf_page); 
    
    window.Webflow && window.Webflow.ready();
    window.Webflow && window.Webflow.require("ix2").init();
    document.dispatchEvent(new Event("readystatechange"));
  });
1 Like

Thank you for this!! Doing some initial tests and it’s working great so far with interactions on the pages I’ve tested. Had been struggling to get Barba JS working with interactions for days with no luck.

Only thing I’ve noticed is that Pjax adds a “?t=” variable followed by a string of numbers to URLs after page changes (not related to the data-wf-page fix)… is there a way to turn that off? Couldn’t find anything in the docs and I’m new to Pjax so not sure if there’s a quick fix or if it’s a necessity?

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 https://github.com/MoOx/pjax

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: https://www.udc2.jp/#tabs (“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,
    }