gsamaras
gsamaras

Reputation: 73444

Correct way of Caching and this when using jQuery

When using jQuery, caching is very important, and it seems I have forgotten the related principals. When I cache something, how can I re-use it inside function on()?

Example:

var paginationDemo = $("#pagination-demo");
paginationDemo.on('click', function() {
  var index = $('#pagination-demo').find('.active > a')[0].innerHTML;
  ...
});

As you can see here, I am calling jQuery again to find the id, shame on me! Is there a way to do it with this?

var index = this.find('.active > a')[0].innerHTML;

or:

var index = $(this).find('.active > a')[0].innerHTML;

But I am not sure what will this hold inside the body of on(). What is the correct way to do this?

Upvotes: 0

Views: 120

Answers (3)

Promil Bhardwaj
Promil Bhardwaj

Reputation: 76

To make use of variable caching just reuse the variable "paginationDemo" again inside 'on'. The second approach also works fine in this case.

var index = $(this).find('.active > a')[0].innerHTML;

Because 'this' still holds the reference to DOM object.

But this approach looses its validity inside nested functions or anonymous functions (the 'unnamed' functions). So you can save the reference to this variable to make is work (the self approach). Or use the cached variable directly (paginationDemo). eg below:

 var paginationDemo = $("#paginationDemo");
    paginationDemo.on('click', function(e) {
          var self =this;      // saving reference to this
          console.log(this);     // refers to DOM object paginationDemo

          var index = $(this).find('.active > a')[0].innerHTML; 
                                 //will work
          var index = paginationDemo.find('.active > a')[0].innerHTML; 
                                    //will work, this is caching approach

         (function (){
              //inside anonymous fun, this changed now
            console.log(this);      // this refers to "window" object now!
            var index = $(this).find('.active > a')[0].innerHTML; //won't work

            var index = $(self).find('.active > a')[0].innerHTML; 
                               //works !! lexical scope variable self used    

            paginationDemo.find('.to-be-found').text('FOUND');
                                 //works too

       })();
    });

Here is a link to how this works : this - JavaScript | MDN

Upvotes: 1

Kiran Yallabandi
Kiran Yallabandi

Reputation: 2584

From what I understand you want to use the jquery object that you created inside the call-back you registered via on as well.

From the official docs :

In addition to the event object, the event handling function also has access to the DOM element that the handler was bound to via the keyword this. To turn the DOM element into a jQuery object that we can use jQuery methods on, we simply do $( this )

But in this case as well you will have to construct the jQuery object again. Not as costly as using a selector to find an element but none the less.

One solution to the problem might be to use the event.data property

var paginationDemo = $("#pagination-demo");
paginationDemo.on('click',{ cachedElement:paginationDemo},function(event) {
  var index = event.data.cachedElement.find('.active > a')[0].innerHTML;
  ...
});

This way you can reuse the original jQuery object and acheive what you wanted from cacheing.

UPDATE :

Inside the call-back passed to on, the key word this refers to the underlying DOM object. When we use this idiom : $(this) we are constructing a fresh jQuery object. However it is not the same as the jQuery object stored in paginationDemo variable. In other words both the jQuery objects will act on the same DOM element. However their references are different

event.data.cachedElement === $(this)
>false

Upvotes: 1

jiveturkey
jiveturkey

Reputation: 31

Your second option will work:

var index = $(this).find('.active > a')[0].innerHTML;

Upvotes: 1

Related Questions