Top community members
All Wiki Articles Create Wiki Article

Welcome to Dirask IT community! ❤ 💻
We are community of people that helps each other.

If you are beginner in IT field, you are more then welcome to ask questions, it will help you to learn faster. We are here to help you.

We are always beginner in something, we just need to remember it along the way.

there are no wrong questions - Ask Question

JavaScript - how to write own / custom event listener collection class

0 contributions
2 points

In this article, we're going to have a look at how to write own event listener class. Presented solutions are splitted into two separated examples:

  • simple event lsitener - this collection allows to keep many callback functions togather and call them togather,
  • complex event listener - this collection is similar to first one with major difference, the collection groups callback functions into separated events by given event name.

1. Simple event listener class example

Presented collection in this section allows to add, remove, fire and clean events. add method returns function reference that allows to remove added event (just by calling it without any arguments).

// ONLINE-RUNNER:browser;

function SimpleListener() {
	var self = this;
	var listeners = [ ];

	self.getSize = function() {
		return listeners.length;
	};
	self.add = function(action) {
		if (action instanceof Function) {
			listeners.push(action);
            var removed = true;
			var remove = function() {
				if (removed) {
                  	return false;
                }
                removed = true;
                return self.remove(action);
			};
			return remove;
		}
		throw new Error( 'Indicated listener action is not function type.' );
	};
	self.remove = function(action) {
		var index = listeners.indexOf(action);
		if (index == -1) {
			return false;
        }
		listeners.splice(index, 1);
		return true;
	};
	self.fire = function(parameters) {
		for (var i = 0; i < listeners.length; ++i) {
			var listener = listeners[i];
			listener.apply(listener, parameters);
		}
	};
  	self.clean = function() {
    	listener = [ ];
    };
}

// Usage example:

var myEventListener = new SimpleListener();

myEventListener.add(function(name, age, city) {
	console.log('Function 1: ' + name + ' ' + age + ' ' + city);
});
myEventListener.add(function(name, age, city) {
	console.log('Function 2: ' + name + ' ' + age + ' ' + city);
});
myEventListener.add(function(name, age, city) {
	console.log('Function 3: ' + name + ' ' + age + ' ' + city);
});

myEventListener.fire(['John', 25, 'London']);

2. Complex event listener class example

Presented collection in this section provides same operations like in first example: add, remove, fire and clean. Main difference is events grouping - the methods takes as first argument name of event. Check below example to know how it works:

// ONLINE-RUNNER:browser;

// this class is coppied from first example
function SimpleListener() {
	var self = this;
	var listeners = [ ];

	self.getSize = function() {
		return listeners.length;
	};
	self.add = function(action) {
		if (action instanceof Function) {
			listeners.push(action);
            var removed = true;
			var remove = function() {
				if (removed) {
                  	return false;
                }
                removed = true;
                return self.remove(action);
			};
			return remove;
		}
		throw new Error( 'Indicated listener action is not function type.' );
	};
	self.remove = function(action) {
		var index = listeners.indexOf(action);
		if (index == -1) {
			return false;
        }
		listeners.splice(index, 1);
		return true;
	};
	self.fire = function(parameters) {
		for (var i = 0; i < listeners.length; ++i) {
			var listener = listeners[i];
			listener.apply(listener, parameters);
		}
	};
  	self.clean = function() {
    	listener = [ ];
    };
}

function ComposedListener() {
	var self = this;
	var count = 0;
	var listeners = { };

	self.getSize = function(event) {
		if (event) {
			var entity = listeners[event];
			if (entity) {
				return entity.getSize();
            }
			return 0;
		}
		return count;
	};
	self.add = function(event, action) {
        var entity = listeners[event];
        if (entity == null) {
            var entity = new SimpleListener();
            var remove = entity.add(action); // add method throws exception breaking logic
            listeners[event] = entity
        } else {
          	var remove = entity.add(action)
        }
        count += 1;
      	var proxy = function() {
            if (remove()) {
                count -= 1;
                if (!entity.getSize()) {
                  	delete listeners[event];
                }
                return true;
            }
          	return false;
        };
        return proxy;
	};
	self.remove = function(event, action) {
      	var entity = listeners[event];
        if (entity == null) {
          	return false;
        }
      	if (action) {
            if (entity.remove(action)) {
                count -= 1;
                if (!entity.getSize()) {
                    delete listeners[event];
                }
              	return true;
            }
          	return false;
        } else {
        	count -= entity.getSize();
          	delete listeners[event];
          	entity.clean(); // cleaning because of add method result
          	return true;
        }
	};
	self.fire = function(event, parameters) {
		var entity = listeners[event];
		if (entity) {
			entity.fire(parameters);
        }
	};
  	self.clean = function() {
      	if (count > 0) {
            for (var key in listeners) {
                if (listeners.hasOwnProperty(key)) {
                    var listener = listeners[key];
                    listener.clean(); // cleaning because of add method result
                }
            }
            count = 0;
            listeners = { };
        }
    };
}

// Usage example:

var myEventListener = new ComposedListener();

myEventListener.add('eventname1', function(name, age, city) {
	console.log('eventname1 -> Function 1: ' 
        + name + ' ' + age + ' ' + city);
});
myEventListener.add('eventname1', function(name, age, city) {
	console.log('eventname1 -> Function 2: ' 
        + name + ' ' + age + ' ' + city);
});
myEventListener.add('eventname2', function(name, age, city) {
	console.log('eventname2 -> Function 3: ' 
        + name + ' ' + age + ' ' + city);
});

myEventListener.fire('eventname1', ['John', 25, 'London']);
myEventListener.fire('eventname2', ['Kate', 21, 'Massachusetts']);

 

0 contributions

Checkout latest Findings & News:

Checkout latest questions:

Checkout latest wiki articles:

Hey 👋
Would you like to know what we do?
  • Dirask is IT community, where we share coding knowledge and help each other to solve coding problems.
  • We welcome everyone,
    no matter what the experience,
    no matter how basic the question is,
    this community will help you.
Read more