How to pass mouse events to an HTML Element under a SVG?

2,064 views
Skip to first unread message

HH

unread,
Dec 16, 2013, 4:38:33 PM12/16/13
to d3...@googlegroups.com
I'm using d3 to show some link analysis type stuff (nodes and edges) on top of a map. This means the svg overlay blocks all the mouse events (click, pan, zoom etc) for the map <div> underneath the svg.

I re-created a very simple jsfiddle to re-create my problem where the <button> represents my map: http://jsfiddle.net/H469P/

I've tried a few solutions I've found across the web which have not helped unfortunately:

1.) The css tag "pointer-events: none" works great in Firefox, but it doesn't work for IE9 which is a requirement for me.

2.) The document.elementFromPoint(x, y) is an interesting API, but I'm not getting back the overlayed html element back in the data result.

Thanks in advance for your help. I appreciate it.




marc fawzi

unread,
Dec 16, 2013, 5:11:12 PM12/16/13
to d3...@googlegroups.com
hi

#2 requires that you hide the SVG (display: none), get the element beneath it, and then show the SVG again. Problem is flicker, or worse refreshing the layout.

the best way is to use 'mousemove' event on document to tell when you're over the SVG using document.elementFromPoint(x, y) and if you are then simply forward all events to the overlayed element. You could set a global var in your enclosing scope like overSVG and set it to true or false as the mouse moves (I might have done it a better way in the past but i don't readily recall) and setup forwarding event handlers on the SVG (for click, pan, zoom, etc) that redirect the event to the overlayed element wen overSVG is set to true. Redirecting events is really simple with jQuery: jut set event.target inside the SVG event handlers to the overlayed element then do $(element).trigger(event)




--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Phuoc Do

unread,
Dec 16, 2013, 5:47:28 PM12/16/13
to d3...@googlegroups.com
The best thing I found for this is to make sure what you want clickable appears before.

<svg>
  <g class="group1>
    <circle />
  </g>
  <g class="group2>
    <circle />
  </g>
</svg>

2nd circle is the clickable one. If you want more control, use <g> to append. You can make your div float on top of svg using. Then the button is clickable.

svg {
  position: relative;
}

div {
  postion: absolute;
  top: 20px;
  left: 20px;
}

Phuoc Do

marc fawzi

unread,
Dec 16, 2013, 5:55:08 PM12/16/13
to d3...@googlegroups.com
yup, assuming it's not a general replacement for "pointer-events: none" that he's looking for. In some situations, maybe not his, you need a certain element to show up above another but with events passing thru

HH

unread,
Dec 17, 2013, 9:42:31 AM12/17/13
to d3...@googlegroups.com
Thanks Marc and Phuoc...interestingly, it appears with some tweaking we were able to get the "pointer-events" to play nicely with IE9. Here's the Fiddle of that in case any one else stumbles upon this thread.

http://jsfiddle.net/M8s4g/6/

marc fawzi

unread,
Dec 17, 2013, 11:50:46 AM12/17/13
to d3...@googlegroups.com
Hi HH,

I tried your original fiddle on Chrome (sorry, no IE9 on my machine) and sure enough it failed to open the alert with 'pointer-events' set to none on the SVG yet the button was registering the click as it highlighted when I clicked. I put the JS directly into the in-line onclick handler and it worked. Could this have been the problem? Or what was the problem?

the original fiddle working fine now (at least on Chrome) where it wasn't previously ... I generally recommend using jQuery's .on or the cross-browser native way of adding events externally (not inline)  


I'm trying to get at the lesson learned!? :)

HH

unread,
Dec 18, 2013, 10:59:24 AM12/18/13
to d3...@googlegroups.com
Marc-
  Yes....thanks for that clarification. That is definitely one takeaway, the other is the pointer-events does work with IE9+ if done correctly.
Reply all
Reply to author
Forward
0 new messages