Skip to content

Commit 8336f88

Browse files
authored
Merge pull request #6021 from SabineWren/fix-hover-flicker
Fixed hover events in Shadow DOM
2 parents e11b0bf + 8182d7a commit 8336f88

File tree

2 files changed

+12
-15
lines changed

2 files changed

+12
-15
lines changed

draftlogs/6021_fix.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix hover events in Shadow DOM [[#6021](https://github.com/plotly/plotly.js/pull/6021)]

src/components/fx/hover.js

+11-15
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@ var cartesianScatterPoints = {
7878
// The actual rendering is done by private function _hover.
7979
exports.hover = function hover(gd, evt, subplot, noHoverEvent) {
8080
gd = Lib.getGraphDiv(gd);
81-
81+
// The 'target' property changes when bubbling out of Shadow DOM.
82+
// Throttling can delay reading the target, so we save the current value.
83+
var eventTarget = evt.target;
8284
Lib.throttle(
8385
gd._fullLayout._uid + constants.HOVERID,
8486
constants.HOVERMINTIME,
85-
function() { _hover(gd, evt, subplot, noHoverEvent); }
87+
function() { _hover(gd, evt, subplot, noHoverEvent, eventTarget); }
8688
);
8789
};
8890

@@ -247,7 +249,7 @@ exports.loneHover = function loneHover(hoverItems, opts) {
247249
};
248250

249251
// The actual implementation is here:
250-
function _hover(gd, evt, subplot, noHoverEvent) {
252+
function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
251253
if(!subplot) subplot = 'xy';
252254

253255
// if the user passed in an array of subplots,
@@ -366,7 +368,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
366368
// [x|y]px: the pixels (from top left) of the mouse location
367369
// on the currently selected plot area
368370
// add pointerX|Y property for drawing the spikes in spikesnap 'cursor' situation
369-
var hasUserCalledHover = !evt.target;
371+
var hasUserCalledHover = !eventTarget;
370372
var xpx, ypx;
371373

372374
if(hasUserCalledHover) {
@@ -383,13 +385,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
383385
return;
384386
}
385387

386-
// Discover event target, traversing open shadow roots.
387-
var target = evt.composedPath && evt.composedPath()[0];
388-
if(!target) {
389-
// Fallback for browsers not supporting composedPath
390-
target = evt.target;
391-
}
392-
var dbb = target.getBoundingClientRect();
388+
var dbb = eventTarget.getBoundingClientRect();
393389

394390
xpx = evt.clientX - dbb.left;
395391
ypx = evt.clientY - dbb.top;
@@ -837,15 +833,15 @@ function _hover(gd, evt, subplot, noHoverEvent) {
837833
if(!helpers.isUnifiedHover(hovermode)) {
838834
hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
839835
alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
840-
} // TODO: tagName hack is needed to appease geo.js's hack of using evt.target=true
836+
} // TODO: tagName hack is needed to appease geo.js's hack of using eventTarget=true
841837
// we should improve the "fx" API so other plots can use it without these hack.
842-
if(evt.target && evt.target.tagName) {
838+
if(eventTarget && eventTarget.tagName) {
843839
var hasClickToShow = Registry.getComponentMethod('annotations', 'hasClickToShow')(gd, newhoverdata);
844-
overrideCursor(d3.select(evt.target), hasClickToShow ? 'pointer' : '');
840+
overrideCursor(d3.select(eventTarget), hasClickToShow ? 'pointer' : '');
845841
}
846842

847843
// don't emit events if called manually
848-
if(!evt.target || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
844+
if(!eventTarget || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
849845

850846
if(oldhoverdata) {
851847
gd.emit('plotly_unhover', {

0 commit comments

Comments
 (0)