// Add events to elements ;[ 'click' , 'dblclick' , 'mousedown' , 'mouseup' , 'mouseover' , 'mouseout' , 'mousemove' // , 'mouseenter' -> not supported by IE // , 'mouseleave' -> not supported by IE , 'touchstart' , 'touchmove' , 'touchleave' , 'touchend' , 'touchcancel' ].forEach(function(event) { // add event to SVG.Element SVG.Element.prototype[event] = function(f) { var self = this // bind event to element rather than element node this.node['on' + event] = typeof f == 'function' ? function() { return f.apply(self, arguments) } : null return this } }) // Initialize listeners stack SVG.listeners = [] SVG.handlerMap = [] // Add event binder in the SVG namespace SVG.on = function(node, event, listener, binding) { // create listener, get object-index var l = listener.bind(binding || node.instance || node) , index = (SVG.handlerMap.indexOf(node) + 1 || SVG.handlerMap.push(node)) - 1 , ev = event.split('.')[0] , ns = event.split('.')[1] || '*' // ensure valid object SVG.listeners[index] = SVG.listeners[index] || {} SVG.listeners[index][ev] = SVG.listeners[index][ev] || {} SVG.listeners[index][ev][ns] = SVG.listeners[index][ev][ns] || {} // reference listener SVG.listeners[index][ev][ns][listener] = l // add listener node.addEventListener(ev, l, false) } // Add event unbinder in the SVG namespace SVG.off = function(node, event, listener) { var index = SVG.handlerMap.indexOf(node) , ev = event && event.split('.')[0] , ns = event && event.split('.')[1] if(index == -1) return if (listener) { // remove listener reference if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns || '*']) { // remove listener node.removeEventListener(ev, SVG.listeners[index][ev][ns || '*'][listener], false) delete SVG.listeners[index][ev][ns || '*'][listener] } } else if (ns && ev) { // remove all listeners for a namespaced event if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns]) { for (listener in SVG.listeners[index][ev][ns]) SVG.off(node, [ev, ns].join('.'), listener) delete SVG.listeners[index][ev][ns] } } else if (ns){ // remove all listeners for a specific namespace for(event in SVG.listeners[index]){ for(namespace in SVG.listeners[index][event]){ if(ns === namespace){ SVG.off(node, [event, ns].join('.')) } } } } else if (ev) { // remove all listeners for the event if (SVG.listeners[index][ev]) { for (namespace in SVG.listeners[index][ev]) SVG.off(node, [ev, namespace].join('.')) delete SVG.listeners[index][ev] } } else { // remove all listeners on a given node for (event in SVG.listeners[index]) SVG.off(node, event) delete SVG.listeners[index] } } // SVG.extend(SVG.Element, { // Bind given event to listener on: function(event, listener, binding) { SVG.on(this.node, event, listener, binding) return this } // Unbind event from listener , off: function(event, listener) { SVG.off(this.node, event, listener) return this } // Fire given event , fire: function(event, data) { // Dispatch event if(event instanceof Event){ this.node.dispatchEvent(event) }else{ this.node.dispatchEvent(new CustomEvent(event, {detail:data})) } return this } })