Created
February 6, 2014 23:38
-
-
Save erikringsmuth/8854786 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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