store the event listeners using a hash if the context have a leaflet_id.

When removing a layer,the slowest part was to remove the event from the map.  For each event, the removeEventListener method had to loop the whole list.  With thousand of layers, it become very slow to do.  With a hash used has an index to find event listeners for a given leaflet id, its no more an issue.
This commit is contained in:
jfgirard 2012-11-12 11:10:03 -05:00
parent c82d023dde
commit db8056df45

View File

@ -26,18 +26,44 @@ L.Mixin.Events = {
types = L.Util.splitWords(types);
for (i = 0, len = types.length; i < len; i++) {
events[types[i]] = events[types[i]] || [];
events[types[i]].push({
var evt = {
action: fn,
context: context || this
});
};
if (context && context._leaflet_id) {
var tIndex = types[i] + '_idx', leafletId = context._leaflet_id;
events[tIndex] = events[tIndex] || {};
if (events[tIndex][leafletId]) {
events[tIndex][leafletId].push(evt);
} else {
events[tIndex][leafletId] = [evt];
}
} else {
events[types[i]] = events[types[i]] || [];
events[types[i]].push(evt);
}
}
return this;
},
hasEventListeners: function (type) { // (String) -> Boolean
return (key in this) && (type in this[key]) && (this[key][type].length > 0);
if ((key in this)) {
if ((type in this[key]) && this[key][type].length > 0) {
return true;
} else {
var typeIdx = type + '_idx';
if (typeIdx in this[key]) {
for (var leafletId in this[key][typeIdx]) {
if (this[key][typeIdx].hasOwnProperty(leafletId)) {
//atleast one id
return true;
}
}
}
}
}
return false;
},
removeEventListener: function (types, fn, context) { // (String[, Function, Object]) or (Object[, Object])
@ -50,25 +76,27 @@ L.Mixin.Events = {
this.removeEventListener(type, types[type], fn);
}
}
return this;
}
types = L.Util.splitWords(types);
for (i = 0, len = types.length; i < len; i++) {
if (this.hasEventListeners(types[i])) {
listeners = events[types[i]];
//if the context has a leaflet id, use it to find the listeners
if (context && context._leaflet_id) {
listeners = events[types[i] + '_idx'][context._leaflet_id] || [];
} else {
listeners = events[types[i]];
}
for (j = listeners.length - 1; j >= 0; j--) {
if (
(!fn || listeners[j].action === fn) &&
(!context || (listeners[j].context === context))
) {
(!fn || listeners[j].action === fn) && (!context || (listeners[j].context === context))) {
listeners.splice(j, 1);
}
}
if (context && context._leaflet_id && listeners.length === 0) {
delete events[types[i] + '_idx'][context._leaflet_id];
}
}
}
@ -80,16 +108,32 @@ L.Mixin.Events = {
return this;
}
var event = L.extend({
var event = L.Util.extend({
type: type,
target: this
}, data);
if (this[key][type]) {
var listeners = this[key][type].slice();
for (var i = 0, len = listeners.length; i < len; i++) {
listeners[i].action.call(listeners[i].context || this, event);
}
}
//fire event for the indexed listeners as well
var listenersIndex = this[key][type + '_idx'], listenerList;
if (listenersIndex) {
for (var leafletId in listenersIndex) {
if (listenersIndex.hasOwnProperty(leafletId)) {
listenerList = listenersIndex[leafletId];
if (listenerList) {
for (var j = 0, lenList = listenerList.length; j < lenList; j++) {
listenerList[j].action.call(listenerList[j].context || this, event);
}
}
}
}
}
return this;
}