-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Using Backbone without jQuery
With the latest changes from #3003, Backbone is now even further decoupled from jQuery. You can use your favorite non-jQuery DOM manipulation library with Backbone.View, or even forgo a DOM manipulation library entirely in favor of native methods. Backbone.View now exposes hooks that allow a View "adapter" to easily overwrite a few key Backbone.View methods that Backbone needs to operate, and leaves the rest of the public interface mostly the same.
For most users, the changes should be minimal. If you like using jQuery please by all means continue using it. If you're interested in using something other than jQuery with your project, take a look at Backbone.D3View for D3-backed Views, and Backbone.NativeView for going full native. You can also use a server-side DOM library like jsdom or cheerio for server-side rendering as in this gist example.
There are 8 total overridable methods:
-
$
for view-scoped element lookup. Takes a stringselector
and returns an array-like object (i.e. an object with a numericlength
property, like an NodeList, an Array, or a jQuery context) for easy iteration. See Backbone.View and Backbone.NativeView implementations. -
_createElement
creates an element given atagName
. Useful for out-of-browser DOM creation (for instance server-side rendering). Backbone.View and Backbone.NativeView use the same method. -
_removeElement
to remove the view's element from the DOM. Backbone.View and Backbone.NativeView. -
delegate
to add a single event listener to the view'sthis.el
property, with the benefit of easy bookkeeping for later event removal. Backbone.View and Backbone.NativeView. -
undelegate
to remove a single event listener, the inverse ofdelegate
. Theselector
andlistener
arguments are optional. Backbone.View and Backbone.NativeView. -
undelegateEvents
to remove all events added bydelegate
. Backbone.View and Backbone.NativeView. -
_setElement
sets the view'sthis.el
property from a string of HTML, a string selector, or a string element. Backbone.View and Backbone.NativeView. -
_setAttributes
applies a hash of attributes to the element. Backbone.View and Backbone.NativeView.
A number of drop-in replacements for Backbone.ajax
provide feature parity with jQuery.ajax
without jQuery. A native implementation is available as Backbone.NativeAjax.
Since we can no longer rely on the existence of the jQuery-friendly interface of view.$el.on
to be present on all Views, Backbone.View exposes two new hooks for event delegation, view.delegate
and view.undelegate
. It also requires that the return value from view.$
be an array-like object (a 0-indexed element list with a numeric length
property, like an Array, a NodeList, or a jQuery context). You should iterate over the return value of view.$
with Underscore methods like _.each
and _.map
and use native element methods on the results:
_.each(view.$('.title'), function(el) {
el.classList.add('active');
});
By default Backbone attempts to load $
for you. Either off the window
object if global, through define
if AMD, and require
if CommonJS. If you use jQuery in your app this should work seamlessly.
If you don't want jQuery and you're using a build tool like browserify or webpack to build your bundle, you must tell it to exclude or ignore the import.
For browserify, pass the exclude
option to the command line (or set the argument in your configuration).
$ browserify app.js --exclude jquery
For Webpack, add the IgnorePlugin
and turn off Webpack's AMD detection in webpack.config.js with imports-loader
.
{
module: {
loaders: [
{ test: /backbone\.js$/, loader: 'imports?define=>false' }
]
},
plugins: [
new webpack.IgnorePlugin(/^jquery$/)
]
}
Set the Backbone.$
property to support Ender, Zepto or your favorite DOM library.
To change the DOM library to Zepto with Browserify, first install aliasify
.
npm install --save aliasify
Add an "aliasify" section to the application's package.json
:
{
"browserify" {
"transform": ["aliasify"]
},
"aliasify": {
"aliases": {
"jquery": "zepto"
}
}
}
... and call the browserify executable with an extra flag:
browserify entry.js --global-transform aliasify -o out.js
... or if your app uses the browserify node API (example):
browserify(['./index.js'])
.transform(aliasify, {global: true})
.bundle()
.pipe(fs.createWriteStream(__dirname + '/out.js'));
Using WebPack, the resolve.alias configuration option can be used:
{
context: __dirname + "/app",
entry: "./entry",
output: {
path: __dirname + "/dist",
filename: "bundle.js"
},
resolve: {
alias: {
"jquery": "zepto"
}
}
}