How to Attach Event Listeners to SVG Elements

Scalable Vector Graphics (SVG) elements are part of the Document Object Model (DOM), allowing you to manipulate and interact with them using standard JavaScript methods. This guide explains how to attach interactive event listeners—such as click, mouseover, and mouseout—directly to SVG DOM nodes using vanilla JavaScript, event delegation, and inline attributes, along with essential CSS considerations for interactivity.

The standard and most flexible way to handle events on SVG nodes is through the addEventListener method. You can target individual SVG shapes like <circle>, <rect>, <path>, or <g> groups.

<svg width="200" height="200" id="main-svg">
  <circle id="interactive-circle" cx="100" cy="100" r="50" fill="blue" />
</svg>

<script>
  const circle = document.getElementById('interactive-circle');

  // Attach a click event listener
  circle.addEventListener('click', (event) => {
    event.target.setAttribute('fill', 'green');
  });

  // Attach a mouseover event listener
  circle.addEventListener('mouseover', (event) => {
    event.target.style.cursor = 'pointer';
    event.target.setAttribute('r', '60');
  });

  // Attach a mouseout event listener
  circle.addEventListener('mouseout', (event) => {
    event.target.setAttribute('r', '50');
  });
</script>

2. Using Event Delegation

If your SVG contains many interactive nodes or dynamically generated elements, attach a single listener to the root <svg> or a container <g> element rather than individual shapes.

const svgContainer = document.getElementById('main-svg');

svgContainer.addEventListener('mouseover', (event) => {
  // Check if the hovered element is a shape you want to target
  if (event.target.tagName === 'circle' || event.target.classList.contains('interactive')) {
    event.target.setAttribute('fill', 'orange');
  }
});

svgContainer.addEventListener('mouseout', (event) => {
  if (event.target.tagName === 'circle' || event.target.classList.contains('interactive')) {
    event.target.setAttribute('fill', 'blue');
  }
});

3. Using Inline Event Attributes

You can attach event handlers directly in the SVG markup using attributes like onclick or onmouseover.

<svg width="200" height="200">
  <rect 
    x="20" 
    y="20" 
    width="100" 
    height="100" 
    fill="red" 
    onclick="handleClick(this)" 
    onmouseover="this.setAttribute('opacity', '0.7')"
    onmouseout="this.setAttribute('opacity', '1')"
  />
</svg>

<script>
  function handleClick(element) {
    alert(`Clicked rectangle with width: ${element.getAttribute('width')}`);
  }
</script>

4. Important CSS Property: pointer-events

If SVG nodes are not responding to mouse events as expected, verify the CSS pointer-events property:

/* Ensure all child shapes receive pointer interactions */
svg path, svg circle, svg rect {
  pointer-events: all;
}