diff options
Diffstat (limited to 'src/event.js')
-rw-r--r-- | src/event.js | 222 |
1 files changed, 109 insertions, 113 deletions
diff --git a/src/event.js b/src/event.js index 2563699..fae7314 100644 --- a/src/event.js +++ b/src/event.js @@ -1,144 +1,140 @@ // 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) { - // bind event to element rather than element node - SVG.on(this.node, event, f) - return this - } -}) -// Initialize listeners stack -SVG.listeners = [] -SVG.handlerMap = [] +;[ 'click', + 'dblclick', + 'mousedown', + 'mouseup', + 'mouseover', + 'mouseout', + 'mousemove', + 'mouseenter', + 'mouseleave', + 'touchstart', + 'touchmove', + 'touchleave', + 'touchend', + 'touchcancel' ].forEach(function (event) { + // add event to SVG.Element + SVG.Element.prototype[event] = function (f) { + // bind event to element rather than element node + if (f == null) { + SVG.off(this, event) + } else { + SVG.on(this, event, f) + } + return this + } + }) + SVG.listenerId = 0 // Add event binder in the SVG namespace -SVG.on = function(node, event, listener, binding, options) { - // 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] || '*' - +SVG.on = function (node, events, listener, binding, options) { + var l = listener.bind(binding || node) + var n = node instanceof SVG.Element ? node.node : node - // 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] || {} + // ensure instance object for nodes which are not adopted + n.instance = n.instance || {_events: {}} - if(!listener._svgjsListenerId) - listener._svgjsListenerId = ++SVG.listenerId + var bag = n.instance._events - // reference listener - SVG.listeners[index][ev][ns][listener._svgjsListenerId] = l + // add id to listener + if (!listener._svgjsListenerId) { listener._svgjsListenerId = ++SVG.listenerId } - // add listener - node.addEventListener(ev, l, options || false) -} + events.split(SVG.regex.delimiter).forEach(function (event) { + var ev = event.split('.')[0] + var ns = event.split('.')[1] || '*' -// 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] - , namespace = '' + // ensure valid object + bag[ev] = bag[ev] || {} + bag[ev][ns] = bag[ev][ns] || {} - if(index == -1) return + // reference listener + bag[ev][ns][listener._svgjsListenerId] = l - if (listener) { - if(typeof listener == 'function') listener = listener._svgjsListenerId - if(!listener) return - - // 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) + // add listener + n.addEventListener(ev, l, options || false) + }) +} - delete SVG.listeners[index][ev][ns] - } +// Add event unbinder in the SVG namespace +SVG.off = function (node, events, listener, options) { + var n = node instanceof SVG.Element ? node.node : node + if (!n.instance) return + + // listener can be a function or a number + if (typeof listener === 'function') { + listener = listener._svgjsListenerId + if (!listener) return + } - } 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('.')) - } + var bag = n.instance._events + + ;(events || '').split(SVG.regex.delimiter).forEach(function (event) { + var ev = event && event.split('.')[0] + var ns = event && event.split('.')[1] + var namespace, l + + if (listener) { + // remove listener reference + if (bag[ev] && bag[ev][ns || '*']) { + // removeListener + n.removeEventListener(ev, bag[ev][ns || '*'][listener], options || false) + + delete bag[ev][ns || '*'][listener] + } + } else if (ev && ns) { + // remove all listeners for a namespaced event + if (bag[ev] && bag[ev][ns]) { + for (l in bag[ev][ns]) { SVG.off(n, [ev, ns].join('.'), l) } + + delete bag[ev][ns] + } + } else if (ns) { + // remove all listeners for a specific namespace + for (event in bag) { + for (namespace in bag[event]) { + if (ns === namespace) { SVG.off(n, [event, ns].join('.')) } } + } + } else if (ev) { + // remove all listeners for the event + if (bag[ev]) { + for (namespace in bag[ev]) { SVG.off(n, [ev, namespace].join('.')) } + + delete bag[ev] + } + } else { + // remove all listeners on a given node + for (event in bag) { SVG.off(n, event) } + + n.instance._events = {} } - - } 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] - delete SVG.handlerMap[index] - - } + }) } -// SVG.extend(SVG.Element, { // Bind given event to listener - on: function(event, listener, binding, options) { - SVG.on(this.node, event, listener, binding, options) - + on: function (event, listener, binding, options) { + SVG.on(this, event, listener, binding, options) return this - } + }, // Unbind event from listener -, off: function(event, listener) { + off: function (event, listener) { SVG.off(this.node, event, listener) - return this - } - // Fire given event -, fire: function(event, data) { - + }, + fire: function (event, data) { // Dispatch event - if(event instanceof window.Event){ - this.node.dispatchEvent(event) - }else{ - this.node.dispatchEvent(event = new SVG.CustomEvent(event, {detail:data, cancelable: true})) + if (event instanceof window.Event) { + this.node.dispatchEvent(event) + } else { + this.node.dispatchEvent(event = new window.CustomEvent(event, {detail: data, cancelable: true})) } - this._event = event return this - } -, event: function() { + }, + event: function() { return this._event } }) |