1

I'm experiencing an issue with removing / appending elements - which then lose their event handlers. So - the element gets cloned and appended on mousenter (which keeps all event handlers). I then use .detach() to remove the original to stop duplication, which as I understand, is supposed to keep the event listeners, but that's not what I'm seeing.

$("#containerSVG").on("mouseenter", "g", function(e){
    $(this).clone(true).appendTo("#containerSVG");
    $(this).detach();
});

$("#containerSVG").on("mouseleave", "g", function(){
    console.log("mouse leave triggered");
});

Here's a fiddle https://jsfiddle.net/6m54ttLe/6/ that shows the issue. If I remove the detach() then the mouseleave is triggered fine, when using detach() it is not triggered at all.

All suggestions much appreciated!

Update The reason I need to use clone() and not just appendTo() is because IE and EDGE lose the event handlers completely (even though Chrome and other decent browsers do not). Here's another post that discusses the same issue. I am not using d3 (and don't have time to learn it for this project) so the solutions they talk about are not applicable SVG element loses event handlers if moved around the DOM

Update 2 I still haven't found a solution to this issue. Would love to find one! However I have found a workaround by having each path in a separate SVG with a div instead of <g> and then I can use css z-index to bring the hovered one to the front. Just thought I'd add that in case anyone else has a similar issue.

ceindeg
  • 434
  • 5
  • 9
  • Why do you need to do either appendTo or clone? What is the funcyional requirement you're trying to meet? – Robert Longson Apr 03 '18 at 11:26
  • Hi Robert, I'm trying to get the hovered path to appear in front of the others. Essentially recreating z-index as it does not apply to SVG paths. – ceindeg Apr 03 '18 at 12:30
  • use a element that is in front of the existing paths and point it to one of the underneath paths. The will display a copy of the path on top. Just change he element's href to raise different elements. – Robert Longson Apr 03 '18 at 12:59
  • Thanks for the suggestion, I've updated the fiddle but there's no mouseleave triggered from the new element either... https://jsfiddle.net/6m54ttLe/28/ – ceindeg Apr 03 '18 at 13:59

1 Answers1

0

You do not actually need to clone the element: all you need is to do $(this).appendTo(...), and that has the effect of moving the selected node and appending it to whatever target you want. With that in mind, the following code will fix your problem:

$("#containerSVG").on("mouseenter", "g", function(e) {
  $(this).appendTo("#containerSVG");
});
$("#containerSVG").on("mouseleave", "g", function() {
  console.log('mouseleave');
});

See proof-of-concept fiddle: https://jsfiddle.net/teddyrised/6m54ttLe/20/, or check out the code snippet below:

$("#containerSVG").on("mouseenter", "g", function(e) {
  $(this).appendTo("#containerSVG");
});
$("#containerSVG").on("mouseleave", "g", function() {
  console.log('mouseleave');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg id="containerSVG" xmlns="http://www.w3.org/2000/svg" width="340" height="340" viewBox="0 0 340 340">
<g><path fill="#cc0000" d="M170,170 L170,0 A170,170 0 1,1 8.32039222982391, 117.46711095625892 z" transform="rotate(0, 170, 170)"></path></g>
<g>
  <path fill="#000000" d="M154,154 L154,0 A154,154 0 0,1 297.18557882679073, 97.30881888655958 z" transform="rotate(0, 154, 154)"></path><path fill="#000000" d="M154,154 L154,0 A154,154 0 0,1 192.29824262338764, 4.838193186190701 z" transform="rotate(68.4, 154, 154)"></path><path fill="#000000" d="M154,154 L154,0 A154,154 0 0,1 252.16329442129822, 35.34096061252849 z" transform="rotate(82.80000000000001, 154, 154)"></path><path fill="#000000" d="M154,154 L154,0 A154,154 0 0,1 306.7856640024296, 134.69868203109712 z" transform="rotate(122.4, 154, 154)"></path></g>
 </svg>
Terry
  • 63,248
  • 15
  • 96
  • 118
  • Thanks Terry, unfortunately this doesn't work in MS Edge or IE11 - the mouseleave event is not fired as appendTo does not keep the event handlers for those browsers. – ceindeg Apr 03 '18 at 11:21
  • @ceindeg The event handlers are bound to the SVG element, that’s how event bubbling works. Have you tried `mouseover` and `mouseout` instead? – Terry Apr 03 '18 at 14:20
  • 1
    Yep it makes no difference unfortunately. Your suggestion works fine for Chrome / Firefox / Safari, I just need a workaround for Edge / IE. – ceindeg Apr 03 '18 at 14:46