4

I am making a module for the Joomla! page of a client that uses Ajax to render different queries to the database. The result of these queries is that I regenerate the entire HTML code of the different DIVs. Within my jQuery Object I have a function named as cache() that stores all objects that I need to attach them the different events. My problem is that every time I regenerate the HTML code from any of these divs, I have to rebuild all the objects, so I've created a new function recache() to make this work more easy.

I guess this is not the best procedure. Is there any way to keep alive these handlers without having to call this function cache() each time, or is there any way to rebind dynamically this objects?

Thank you!

Here my code:

    var Object = {
        init: function() {
            this.cache();
            this.bindEvents();
            return this;
        },

        cache: function() {
                   OBJECTS....
                       this.nameObject = $('#anchor');
                       etc..
        },

        recache: function() {
            Objects to be recached as needed.
        },

        bindEvents: function() {
            EVENTS attached to the objects. 
                        this.nameObject.on( 'click', 'context', this.nameFunction );

        },

                    nameFunction: function() {
                        #CODE....
                    }

                }; //END Playlist (Object)

window.Object = Object.init();

I usually use on() function instead of delegate(), live() or bind(), butI'm not sure this is exactly my problem.

Thanks in advance!

SomeKittens
  • 38,868
  • 19
  • 114
  • 143
Alberto
  • 151
  • 1
  • 8

2 Answers2

11

You hinted at the right plan: use .on(). Remember though that when you're delegating a listener, you need to delegate to a listener that will not be destroyed.

Or in other words:

// will not do anything useful for this scenario:
$('.something').on('click', function() { /* ... */ });

is different from

// use the document as a listener: will work but not efficient
$(document).on('click', '.something', function() { /* ... */ });

which is different from

// use a closer ancestor that is NOT destroyed. Best option if you can
$('#someAncestor').on('click', '.something', function() { /* ... */ });
Greg Pettit
  • 10,749
  • 5
  • 53
  • 72
  • Upps! We're so sorry, you're right! Exactly the context of the on() method of the functions in question are destroyed when I regenerate the HTML code. This is the reason of having to recache these objects. I'm feel like a newbie. ;) ;) THANKS!! – Alberto Mar 30 '12 at 14:23
  • Cool beans. I only mention this because you're new to SO, but if this answer helped, you can "accept" it with the checkbox icon to the left, once a certain amount of time has passed (15min? can't remember) – Greg Pettit Mar 30 '12 at 14:30
  • Finally I refactored my application changing all the events to the ancestors, and except for some minor problems with Safari also solved, all works like a charm now. Thanks!! – Alberto Mar 30 '12 at 21:23
4

Bind the event handler on a parent element and use event delegation to handle the events. By binding the event handler on a parent element you don't need to bind it on all the child elements.

/HTML/

<div id="container">
    <button id="button1" class="click">button with click</button>
    <button id="button2" class="click">button with click</button>
</div>

/Javascript/

// use this
$("#container").on("click", ".click", function(){
    alert(this.id + ": I've been clicked.");
});

// don't use this
$(".click").on("click", function(){
    alert(this.id + ": I've been clicked.");
});
jeremysawesome
  • 7,033
  • 5
  • 33
  • 37