Registering layers in a web mapping library. API design I am working on a web mapping library, that makes it possible to create a map with SVG and JavaScript. As every map shall consist of SVG and Image elements, which can be grouped in layers, which in turn can be set invisible, I need an API to reflect this functionality. I started with two classes/prototypes:

Map()                      // the map constructor
.add(object)               // method to add a layer or element

Layer()                    // the layer constructor
.add(object)               // method to add an element
.setVisibility(boolean)    // mothod to set the visibilty


Some days later I extended the Map with a method to register event handlers that I modeled after the Jquery on/off API:

Map()
.add(object)
.on(events, handler)       // method to register event handlers
.off(events)               // … and to unregsiter handlers


The trick with the events parameter is, that it is a string containing both an event and an optinal namespace to group the event handlers like click.namespace

A classmate then gave me the advice to remove the layer class completely and add "add()" and "remove()" methods that work like the on and off methods to group elements to layers. So the following API emerged:

Map()
.add(namespace, object)
.remove(namespace)
.on(events, handler)
.off(events)


What I find somehow cumbersome, is, that events describe both an event and an optinal namespace, whereas namespace only describes a namespace. So

The Question is:

How to design such an API in a simple, but still consistent way so that I can group elements and event handlers in a similar manner?
Since namespaces are always optional, you can follow the common JavaScript convention and put them at the end of the arguments list:

Map()
.add(object, namespace1)
.remove(namespace1)
.on(events, handler, namespace2)
.off(events)
.on(otherEvents, handler)




As you say, events describe both an event and a namespace. More specifically, they describe an event on a namespace or the whole map, which is why it makes sense to add back the "layer" object. This is the simplest way to show the difference between "event on a layer" and "event on all layers":

var l = Layer()            // the layer constructor
.add(object)               // method to add an element
.setVisibility(boolean)    // mothod to set the visibilty
.on("click", handler)      // do XXX when clicking on an object of this layer
.off("click")

var m = Map()              // the map constructor
.add(l)                    // method to add a layer or element
.on("hover", handler)      // do XXX when hovering the whole map


You should also wonder what you're going to do with bubbling events. If there's an event which is not handled in the layer, is it going to bubble up and be handled by the map? For all browsers? Those issues (and many more) are already covered by jQuery, which is why I don't suggest rewriting half of their event-handling code and simply use it directly. Why not writing your API as a jQuery plugin?