Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event delegation on SVG Elements

I am trying to have a common click handler for all the elements I am appending to a SVG canvas. But I cannot delegate the handler to the newly created elements.

This is the code I have tried to delegate, but no luck

$("#floor").on('click','.drawnLine', function() {
    //#floor is the SVG Element
    //.drawnLine is the <line> element that is added dynamically
    console.log($(this).data('index'));
});

Update: On the jQuery manual of .on() it is mentioned that

Note: Delegated events do not work for SVG.

So now the question is any other workaround for this problem?

like image 323
Starx Avatar asked Jan 21 '13 01:01

Starx


People also ask

Can we attach event handler to SVG?

SVG is XML based, which means that every element is available within the SVG DOM. You can attach JavaScript event handlers for an element.

How do I know if an event target is SVG?

Click the left circle (inside the padding) and event. target. nodeName == svg ; click the right circle (in the svg proper) and event.

What is event delegation used for?

Event delegation refers to the process of using event propagation (bubbling) to handle events at a higher level in the DOM than the element on which the event originated. It allows us to attach a single event listener for elements that exist now or in the future.

What is event delegation model in JavaScript?

Event Delegation is basically a pattern to handle events efficiently. Instead of adding an event listener to each and every similar element, we can add an event listener to a parent element and call an event on a particular target using the . target property of the event object.


1 Answers

When jQuery fails with SVG you can use vanilla js. Fortunately every browser that supports svg also supports event listeners. The pure js delegated event is not so ugly:

$("#floor")[0].addEventListener('click', function(e) {
  // do nothing if the target does not have the class drawnLine
  if (!e.target.classList.contains("drawnLine")) return;
  console.log($(this).data('index'));
});

But you can also create your own function to delegate your events more cleanly.

like image 66
methodofaction Avatar answered Oct 04 '22 09:10

methodofaction