20

我正在尝试为要附加到 SVG 画布的所有元素创建一个通用的单击处理程序。但是我不能将处理程序委托给新创建的元素。

这是我试图委托的代码,但没有运气

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

更新:.on()它的jQuery手册中提到

注意:委托事件不适用于 SVG。

所以现在的问题是这个问题的任何其他解决方法?

4

2 回答 2

13

当 jQuery 使用 SVG 失败时,您可以使用 vanilla js。幸运的是,每个支持 svg 的浏览器也支持事件监听器。纯js委托事件没那么难看:

$("#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'));
});

但是您也可以创建自己的函数来更干净地委派您的事件。

于 2013-01-21T14:37:33.940 回答
9

TL/DR:将事件侦听器附加到非 SVG 父元素。

jQuery 文档中的注释有些误导。

委派事件不适用于 SVG。

应该是...

当侦听器附加到SVG时,委托事件不起作用。

当事件侦听器附加到 SVG 元素时,jQuery 的事件委托不起作用;但是,如果您将侦听器附加到 SVG 的非 SVG 父级,事件传播将按预期工作,并且任何匹配 SVG 元素的选择器确实会触发您的事件处理函数。

将侦听器附加到 SVG 元素将不起作用

$("#floor").on('click','.drawnLine', function() {
    console.log($(this).data('index'));
});

但是将其附加到父元素将起作用:

$(document.body).on('click','#floor .drawnLine', function() {
    console.log($(this).data('index'));
});

Note: one quirk I've noticed is that if the event target is an SVG element, the event won't bubble up all the way to document.body on iOS. So if you want iOS users to be able to trigger your handler function you'll need to attach your event listener to some element in between (such as the div element your SVG resides in).

于 2015-03-17T14:35:16.813 回答