0

First let me say this has caused me hours of agony, and I've tried my best to find resources and grasp why this is happening.

  1. I have a file browser that works off AJAX.
  2. When I load a new directory, I have to re-initialize event handlers
  3. When I change directories, it stacks.

So if I go to say files/../files/.. to get back to the root (twice), it fires 4 times.

I have tried unbinding with .off(), I've tried restricting with .one(), I've tried resetting ALL binds with $(document).find('*').off() and with specific events, I have tried e.stopPropagation();.

Nothing seems to work. This is driving me nuts. If I don't re-initialize the system, the new content loaded via AJAX does not receive the binds. If I do, it stacks. Please help!

//previous method
file.on('click',dothis);
//method that actually works
files.on('click','a',dothis);
random_user_name
  • 23,924
  • 7
  • 69
  • 103
Casey Dwayne
  • 2,069
  • 1
  • 14
  • 31
  • 1
    If you use event delegation, you shouldn't need to reinitialize event handlers. – Barmar Apr 10 '14 at 23:11
  • 3
    Please post the minimum amount of code that demonstrates the problem. – Barmar Apr 10 '14 at 23:12
  • 1
    See http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – Barmar Apr 10 '14 at 23:13
  • 1
    Look at the [selector] parameter in jQuery's .on(). This will allow for event delegation to where you should no longer need to add/remove event bindings. – Ben Apr 10 '14 at 23:13
  • Out of all the posts I looked at prior to asking, not one mentioned event delegation. This is a real lifesaver. Thank you! – Casey Dwayne Apr 10 '14 at 23:18
  • If you think event delegation is important and relevant to the other questions, consider adding a comment or answer so that it will be helpful to others. – crockeea Apr 11 '14 at 01:28

2 Answers2

1

Rather than trying to clear all event handlers and then reinstall everything, there are two much cleaner ways to solve your issue:

  1. You can reinitalize ONLY the newly loaded HTML so you don't get any double event handlers on existing content. The usual way to do this is to scope the selectors for adding event handlers to the new content to the parent object of the new content by putting it's selector at the start of your selector or passing it as the context (the 2nd argument).

  2. You can switch to use delegated event handlers on a static, common parent so you don't have to reinitialize the event handlers at all, even for dynamic content.

For delegated event handling, you would use event handlers of this form:

$("some static parent selector").on("click", "child object selector", fn);

The static parent selector needs to NOT be dynamically loaded itself and the dynamic content needs to be a child of it. You can even use $(document) for the static parent, but it is better (for efficiency of event routing) to select a parent that is closer to the dynamic content.

Here are a few popular references on delegated event handling:

jQuery .live() vs .on() method for adding a click event after loading dynamic html

Does jQuery.on() work for elements that are added after the event handler is created?

Should all jquery events be bound to $(document)?

JQuery Event Handlers - What's the "Best" method


For reinitalizing only the newly loaded HTML, you can just prefix your selectors with the parent of the newly loaded content:

$("#parentOfDynamicContent .myAnchors").on("click", fn);

Or, like this:

$("#parentOfDynamicContent").find(".myAnchors").on("click", fn);
Community
  • 1
  • 1
jfriend00
  • 580,699
  • 78
  • 809
  • 825
0

Are you sure you're setting .on() on your inserted elements parent? on() doesn't listen to elements inserted before it was set, you need to set it to a DOM parent.

Code would help, maybe just where you set on() and off() and some basic html structure.

Example usage:

$('#parent').on('click', 'a', function(e) {

});

This will listen to all clicks on a elements inside #parent.

Skoua
  • 2,690
  • 3
  • 37
  • 44