codec
codec

Reputation: 8806

Caching DOM elements javascript

I am trying to cache all the DOM elements on the page intialisation using the following code:

init:function(){
      this.cacheDom();      
    }

cacheDom:function(){
       var that = this;
       this.$jsTabs              = this.container.find('.js-tabs');
       this.$li                  = $jsTabs.find('.tabs').find('li');
       this.$filterBodyTr   =  that.container.find('#filter_body').find("tr");
       this.$customRuleInfo = that.container.find('#custom_rule_info');

    },

enableTabs :function() {

     this.$li.click(function(){
      var index  = this.$li.index(this);
      this.$jsTabs.tabs().select(index);
      if(index==2){
        ****var tr = this.$filterBodyTr;****
        tr.each(function(){
            $t = $(this);
            if($t.is(":visible")){
                if ($t.text().toUpperCase().indexOf("MY NAME") > -1){
                    ****this.$customRuleInfo.addClass("hide-data");****
                }
            }
        });
      }

  });
},

Here this.$filterBodyTr and this.$customRuleInfo remains undefined in lines marked with **** in enableTabs function. I tried using this instead of that to find the element but it always shows undefined.

Here is the html code referring the elements

<table class="table-compressed" id = "js_filter_sort">
        <colgroup>
             <col class="column-lg-3">
             <col class="column-lg-1">
             <col class="column-lg-4">
             <col class="column-lg-2">
             <col class="column-lg-2">
        </colgroup>
        <tbody id = "filter_body"> </tbody>
 </table>



<div class= "row gutter-0 clear text-left padding-left-20 padding-right-20 padding-bottom-20 padding-top-20 hide-data" id = "custom_rule_info">                                               
                                        </div>

How can I cache those 2 elements marked with ****. If I don't cache the elements and intialise var that=this; inside enableTabs function it works perfectly fine.

Upvotes: 1

Views: 4163

Answers (1)

motanelu
motanelu

Reputation: 4025

What happens is that the reference to this changes and points to something else, as such:

  • in the click function is a reference to the DOM element which triggered the event
  • in the each function is a reference of the current element you're iterating over

One practice is to save a reference to this in another variable - usually called self- and this will be available as a closure inside the other methods. To better understand how the context changes, have a look over bind, call or apply.

In the meantime, try this:

init:function(){
  this.cacheDom();      
}

cacheDom:function(){
   this.$jsTabs         = this.container.find('.js-tabs');
   this.$li             = $jsTabs.find('.tabs').find('li');
   this.$filterBodyTr   =  that.container.find('#filter_body').find("tr");
   this.$customRuleInfo = that.container.find('#custom_rule_info');
},

enableTabs :function() {
  var self = this
  this.$li.click(function(){
    var index  = self.$li.index(this);
    self.$jsTabs.tabs().select(index);
    if(index==2){
      var tr = self.$filterBodyTr;
      tr.each(function(){
        $t = $(this);
        if($t.is(":visible")){
          if ($t.text().toUpperCase().indexOf("MY NAME") > -1){
           self.$customRuleInfo.addClass("hide-data");
          }
        }
      });
    }
  });
},

Upvotes: 1

Related Questions