mirror of
https://github.com/Choices-js/Choices.git
synced 2024-06-08 00:42:15 +02:00
e7d775e2ae
Instead of attaching a new root-level event listener for bubbling events for every choices instance, use a simple event delegation script to handle each event type. Each event callback function already is coded as if it were fully delegated, since the events are attached at the document level, so no changes are needed to detect which element is being called. Note that focus and blur event do not bubble, so they have been left as they are. Also note that the event delegation uses an IIFE purposely instead of ES6 modules, since the event list should be globally cached, and it doesn't make sense to instantiate a new scope for each instance (then we're back where we started!) fix #643
40 lines
1 KiB
JavaScript
40 lines
1 KiB
JavaScript
window.delegateEvent = (function delegateEvent() {
|
|
let events;
|
|
let addedListenerTypes;
|
|
if (typeof events === 'undefined') {
|
|
events = new Map();
|
|
}
|
|
if (typeof addedListenerTypes === 'undefined') {
|
|
addedListenerTypes = [];
|
|
}
|
|
|
|
function _callback(event) {
|
|
const type = events.get(event.type);
|
|
if (!type) return;
|
|
type.forEach(fn => fn(event));
|
|
}
|
|
|
|
return {
|
|
add: function add(type, fn) {
|
|
// Cache list of events.
|
|
if (events.has(type)) {
|
|
events.get(type).push(fn);
|
|
} else {
|
|
events.set(type, [fn]);
|
|
}
|
|
// Setup events.
|
|
if (addedListenerTypes.indexOf(type) === -1) {
|
|
document.documentElement.addEventListener(type, _callback, true);
|
|
addedListenerTypes.push(type);
|
|
}
|
|
},
|
|
remove: function remove(type, fn) {
|
|
if (!events.get(type)) return;
|
|
events.set(type, events.get(type).filter(item => item !== fn));
|
|
if (!events.get(type).length) {
|
|
addedListenerTypes.splice(addedListenerTypes.indexOf(type), 1);
|
|
}
|
|
},
|
|
};
|
|
})();
|