implement off with callbacks

This commit is contained in:
Anton Lavrenov
2018-01-12 11:05:12 +07:00
parent 3de52cac83
commit 8894d75a44
5 changed files with 2006 additions and 1955 deletions

View File

@@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added ### Added
* new `Konva.Transformer` group that allow simple resize, and rotate of a shape. * new `Konva.Transformer` group that allow simple resize, and rotate of a shape.
* Add ability to remove event by callback `node.off('event', callback)`
## Changed ## Changed

View File

@@ -2897,7 +2897,7 @@
* // remove listener by name * // remove listener by name
* node.off('click.foo'); * node.off('click.foo');
*/ */
off: function(evtStr) { off: function(evtStr, callback) {
var events = (evtStr || '').split(SPACE), var events = (evtStr || '').split(SPACE),
len = events.length, len = events.length,
n, n,
@@ -2921,11 +2921,11 @@
if (baseEvent) { if (baseEvent) {
if (this.eventListeners[baseEvent]) { if (this.eventListeners[baseEvent]) {
this._off(baseEvent, name); this._off(baseEvent, name, callback);
} }
} else { } else {
for (t in this.eventListeners) { for (t in this.eventListeners) {
this._off(t, name); this._off(t, name, callback);
} }
} }
} }
@@ -4101,20 +4101,24 @@
? [this] ? [this]
: []; : [];
}, },
_off: function(type, name) { _off: function(type, name, callback) {
var evtListeners = this.eventListeners[type], var evtListeners = this.eventListeners[type],
i, i,
evtName; evtName,
handler;
for (i = 0; i < evtListeners.length; i++) { for (i = 0; i < evtListeners.length; i++) {
evtName = evtListeners[i].name; evtName = evtListeners[i].name;
handler = evtListeners[i].handler;
// the following two conditions must be true in order to remove a handler: // the following two conditions must be true in order to remove a handler:
// 1) the current event name cannot be konva unless the event name is konva // 1) the current event name cannot be konva unless the event name is konva
// this enables developers to force remove a konva specific listener for whatever reason // this enables developers to force remove a konva specific listener for whatever reason
// 2) an event name is not specified, or if one is specified, it matches the current event name // 2) an event name is not specified, or if one is specified, it matches the current event name
if ( if (
(evtName !== 'konva' || name === 'konva') && (evtName !== 'konva' || name === 'konva') &&
(!name || evtName === name) (!name || evtName === name) &&
(!callback || callback === handler)
) { ) {
evtListeners.splice(i, 1); evtListeners.splice(i, 1);
if (evtListeners.length === 0) { if (evtListeners.length === 0) {

2
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -530,7 +530,7 @@
* // remove listener by name * // remove listener by name
* node.off('click.foo'); * node.off('click.foo');
*/ */
off: function(evtStr) { off: function(evtStr, callback) {
var events = (evtStr || '').split(SPACE), var events = (evtStr || '').split(SPACE),
len = events.length, len = events.length,
n, n,
@@ -554,11 +554,11 @@
if (baseEvent) { if (baseEvent) {
if (this.eventListeners[baseEvent]) { if (this.eventListeners[baseEvent]) {
this._off(baseEvent, name); this._off(baseEvent, name, callback);
} }
} else { } else {
for (t in this.eventListeners) { for (t in this.eventListeners) {
this._off(t, name); this._off(t, name, callback);
} }
} }
} }
@@ -1734,20 +1734,24 @@
? [this] ? [this]
: []; : [];
}, },
_off: function(type, name) { _off: function(type, name, callback) {
var evtListeners = this.eventListeners[type], var evtListeners = this.eventListeners[type],
i, i,
evtName; evtName,
handler;
for (i = 0; i < evtListeners.length; i++) { for (i = 0; i < evtListeners.length; i++) {
evtName = evtListeners[i].name; evtName = evtListeners[i].name;
handler = evtListeners[i].handler;
// the following two conditions must be true in order to remove a handler: // the following two conditions must be true in order to remove a handler:
// 1) the current event name cannot be konva unless the event name is konva // 1) the current event name cannot be konva unless the event name is konva
// this enables developers to force remove a konva specific listener for whatever reason // this enables developers to force remove a konva specific listener for whatever reason
// 2) an event name is not specified, or if one is specified, it matches the current event name // 2) an event name is not specified, or if one is specified, it matches the current event name
if ( if (
(evtName !== 'konva' || name === 'konva') && (evtName !== 'konva' || name === 'konva') &&
(!name || evtName === name) (!name || evtName === name) &&
(!callback || callback === handler)
) { ) {
evtListeners.splice(i, 1); evtListeners.splice(i, 1);
if (evtListeners.length === 0) { if (evtListeners.length === 0) {

View File

@@ -1926,6 +1926,48 @@ suite('Node', function() {
layer.draw(); layer.draw();
}); });
// ======================================================
test('remove event with with callback', function() {
var stage = addStage();
var layer = new Konva.Layer();
var circle = new Konva.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 70,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
name: 'myCircle'
});
stage.add(layer);
layer.add(circle);
layer.draw();
var event1 = 0;
var event2 = 0;
var callback1 = function() {
event1 += 1;
}
var callback2 = function() {
event2 += 1;
}
circle.on('event', callback1);
circle.on('event', callback2);
circle.fire('event');
assert.equal(event1, 1, 'event1 triggered once');
assert.equal(event2, 1, 'event2 triggered once');
circle.off('event', callback1);
circle.fire('event');
assert.equal(event1, 1, 'event1 still triggered once');
assert.equal(event2, 2, 'event2 triggered twice');
});
// ====================================================== // ======================================================
test('simulate event bubble', function() { test('simulate event bubble', function() {
var stage = addStage(); var stage = addStage();