-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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 stringselectorand returns an array-like object (i.e. an object with a numericlengthproperty, like an NodeList, an Array, or a jQuery context) for easy iteration. See Backbone.View and Backbone.NativeView implementations. -
_createElementcreates 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. -
_removeElementto remove the view's element from the DOM. Backbone.View and Backbone.NativeView. -
delegateto add a single event listener to the view'sthis.elproperty, with the benefit of easy bookkeeping for later event removal. Backbone.View and Backbone.NativeView. -
undelegateto remove a single event listener, the inverse ofdelegate. Theselectorandlistenerarguments are optional. Backbone.View and Backbone.NativeView. -
undelegateEventsto remove all events added bydelegate. Backbone.View and Backbone.NativeView. -
_setElementsets the view'sthis.elproperty from a string of HTML, a string selector, or a string element. Backbone.View and Backbone.NativeView. -
_setAttributesapplies 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: {
rules: [
{
test: /backbone\.js$/,
use: {
loader: 'imports-loader?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"
}
}
}