This repository has been archived by the owner. It is now read-only.

Callbacks get duplicated when a page is visited multiple times #14

Closed
ghiculescu opened this Issue Dec 27, 2012 · 4 comments

Comments

Projects
None yet
4 participants

There's two pages that link to each other. Let's call them Page A and Page B.

Page A looks like;

<a href="pageb">page b</a>

And page B looks like:

<a href="pagea">page a</a>
<script type="text/javascript">
 $(document).ready(function() {
    console.log(window.location.href)
  });
</script>

Start on page A, and navigate to page B; the page's URL will be logged once. Navigate back to page A, and the URL will be logged again. Navigate back to page B, and it will be logged twice. Basically, an additional .ready() handler will be added each time, so after a while you might find the events from page B being run 10 times each time you go from one page to the other.

It's late at night so I haven't been able to think of an elegant solution. But I imagine that checking for duplicates at line 35 (https://github.com/kossnocorp/jquery.turbolinks/blob/master/src/jquery.turbolinks.coffee#L35) would work. Every .ready() callback should only be called once per page:load, I think.

I doubt it makes a difference, but I'm using Chrome 23 on OS X.

Secondary issue;

In my project, the initial issue came up because I have some object initialisation that only happens on one particular page;

<script type="text/javascript">
 $(document).ready(function() {
    window.handler = new Handler().init();
  });
</script>

So I'll have to modify the init() function to only act if it's on the right page. Unless this project could somehow solve that problem too?

One workaround is to remove the $(document).ready(), and just move the <script> block to the bottom of the page. This feels riskier; I'd prefer to use $(document).ready() wherever possible.

I think this is a sacrifice of overloading the set ready event. Every time a new page comes in it re runs the inbound .ready(), and hence duplicates your event.

Is there a way to access the non overloaded on .ready()? This would allow the best of both worlds. The blind rewrite to make 3rd party code just work. And have the developer decide what really needs to run on initial dom ready?

Collaborator

rstacruz commented Jan 24, 2013

Here's how I'd do this:

Solution 1: move the code to a JS file

Move the code to a JS file instead of putting it inline in a <script> tag.

Your problem with this, though, is that it'd be called on all pages, while you only intend it to work on a certain page. To get around this, add a class to the <body> tag that marks the correct page:

$(function() {
  if ($("body").is(".profile-page") {
    window.handler = new Handler().init();
  }
});

Solution 2: Don't use a document.ready wrapper

It's redundant: since your intention is for it to run after all DOM elements are in place, and your scripts are placed after all the DOM elements (presumably), there's no need for you to wrap it in a $(document).ready wrapper.

<script>
    window.handler = new Handler().init();
</script>

I ended up using Solution 2.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.