22 Jun 2012
About Javascript dispatch event and delegate event
(function () {
var all_events = {}; // events data, private to this file
function bind_event (ele, event, handler) {
if(ele.addEventListener) {
ele.addEventListener(event, handler, false);
} else { // ie
ele.attachEvent('on' + event, handler);
}
}
// a Simple impl of dispatch event.
function dispatch_event (ele, selector, eventName, handler) {
var handlers = all_events[ele] || {};
if(handlers[eventName]) {
handlers[eventName].push(handler); // add more
} else {
handlers[eventName] = [handler]; // register
var one_handler = function (e) {
// find registerd handlers
var handlers = (all_events[ele] || {})[eventName];
if(!handlers) { return; }
var target = e.target;
// IE6, IE7 does not support querySelectorAll
var nodes = ele.querySelectorAll(selector);
for(var i = 0; i < nodes.length; i++) {
// interested event hanpend on interested DOM node
if(nodes[i] === target) {
for(var j = 0; j < handlers.length; j++) { // call one by one
// properly bind `this`
var ret = handlers[j].apply(target, [e]);
if(ret === false) {
e.preventDefault(); e.stopPropagation();
}
}
}
}
};
bind_event(ele, eventName, one_handler);
}
all_events[ele] = handlers;
}
var EVENTSPLITTER = /^(\S+)\s*(.*)$/;
// extracted from Backbone.js, brilliant
function delegate_events (ele, events) {
for (var key in events) {
var method = events[key],
match = key.match(EVENTSPLITTER),
eventName = match[1],
selector = match[2];
if (selector === '') {
bind_event(ele, eventName, method);
} else {
dispatch_event(ele, selector, eventName, method);
}
}
}
function click_handler1 () { console.log('click', this, e); }
function click_handler2 () { console.log('click2', this, e); }
// I like the syntax.
// And it's very flexable, modify the DOM as you want,
// event handler will work just the way you want it
delegate_events(document, {
'click li': click_handler1,
'click ul li': click_handler2
});
})();