jquery-pjax icon indicating copy to clipboard operation
jquery-pjax copied to clipboard

Back and forward bug

Open elfassy opened this issue 12 years ago • 13 comments

  • load a page
  • click browser back button
  • click browser forward button

then i see double every javascript enhanced elements (example twice the drowp down field, twice the RTE...). Can anyone else reproduce this problem?

i'm using

$(document).on("pjax:end ready", function(){
 ...
}

with pjax:complete or pjax:success I don't get duplicate dropdowns, but i can't select them after going back and forth. thanks for the help!

elfassy avatar Oct 01 '13 15:10 elfassy

Not sure if this will fix your issue, but it might help you someway. I was having an issue where clicking a pjaxed link, then clicking back, then forward would cause duplicate content to be show in the pjax target area. There were two items together that where causing this issue:

1.) My pjax initializing call was using a class for the container selector (e.g. $(document).pjax('a[data-pjax]', '.pjax-container')). 2.) The server was returning a block of markup which included the same pjax target container. When pjax went to replace the content initially, it would end up with the below structure. Once back and forward where clicked, pjax would end up replacing twice, due to multiple .pjax-container elements existing.

<div class="pjax-container">
    <div class="pjax-container">
        ...
    </div>
</div>

Altering the server-side to return just the inner content fixed the problem for me.

kfriend avatar Jan 10 '14 19:01 kfriend

I think you want get back button working as expected without window.location.reload()

Just try it with some js library like jQuery UI or Google maps... Do some element or map in one page loaded with pjax, and hit back button. gmap will become some strange static image creation, jQuery UI element want be properly instantated at all, and it will be broken and unusable.

tzoro avatar Jan 17 '14 10:01 tzoro

pjax:success not work for me. When I click back button all my js not initialize. I mean all my dropdown menus, checkboxes are just FROZEN. And I can't select them at all :(. Any idea?

Here is the example I'm using pjax:success event with jQuery ready event:

$(document).on 'ready pjax:success', ->
  // My code goes here

I also tried to re-trigger pjax:success event. Here is the code:

$(document).pjax('a[data-pjax]', '.pjax-container')

popStateActivated = false

$(document).on 'pjax:end', (e)->
  if popStateActivated
    $(document).trigger('pjax:success')
    popStateActivated = false

$(document).on 'pjax:popstate', (e)->
  popStateActivated = true

But no luck..... :(

zolzaya avatar May 27 '14 02:05 zolzaya

Please don't re-trigger the pjax:success event artificially. If you want to be informed of any pjax navigation, be it an XHR request or on browser back button (restoring content from cache instead of XHR) use the pjax:end event.

We can't know why your JS components don't work after pjax because we don't know which JS libraries are you using and how do they bind with the HTML elements. If anything on your page needs re-initializing after navigation, do it in the lines of this:

$(document).on 'pjax:end', (event) ->
  $(event.target).find('.my-widget').initializeWidget()

mislav avatar May 27 '14 04:05 mislav

@mislav okay thank you for advice. I will follow it :)

zolzaya avatar May 27 '14 04:05 zolzaya

Whoops, fixed my code example by changing $(this) to $(event.target) in the event handler.

mislav avatar May 27 '14 04:05 mislav

The same issue I have with flickity carousel. On first load slider is initialized on document:ready. But if I go to another page and then go back using 'browser's back' button slider doesn't work or initialized twice.

neilhem avatar Jul 02 '15 14:07 neilhem

One workaround that worked for me is to let the page refresh on back/forward buttons. Here is the (I guess) ugly solution I came up with:

$(document).ready(function(){
    initializePage(); // Contains the initialization scripts for the plugins.
});

var pjax_called = false; // Executes on page load.
$(document).on("pjax:complete", function() {
    initializePage();
    pjax_called = true; // Prevent the reload
});

$(document).on("pjax:end", function() {
    if(!pjax_called)
        window.location.reload();
    pjax_called = false; //reset
});

The idea is that the complete event is called when there is a pjax request whereas the end event is called on both pjax requests and back/forward button clicks.

Any suggestions? Please let me know.

iuysal avatar Jan 28 '16 20:01 iuysal

I use pjax:beforeSend event to destroy slider & reinitialize after pjax:end. So even after back/forward navigation slider works as it should.

neilhem avatar Jan 29 '16 09:01 neilhem

I'm setback by this back-forward issue too.

When using 'complete' my js stops working. When using 'end' my js gets doubled. (datatables.js in my case)

There's gotta be something less hacky / tailored to a specific plugin.

legshooter avatar Mar 10 '16 03:03 legshooter

First I tried:

$(document).on('pjax:popstate', function (event) {
    event.preventDefault();
    location = event.currentTarget.URL;
});

But event.preventDefault() doesn't work, as documented in the intersection of the pjax:popstate row and the cancel column in the events table. So the result is a regular cached back/forward behaviour that messes up js plugins (in different ways, depending on the use of complete/end as I described above), and briefly thereafter the reload occurs. Blechs.

Then I found out we can just use: $.pjax.defaults.maxCacheLength = 0; And now back/forward behave just like clicking a link. Unless I am missing something, this solves the back/forward issues.

P.S. Mind the fact that you have to declare it as a default: #593

legshooter avatar Apr 23 '16 16:04 legshooter

Did someone found a solution for this? I am searching for 3 hours and found nothing good related. I have the same problem with back button, js plugins like dropdowns , menu`s etc are stuck.

AlsonicTech avatar Jan 23 '17 15:01 AlsonicTech

I was having doubled content when clicking back button (had two pjax containers), and @legshooter's suggestion worked for my case - $.pjax.defaults.maxCacheLength = 0;

eduardo-haddad avatar Aug 22 '17 18:08 eduardo-haddad