Skip to content

Commit

Permalink
Improve performance for .on() method kupriyanenko#39
Browse files Browse the repository at this point in the history
  • Loading branch information
kupriyanenko committed Mar 9, 2015
1 parent 52f03cd commit 531ca24
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 47 deletions.
30 changes: 30 additions & 0 deletions perf/events.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
suite("on event", function(suite) {
setup(function() {
suite.jbEl = jBone('<span>');
suite.jqEl = jQuery('<span>');
});

bench("jBone", function() {
suite.jbEl.on('click', function() {});
});

bench("jQuery", function() {
suite.jqEl.on('click', function() {});
});
});

suite("on event with namespace", function(suite) {
setup(function() {
suite.jbEl = jBone('<span>');
suite.jqEl = jQuery('<span>');
});

bench("jBone", function() {
suite.jbEl.on('click.space', function() {});
});

bench("jQuery", function() {
suite.jqEl.on('click.space', function() {});
});
});

suite("on/off events", function(suite) {
setup(function() {
suite.jbEl = jBone('<span>');
Expand Down
115 changes: 68 additions & 47 deletions src/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,70 +49,91 @@ jBone.Event = function(event, data) {
}, data);
};

fn.on = function(event) {
jBone.event = {
add: function(el, types, handler, data, selector) {
var eventHandler = function() {
jBone.event.dispatch.apply(el, arguments);
},
events, eventType, t, event;

jBone.setId(el);
events = jBone.getData(el).events;

types = types.split(" ");
t = types.length;
while (t--) {
event = types[t];

eventType = event.split(".")[0];
events[eventType] = events[eventType] || [];

if (!events[eventType].length) {
el.addEventListener && el.addEventListener(eventType, eventHandler, false);
}

events[eventType].push({
namespace: event.split(".").splice(1).join("."),
fn: eventHandler,
selector: selector,
data: data,
originfn: handler
});
}
},

dispatch: function(e) {
var i = 0,
el = this,
handlerQueue = jBone.getData(el).events[e.type],
length = handlerQueue.length,
expectedTarget,
handler,
eventOptions;

for (; i < length; i++) {
eventOptions = {};
handler = handlerQueue[i];
handler.data && (eventOptions.data = handler.data);

if (!handler.selector) {
if (!(e.namespace && e.namespace !== handler.namespace)) {
handler.originfn.call(el, new BoneEvent(e, eventOptions));
}
} else if (~jBone(el).find(handler.selector).indexOf(e.target) || (expectedTarget = jBone.contains(jBone(el).find(handler.selector), e.target))) {
expectedTarget = expectedTarget || e.target;
eventOptions.currentTarget = expectedTarget;

if (!(e.namespace && e.namespace !== handler.namespace)) {
handler.originfn.call(expectedTarget, new BoneEvent(e, eventOptions));
}
}
}
}
};

fn.on = function(types) {
var args = arguments,
length = this.length,
i = 0,
callback = slice.call(args, -1)[0],
target, data, namespace, fn, events, eventType, expectedTarget, addListener;
handler = slice.call(args, -1)[0],
selector, data;

// .on('click', '.selector', function() {})
if (args.length === 3 && isString(args[1])) {
target = args[1];
selector = args[1];
}
// .on('click', { key: value }, function() {})
else if (args.length === 3 && isObject(args[1])) {
data = args[1];
}
// .on('click', '.selector', { key: value }, function() {})
else if (args.length === 4) {
target = args[1];
selector = args[1];
data = args[2];
}

addListener = function(el) {
jBone.setId(el);
events = jBone.getData(el).events;
event.split(" ").forEach(function(event) {
var eventOptions = {};

if (data) {
eventOptions.data = data;
}

eventType = event.split(".")[0];
namespace = event.split(".").splice(1).join(".");
events[eventType] = events[eventType] || [];

fn = function(e) {
if (e.namespace && e.namespace !== namespace) {
return;
}

expectedTarget = null;

if (!target) {
callback.call(el, new BoneEvent(e, eventOptions));
} else if (~jBone(el).find(target).indexOf(e.target) || (expectedTarget = jBone.contains(jBone(el).find(target), e.target))) {
expectedTarget = expectedTarget || e.target;
eventOptions.currentTarget = expectedTarget;

callback.call(expectedTarget, new BoneEvent(e, eventOptions));
}
};

events[eventType].push({
namespace: namespace,
fn: fn,
originfn: callback
});

el.addEventListener && el.addEventListener(eventType, fn, false);
});
};

for (; i < length; i++) {
addListener(this[i]);
jBone.event.add(this[i], types, handler, data, selector);
}

return this;
Expand Down

0 comments on commit 531ca24

Please sign in to comment.