Home > Software engineering >  Detecting and handling mouse events for a svg element as well as a dom element that is partially beh
Detecting and handling mouse events for a svg element as well as a dom element that is partially beh

Time:12-28

I need to respond to all pointer events on an svg element (such as the rect) within #svg-layer, but I also need to respond to all pointer events on dom elements in the #dom-layer (such as the button in #dom-layer) as long as they are not covered by svg elements. So, in the example below, clicking on the left side of the button (where it is not covered by the blue square) should trigger the button click handler, but clicking anywhere in the blue square should trigger only the rect click handler. JQuery and vanilla javascript answers are both fine.

Seems like there should be a way to solve this problem, but it's eluding me. In the example below, the button click handler is never called. In my actual use case, the #dom-layer is quite complex, so I want to somehow get the pointer event to the #dom-layer and have the browsers built-in logic handle the event capturing and bubbling process as if there weren't the #svg-layer in front. `

<html>

<head>
    <style>
        #dom-layer{
            position: relative;
        }
        #svg-layer{
            position: absolute;
            top: 0;
        }
    </style>
</head>

<body>
    <div>
        <div id="dom-layer">
            <div>
                <button onclick="alert('clicked button')">Button</button>
            </div>
        </div>
        <svg id="svg-layer" width="100%" height="100%">
            <rect x="30" y="0" width="50" height="50" style="fill:rgb(0,0,255)" onclick="alert('clicked rect')" />
        </svg>
    </div>
</body>

</html>

`

I've tried triggering events and dispatching events, but have had no success.

CodePudding user response:

Using the pointer-events property on #svg-layer it's allows you to control whether or not the element will generate pointer events, and if so, how those events will be processed.

#svg-layer {
  position: absolute;
  top: 0;
  pointer-events: none;
}
#svg-layer rect {
  pointer-events: all; 
}

#svg-layer will not generate pointer events, but the rect element within it will. This means that pointer events will be passed through the #svg-layer to the elements in the #dom-layer below it, unless they are intercepted by the rect element, in which case the rect element's event handlers will be called.

#dom-layer {
  position: relative;
}
#svg-layer {
  position: absolute;
  top: 0;
  pointer-events: none;
}

#svg-layer rect {
  pointer-events: all; 
}
<div id="dom-layer">
  <div>
    <button onclick="alert('clicked button')">Button</button>
  </div>
</div>
<svg id="svg-layer" width="100%" height="100%">
  <rect x="30" y="0" width="50" height="50" style="fill:rgb(0,0,255)" onclick="alert('clicked rect')" />
</svg>
</div>

  • Related