Skip to content

Commit 27fc1b1

Browse files
authored
Merge pull request #1933 from konvajs/codex/resolve-mouseleave-vs-pointerleave-behavior
Fix pointerleave bubbling behavior
2 parents f00fd70 + cdd61d7 commit 27fc1b1

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

src/Node.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ const ABSOLUTE_OPACITY = 'absoluteOpacity',
8888
LISTENING = 'listening',
8989
MOUSEENTER = 'mouseenter',
9090
MOUSELEAVE = 'mouseleave',
91+
POINTERENTER = 'pointerenter',
92+
POINTERLEAVE = 'pointerleave',
93+
TOUCHENTER = 'touchenter',
94+
TOUCHLEAVE = 'touchleave',
9195
NAME = 'name',
9296
SET = 'set',
9397
SHAPE = 'Shape',
@@ -2335,8 +2339,17 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
23352339
evt.target = this;
23362340
}
23372341

2342+
const nonBubbling = [
2343+
MOUSEENTER,
2344+
MOUSELEAVE,
2345+
POINTERENTER,
2346+
POINTERLEAVE,
2347+
TOUCHENTER,
2348+
TOUCHLEAVE,
2349+
];
2350+
23382351
const shouldStop =
2339-
(eventType === MOUSEENTER || eventType === MOUSELEAVE) &&
2352+
nonBubbling.indexOf(eventType) !== -1 &&
23402353
((compareShape &&
23412354
(this === compareShape ||
23422355
(this.isAncestorOf && this.isAncestorOf(compareShape)))) ||
@@ -2347,7 +2360,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
23472360

23482361
// simulate event bubbling
23492362
const stopBubble =
2350-
(eventType === MOUSEENTER || eventType === MOUSELEAVE) &&
2363+
nonBubbling.indexOf(eventType) !== -1 &&
23512364
compareShape &&
23522365
compareShape.isAncestorOf &&
23532366
compareShape.isAncestorOf(this) &&

test/unit/Stage-test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
simulateTouchStart,
99
simulateTouchMove,
1010
simulateTouchEnd,
11+
simulatePointerMove,
1112
compareCanvases,
1213
createCanvas,
1314
showHit,
@@ -1222,6 +1223,36 @@ describe('Stage', function () {
12221223
assert.equal(count, 2);
12231224
});
12241225

1226+
it('stage pointerleave should not fire when leaving a child', function () {
1227+
var stage = addStage();
1228+
var layer = new Konva.Layer();
1229+
stage.add(layer);
1230+
1231+
var circle = new Konva.Circle({
1232+
fill: 'red',
1233+
radius: 30,
1234+
x: 50,
1235+
y: 50,
1236+
});
1237+
layer.add(circle);
1238+
layer.draw();
1239+
1240+
var stageLeave = 0;
1241+
var circleLeave = 0;
1242+
stage.on('pointerleave', function () {
1243+
stageLeave += 1;
1244+
});
1245+
circle.on('pointerleave', function () {
1246+
circleLeave += 1;
1247+
});
1248+
1249+
simulatePointerMove(stage, { x: 50, y: 50 });
1250+
simulatePointerMove(stage, { x: 90, y: 50 });
1251+
1252+
assert.equal(circleLeave, 1, 'circle pointerleave should fire');
1253+
assert.equal(stageLeave, 0, 'stage pointerleave should not fire');
1254+
});
1255+
12251256
it('toDataURL with hidden layer', function () {
12261257
var stage = addStage();
12271258
var layer = new Konva.Layer();

0 commit comments

Comments
 (0)