Skip to content

Instantly share code, notes, and snippets.

@erikringsmuth
Created February 6, 2014 23:38
Show Gist options
  • Save erikringsmuth/8854786 to your computer and use it in GitHub Desktop.
Save erikringsmuth/8854786 to your computer and use it in GitHub Desktop.
// view.on - delegate events. These are bound once to the root object so subsequent calls to view.render()
// don't need to re-bind events. Events work differently than jQuery delegate events since there aren't
// native ECMAScript delegate events. jQuery swapped event.target and event.currentTarget. Who knows why...
//
// var MyView = View.extend({
// this.on: {
// 'click span a': function(event) {
// this; // will reference your instance of `MyView`
// event.target; // will reference the DOM element the action took place on. This is `a` in this example.
// event.currentTarget; // will reference `this.el` which is the root element that all events are bound to.
// }
// })
if (typeof(view.on) === 'undefined') view.on = {};
// Keep a reference to all of the event listeners for testing
var eventListeners = {};
for (var callbackName in view.on) {
if (view.on.hasOwnProperty(callbackName)) {
// ['click', 'span', 'a'] from example
var eventParts = callbackName.split(' ');
// 'click' from example
var action = eventParts[0];
// 'span a' from example
var selector = eventParts.splice(1, eventParts.length - 1).join(' ');
// Bind all events to the root element
(function(action, selector, callbackName) {
var eventListener = function eventListener(event) {
// Check if the event was triggered on an element that matches the query selector
var matchingElements = view.el.querySelectorAll(selector);
for (var i in matchingElements) {
if (!event.target) event.target = event.srcElement; // IE8
if (event.target === matchingElements[i]) {
view.on[callbackName].call(view, event);
break;
}
}
};
if (window.addEventListener) {
view.el.addEventListener(action, eventListener, true);
} else {
// IE 8 and older, events are prefixed with 'on'
view.el.attachEvent('on' + action, eventListener);
}
if (typeof(eventListeners[action]) === 'undefined') eventListeners[action] = [];
eventListeners[action].push(eventListener);
})(action, selector, callbackName);
}
}
// view.displatchMockEvent() - triggers a mock event for integration testing event handlers
view.dispatchMockEvent = function dispatchMockEvent(mockEvent) {
if (typeof(mockEvent) === 'undefined') throw 'You must pass a mock event';
if (typeof(mockEvent.type) === 'undefined') throw 'You specify an event type';
if (typeof(mockEvent.target) === 'undefined') throw 'You specify an event target';
if (typeof(eventListeners[mockEvent.type]) === 'undefined') throw 'There are no event handlers set up for ' + mockEvent.type + 'events';
eventListeners[mockEvent.type].forEach(function(eventListener) {
eventListener(mockEvent);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment