Skip to content

Instantly share code, notes, and snippets.

@parris
Created June 3, 2014 20:20
Show Gist options
  • Save parris/294f61851425fbdc2b3a to your computer and use it in GitHub Desktop.
Save parris/294f61851425fbdc2b3a to your computer and use it in GitHub Desktop.
Mixes into Backbone.View to provide Raphael based views
define(function(require) {
// forked from https://github.com/tomasAlabes/backbone.raphael
'use strict';
function addMixin(mixinOptions) {
this.clobber({
setElement: function (element, delegate, undelegateEvents) {
if (this.el && undelegateEvents) {
this.undelegateEvents();
}
// el and $el will be the same, $el would have no special meaning...
this.el = this.$el = element;
if (delegate !== false) {
this.delegateEvents();
}
return this;
},
/*
Backbone's delegateEvents works with jQuery on/off, but cannot be used
with Raphael's event handlers like element.click.
This method can work with both jQuery on/off and Raphael callbacks.
This method can also work with Raphael's drag event that takes 3 callbacks.
*/
delegateEvents: function (events) {
var eventName,
handler,
handlers,
oldHandlers,
idx;
if (!(events || (events = _.result(this, 'events')))) {
return this;
}
this.undelegateEvents();
if (!this._delegatedEvents) {
this._delegatedEvents = [];
}
for (eventName in events) {
handlers = [];
handler = events[eventName];
if (handler.push) {
// We have an array of handlers
for (idx = 0; idx < handler.length; idx++) {
handlers.push(this[handler[idx]].bind(this));
}
} else {
if (!_.isFunction(handler)) {
handler = this[events[eventName]];
}
if (handler) {
handlers.push(handler.bind(this));
}
}
if (!handlers.length) {
continue;
}
this._delegatedEvents.push({
eventName: eventName,
handlers: handlers,
el: this.el
});
//If it is one of the svg/vml events
if (this.el[eventName]) {
this.el[eventName].apply(this.el, handlers);
} else {
this.on(eventName, handlers[0]);
}
}
return this;
},
/*
Clears all callbacks previously bound to the view with `delegateEvents`.
Uses off for jQuery events. Uses event specific methods like unclick, undrag for Raphael.
*/
undelegateEvents: function () {
if (!this._delegatedEvents) {
return;
}
_.each(this._delegatedEvents, function(eventHandler) {
var eventName = eventHandler.eventName,
handlers = eventHandler.handlers,
el = eventHandler.el; // don't use this.el since it might have changed.
if (handlers) {
//If it is one of the svg/vml events
if (el && el['un' + eventName]) {
el['un' + eventName].apply(el, handlers);
} else {
this.off(eventName, handlers[0]);
}
}
}.bind(this));
delete this._delegatedEvents;
return this;
}
});
}
return addMixin;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment