15 How jQuery fits into large projects
8585 ワード
This chapter covers Improving selectors for better performance Organizing your code in modules Loading modules with RequireJS Managing dependencies with Bower Creating SPAs with Backbone.js
15.1 Improving the performance of your selectors
15.1.1 Avoiding the Universal selector
15.1.2 Improving the Class selector
15.1.3 Don't abuse the context parameter
15.1.4 Optimizing filters
15.1.5 Don't overspecify selectors
15.2 Organizing your code into modules
15.2.1 The object literals pattern
15.2.2 The Module pattern
15.3 Loading modules with RequireJS
15.3.1 Getting started with RequireJS
define([[id, ] dependencies,] factory) Parameters id (String) dependencies (Array) factory (Object|Function) Returns undefined
15.3.2 Using RequireJS with jQuery
15.4 Managing dependencies with Bower
15.4.1 Getting started with Bower
15.4.2 Searching a package
15.4.3 Installing,updating, and deleting packages
15.5 Creating single-page applications with Backbone.js
15.5.1 Why use an MV* framework?
15.5.2 Starting with Backbone.js
MODEL
COLLECTION
VIEW
ROUTER
15.5.3 Creating a Todos manage application using Backbone.js
CREATING THE HTML
INSTALLING BACKBONE.JS
THE TODO MODEL
THE TODOS COLLECTION
THE TODO VIEWS
THE APPLICATION VIEW
15.6 Summary
selecting elements RequireJS Bower Backbone.js
15.7 The end
We also wish you health and happiness, and may all your bugs be easily solvable!
15.1 Improving the performance of your selectors
15.1.1 Avoiding the Universal selector
$('form :checkbox');
$('form input:checkbox');
$('input:checkbox', 'form'); v
$('form > *');
$('form').children(); v
15.1.2 Improving the Class selector
var $elements = $('p.description'); v
15.1.3 Don't abuse the context parameter
var $element = $('#test', 'div');
var $element = $('#test'); v
15.1.4 Optimizing filters
$('p:visible');
$('p').filter(':visible'); v
$(':reset');
$('[type="reset"]');
$('input[type="reset"]'); v
$('#my-list li').slice(0,2); v
$('#my-list li:lt(2)');
$('input[placeholder!="Name"]');
$('input').not('[placeholder="Name"]'); v
15.1.5 Don't overspecify selectors
var $value = $('.revenue span.value'); v
var $value = $('table.revenue .value');
var $values = $('table.revenue tr td span.value');
var $values = $('.revenue span.value'); v
15.2 Organizing your code into modules
15.2.1 The object literals pattern
var myService = {
foo: function() {},
bar: function() {},
baz: function() {},
obj: {},
anotherObj: {}
}
var myService = {
foo: function() {},
payment: {
obj: {},
bar: function() {}
},
basket: {
anotherObj: {},
baz: function() {}
}
};
myService.basket.baz();
15.2.2 The Module pattern
var myFirstModule = (function() {
return {
foo: function() {},
bar: function () {},
obj: {}
}
})();
var myFirstModule = (function() {
var count = 0;
function doSomethingPrivate() {};
return {
obj: {},
foo: function() { count++; },
bar: function () { doSomethingPrivate(); }
}
})();
window.myService = (function(oldMyService) {
oldMyService.basket = {
baz: function() {},
anotherObj: {}
};
return oldMyService;
})(window.myService || {});
15.3 Loading modules with RequireJS
15.3.1 Getting started with RequireJS
define([[id, ] dependencies,] factory) Parameters id (String) dependencies (Array) factory (Object|Function) Returns undefined
define(['Person'], function(Person) {
function Car() {
this.getOwner = function() {
return 'The owner is ' + Person.name;
};
}
return Car;
});
require(['Car'], function(Car) {
var car = new Car();
alert(car.getOwner());
});
15.3.2 Using RequireJS with jQuery
define(['jquery'], function($) {
$.fn.jqia = function() {
//Plugin code here...
}
});
15.4 Managing dependencies with Bower
15.4.1 Getting started with Bower
15.4.2 Searching a package
15.4.3 Installing,updating, and deleting packages
15.5 Creating single-page applications with Backbone.js
15.5.1 Why use an MV* framework?
15.5.2 Starting with Backbone.js
MODEL
var todo = Backbone.Model.extend({
position: 1,
title: '',
done: false
});
COLLECTION
var todoList = Backbone.Collection.extend({
model: todo
});
VIEW
var TodoView = Backbone.View.extend({
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var TodoView = Backbone.View.extend({
tagName: 'li',
className; 'todo',
template: _.template($('#todo-template').html())
});
ROUTER
var TodoRouter = Backbone.Router.extend({
routes: {
"todo/:id": "getTodo",
"search/:string": "searchTodo"
},
getTodo: function(id) {
// Your code here
},
searchTodo(string) {
// Your code here
}
});
15.5.3 Creating a Todos manage application using Backbone.js
CREATING THE HTML
INSTALLING BACKBONE.JS
THE TODO MODEL
app.Todo = Backbone.Model.extend({
defaults: {
position: 1,
title: '',
done: false
},
initialize: function() {
this
.on('invalid', function(model, error) {
console.log(error);
})
.on('add', function(model, error) {
console.log(
'Todo with title "' + model.get('title') + '" added.'
);
})
.on('remove', function(model, error) {
console.log(
'Todo with title "' + model.get('title') + '" deleted.'
);
})
.on('change', function(model, error) {
console.log(
'Todo with title "' + model.get('title') + '" updated.'
);
});
},
validate: function(attributes) {
if(!attributes.title) {
return 'Title is required and cannot be empty';
}
if(
attributes.position === undefined ||
parseInt(attributes.position, 10) < 1
) {
return 'Position must be positive';
}
}
});
THE TODOS COLLECTION
app.todoList = new (Backbone.Collection.extend({
model: app.Todo,
localStorage: new Backbone.LocalStorage('todo-list'),
comparator: 'position',
initialize: function() {
this.on('add remove', this.collectionChanged);
},
collectionChanged: function(todo) {
if (todo.isValid()) {
this.each(function(element, index) {
element.save({
position: index + 1
});
});
this.sort();
}
}
}));
THE TODO VIEWS
app.TodoView = Backbone.View.extend({
tagName: 'li',
className: 'todo',
template: _.template($('#todo-template').html()),
events: {
'blur .todo-position': 'updateTodo',
'change .todo-done': 'updateTodo',
'keypress .todo-title': 'updateOnEnter',
'click .todo-delete': 'deleteTodo'
},
initialize: function() {
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'destroy', this.remove);
},
deleteTodo: function() {
this.model.destroy();
},
updateTodo: function() {
this.model.save({
title: $.trim(this.$title.text()),
position: parseInt(this.$position.text(), 10),
done: this.$done.is(':checked')
});
},
updateOnEnter: function(event) {
if (event.which === 13) {
this.updateTodo();
}
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
this.$title = this.$('.todo-title');
this.$position = this.$('.todo-position');
this.$done = this.$('.todo-done');
return this;
}
});
THE APPLICATION VIEW
app.appView = Backbone.View.extend({
el: '#todo-sheet',
events: {
'click #new-todo-save': 'createTodo'
},
initialize: function() {
this.$input = this.$('#new-todo');
this.$list = this.$('ul.todos');
this.listenTo(app.todoList, 'reset sort destroy', this.showTodos);
this.listenTo(app.todoList, 'invalid', this.showError);
app.todoList.fetch();
},
createTodo: function() {
app.todoList.create(
{
title: this.$input.val().trim()
},
{
at: 0,
validate: true
}
);
this.$input.val('');
},
showError: function(collection, error, model) {
this
.$('.error-message')
.finish()
.html(error)
.fadeIn('slow')
.delay(2000)
.fadeOut('slow');
},
showTodo: function(todo) {
if (todo.isValid()) {
var view = new app.TodoView({ model: todo });
this.$list.prepend(view.render().el);
}
},
showTodos: function() {
this.$list.empty();
var todos = app.todoList.sortBy(function(element) {
return -1 * parseInt(element.get('position'), 10);
});
for(var i = 0; i < todos.length; i++) {
this.showTodo(todos[i]);
}
}
});
15.6 Summary
selecting elements RequireJS Bower Backbone.js
15.7 The end
We also wish you health and happiness, and may all your bugs be easily solvable!