Skip to content

Commit f9e00b1

Browse files
committed
Listen to the touch target.
This ensures that if the touch target is removed from the DOM during a zoom gesture, the zoom behavior continues to receive events; touch events, unlike other events, are always dispatched to the target of the touchstart event rather than the window.
1 parent e03b645 commit f9e00b1

4 files changed

Lines changed: 98 additions & 98 deletions

File tree

d3.js

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,9 +1116,9 @@
11161116
}
11171117
function dragstart(id, position, subject, move, end) {
11181118
return function() {
1119-
var element = this, parent = element.parentNode, dispatch = event.of(element, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragTarget = d3.event.target, dragSubject = d3.select(subject()).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(), position0 = position(parent, dragId);
1119+
var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject()).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(), position0 = position(parent, dragId);
11201120
if (origin) {
1121-
dragOffset = origin.apply(element, arguments);
1121+
dragOffset = origin.apply(that, arguments);
11221122
dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ];
11231123
} else {
11241124
dragOffset = [ 0, 0 ];
@@ -1144,7 +1144,7 @@
11441144
function ended() {
11451145
if (!position(parent, dragId)) return;
11461146
dragSubject.on(move + dragName, null).on(end + dragName, null);
1147-
dragRestore(dragged && d3.event.target === dragTarget);
1147+
dragRestore(dragged && d3.event.target === target);
11481148
dispatch({
11491149
type: "dragend"
11501150
});
@@ -1218,15 +1218,15 @@
12181218
}
12191219
zoom.event = function(g) {
12201220
g.each(function() {
1221-
var event_ = event.of(this, arguments), view1 = view;
1221+
var dispatch = event.of(this, arguments), view1 = view;
12221222
if (d3_transitionInheritId) {
12231223
d3.select(this).transition().each("start.zoom", function() {
12241224
view = this.__chart__ || {
12251225
x: 0,
12261226
y: 0,
12271227
k: 1
12281228
};
1229-
zoomstarted(event_);
1229+
zoomstarted(dispatch);
12301230
}).tween("zoom:zoom", function() {
12311231
var dx = size[0], dy = size[1], cx = dx / 2, cy = dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]);
12321232
return function(t) {
@@ -1236,16 +1236,16 @@
12361236
y: cy - l[1] * k,
12371237
k: k
12381238
};
1239-
zoomed(event_);
1239+
zoomed(dispatch);
12401240
};
12411241
}).each("end.zoom", function() {
1242-
zoomended(event_);
1242+
zoomended(dispatch);
12431243
});
12441244
} else {
12451245
this.__chart__ = view;
1246-
zoomstarted(event_);
1247-
zoomed(event_);
1248-
zoomended(event_);
1246+
zoomstarted(dispatch);
1247+
zoomed(dispatch);
1248+
zoomended(dispatch);
12491249
}
12501250
});
12511251
};
@@ -1328,46 +1328,46 @@
13281328
return (y - view.y) / view.k;
13291329
}).map(y0.invert));
13301330
}
1331-
function zoomstarted(event) {
1332-
event({
1331+
function zoomstarted(dispatch) {
1332+
dispatch({
13331333
type: "zoomstart"
13341334
});
13351335
}
1336-
function zoomed(event) {
1336+
function zoomed(dispatch) {
13371337
rescale();
1338-
event({
1338+
dispatch({
13391339
type: "zoom",
13401340
scale: view.k,
13411341
translate: [ view.x, view.y ]
13421342
});
13431343
}
1344-
function zoomended(event) {
1345-
event({
1344+
function zoomended(dispatch) {
1345+
dispatch({
13461346
type: "zoomend"
13471347
});
13481348
}
13491349
function mousedowned() {
1350-
var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, dragged = 0, w = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), l = location(d3.mouse(target)), dragRestore = d3_event_dragSuppress();
1351-
d3_selection_interrupt.call(target);
1352-
zoomstarted(event_);
1350+
var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress();
1351+
d3_selection_interrupt.call(that);
1352+
zoomstarted(dispatch);
13531353
function moved() {
13541354
dragged = 1;
1355-
translateTo(d3.mouse(target), l);
1356-
zoomed(event_);
1355+
translateTo(d3.mouse(that), location0);
1356+
zoomed(dispatch);
13571357
}
13581358
function ended() {
1359-
w.on(mousemove, d3_window === target ? mousewheelreset : null).on(mouseup, null);
1360-
dragRestore(dragged && d3.event.target === eventTarget);
1361-
zoomended(event_);
1359+
subject.on(mousemove, d3_window === that ? mousewheelreset : null).on(mouseup, null);
1360+
dragRestore(dragged && d3.event.target === target);
1361+
zoomended(dispatch);
13621362
}
13631363
}
13641364
function touchstarted() {
1365-
var target = this, event_ = event.of(target, arguments), locations0 = {}, distance0 = 0, scale0, eventId = d3.event.changedTouches[0].identifier, touchmove = "touchmove.zoom-" + eventId, touchend = "touchend.zoom-" + eventId, w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress();
1366-
d3_selection_interrupt.call(target);
1365+
var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, target = d3.select(d3.event.target).on(touchmove, moved).on(touchend, ended), subject = d3.select(that).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress();
1366+
d3_selection_interrupt.call(that);
13671367
started();
1368-
zoomstarted(event_);
1368+
zoomstarted(dispatch);
13691369
function relocate() {
1370-
var touches = d3.touches(target);
1370+
var touches = d3.touches(that);
13711371
scale0 = view.k;
13721372
touches.forEach(function(t) {
13731373
if (t.identifier in locations0) locations0[t.identifier] = location(t);
@@ -1386,7 +1386,7 @@
13861386
scaleTo(view.k * 2);
13871387
translateTo(p, l);
13881388
d3_eventPreventDefault();
1389-
zoomed(event_);
1389+
zoomed(dispatch);
13901390
}
13911391
touchtime = now;
13921392
} else if (touches.length > 1) {
@@ -1395,7 +1395,7 @@
13951395
}
13961396
}
13971397
function moved() {
1398-
var touches = d3.touches(target), p0, l0, p1, l1;
1398+
var touches = d3.touches(that), p0, l0, p1, l1;
13991399
for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {
14001400
p1 = touches[i];
14011401
if (l1 = locations0[p1.identifier]) {
@@ -1411,7 +1411,7 @@
14111411
}
14121412
touchtime = null;
14131413
translateTo(p0, l0);
1414-
zoomed(event_);
1414+
zoomed(dispatch);
14151415
}
14161416
function ended() {
14171417
if (d3.event.touches.length) {
@@ -1423,37 +1423,37 @@
14231423
return void relocate();
14241424
}
14251425
}
1426-
w.on(touchmove, null).on(touchend, null);
1427-
t.on(mousedown, mousedowned).on(touchstart, touchstarted);
1426+
target.on(zoomName, null);
1427+
subject.on(mousedown, mousedowned).on(touchstart, touchstarted);
14281428
dragRestore();
1429-
zoomended(event_);
1429+
zoomended(dispatch);
14301430
}
14311431
}
14321432
function mousewheeled() {
1433-
var event_ = event.of(this, arguments);
1433+
var dispatch = event.of(this, arguments);
14341434
if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this),
1435-
zoomstarted(event_);
1435+
zoomstarted(dispatch);
14361436
mousewheelTimer = setTimeout(function() {
14371437
mousewheelTimer = null;
1438-
zoomended(event_);
1438+
zoomended(dispatch);
14391439
}, 50);
14401440
d3_eventPreventDefault();
14411441
var point = center || d3.mouse(this);
14421442
if (!translate0) translate0 = location(point);
14431443
scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k);
14441444
translateTo(point, translate0);
1445-
zoomed(event_);
1445+
zoomed(dispatch);
14461446
}
14471447
function mousewheelreset() {
14481448
translate0 = null;
14491449
}
14501450
function dblclicked() {
1451-
var event_ = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2;
1452-
zoomstarted(event_);
1451+
var dispatch = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2;
1452+
zoomstarted(dispatch);
14531453
scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1));
14541454
translateTo(p, l);
1455-
zoomed(event_);
1456-
zoomended(event_);
1455+
zoomed(dispatch);
1456+
zoomended(dispatch);
14571457
}
14581458
return d3.rebind(zoom, event, "on");
14591459
};

d3.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/behavior/drag.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@ d3.behavior.drag = function() {
1919

2020
function dragstart(id, position, subject, move, end) {
2121
return function() {
22-
var element = this,
23-
parent = element.parentNode,
24-
dispatch = event.of(element, arguments),
22+
var that = this,
23+
target = d3.event.target,
24+
parent = that.parentNode,
25+
dispatch = event.of(that, arguments),
2526
dragged = 0,
2627
dragId = id(),
2728
dragName = ".drag" + (dragId == null ? "" : "-" + dragId),
2829
dragOffset,
29-
dragTarget = d3.event.target,
3030
dragSubject = d3.select(subject()).on(move + dragName, moved).on(end + dragName, ended),
3131
dragRestore = d3_event_dragSuppress(),
3232
position0 = position(parent, dragId);
3333

3434
if (origin) {
35-
dragOffset = origin.apply(element, arguments);
35+
dragOffset = origin.apply(that, arguments);
3636
dragOffset = [dragOffset.x - position0[0], dragOffset.y - position0[1]];
3737
} else {
3838
dragOffset = [0, 0];
@@ -61,7 +61,7 @@ d3.behavior.drag = function() {
6161
function ended() {
6262
if (!position(parent, dragId)) return; // this touch didn’t end
6363
dragSubject.on(move + dragName, null).on(end + dragName, null);
64-
dragRestore(dragged && d3.event.target === dragTarget);
64+
dragRestore(dragged && d3.event.target === target);
6565
dispatch({type: "dragend"});
6666
}
6767
};

0 commit comments

Comments
 (0)