BAE BAE - 1 month ago 7
Javascript Question

Backbone: Why assign `$('#footer')` to `el`?

I found the following statements:



var todosView = new TodosView({el: $('#footer')});


Why assign
$('#footer')
to
el
?
(This is what really confused me. I read the post here, What is the difference between $el and el in Backbone.js views?, still confused.)

Also, I read:
The
view.$el
property is equivalent to
$(view.el)
and
view.$(selector)
is equivalent to
$(view.el).find(selector)
. In our TodoView example’s render method, we see
this.$el
used to set the HTML of the element and
this.$()
used to find subelements of class ‘edit’.

But, someone said
If you call
$(this.el)
, your just keep executing the jquery selector to get the same jquery object. '$el' is the cached version of
$(this.el)


What is "cached version"?

Answer

What is the difference between $el and el?

I like how user mu is too short puts it:

this.$el = $(this.el);

The el view property

this.el can be resolved from a DOM selector string or an Element; otherwise it will be created from the view's tagName, className, id and attributes properties. If none are set, this.el is an empty div, which is often just fine.

The el option

An el reference may also be passed in to the view's constructor.

The $el property

A cached jQuery object for the view's element. A handy reference instead of re-wrapping the DOM element all the time.

Why assign $('#footer') to el?

this.el can be a jQuery object. You can see that Backbone make sure el is a DOM element and $el is a jQuery object of it in the _setElement function:

_setElement: function(el) {
  this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
  this.el = this.$el[0];
},

This shows why this.$el is equivalent to $(this.el).

But what is Backbone.$?

Backbone keeps a reference to whatever is $.

For Backbone’s purposes, jQuery, Zepto, Ender, or My Library (kidding) owns the $ variable.

In our case, $ is jQuery, so Backbone.$ is just jQuery, but Backbone dependencies are flexible:

Backbone's only hard dependency is Underscore.js ( >= 1.8.3). For RESTful persistence and DOM manipulation with Backbone.View, include jQuery ( >= 1.11.0), and json2.js for older Internet Explorer support. (Mimics of the Underscore and jQuery APIs, such as Lodash and Zepto, will also tend to work, with varying degrees of compatibility.)

this.$(selector) is equivalent to $(view.el).find(selector)

In fact, it's a little more efficient, the $ view function is just:

$: function(selector) {
  return this.$el.find(selector);
},

What is a cached jQuery object?

In this case, it only means that a jQuery object is kept inside a variable, which is reused inside the view. It avoids the costly operation of finding the element with $(selector) each time.

You can (and should) use this little optimization whenever possible, like inside the render function:

render: function() {
    this.$el.html(this.template(/* ...snip... */));
    // this is caching a jQuery object
    this.$myCachedObject = this.$('.selector');
},

onExampleEvent: function(e) {
    // avoids $('.selector') here and on any sub-sequent example events.
    this.$myCachedObject.toggleClass('example');
}

Backbone's source code is less than 2000 lines, it's well-documented and easy to read. I highly encourage everyone to dive into it to easily understand the underlying logic.

They also offer an annotated source page which is even easier to read.

Additional reading