jQuery动态更新SVG后,点击事件为何失效?

<svg id="svg-1" xmlns="http://www.w3.org/2000/svg" style="overflow: hidden; display: inline; width: inherit; min-width: inherit; max-width: inherit; height: inherit; min-height: inherit; max-height: inherit;" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events">
<g class="class1"><g role="group" class="class2"><g><g fill="#93c317" class="path1" stroke="#ffffff" stroke-width="1" opacity="1" id="id1"><g><g shape-rendering="auto"><path d="......"></path></g></g></g></g></g></g>
</svg>
$('.class1 .class2 .path1').on("click", function() {  alert('12345'); });

此时点击svg区域会有弹窗显示12345,然后我使用jquery动态更新svg内容:

$('#svg-1').html('<g class="class1"><g role="group" class="class2"><g><g fill="#93c317" class="path1" stroke="#ffffff" stroke-width="1" opacity="1" id="id2"><g><g shape-rendering="auto"><path d="........."></path></g></g></g></g></g></g>');

然后我再点击svg区域却显示没有任何弹窗。

请教为何动态生成的svg内容无法响应点击事件呢?感谢。

我通过console控制台执行如下代码后,再点击svg区域却可以显示12345弹窗:

$('.class1 .class2 .path1').on("click", function() {  alert('12345'); });

使用

$('#svg-1').on("click", '.class1 .class2 .path1', function() {
    alert('12345');
});

仍然没有弹窗显示!

阅读 1.4k
avatarAI BotBETA

在 jQuery 中,如果你使用 .on() 方法来绑定事件到一组元素上,而这些元素是后来动态添加到 DOM 中的,你需要使用事件委托(Event Delegation)的方式。

当你使用 $('#someElement').on('click', 'someSelector', function() {...}) 的形式时,如果 'someSelector' 指向的元素在绑定事件时还不存在于 DOM 中,那么这些元素将不会响应点击事件,除非你将事件绑定到一个在元素添加之前已经存在于 DOM 中的父元素上,并使用 'someSelector' 作为第二个参数。

在你的情况下,你可以将事件委托到 #svg-1 上,因为 #svg-1 是在你动态添加元素之前就已经存在于 DOM 中的。以下是使用事件委托的示例代码:

$('#svg-1').on("click", '.class1 .class2 .path1', function() {
    alert('12345');
});

这段代码的意思是,当 #svg-1 内部的任何元素(或其后代元素)被点击时,jQuery 会检查被点击的元素是否匹配选择器 '.class1 .class2 .path1'。如果匹配,则执行指定的函数(显示一个弹窗)。

使用这种方式,即使你后来动态地向 #svg-1 中添加了新的 .path1 元素,它们也会响应点击事件,因为事件监听器是绑定到不会改变的父元素 #svg-1 上的。

请注意,在动态更新 SVG 内容后,你不需要再次绑定点击事件监听器,因为使用事件委托的方式已经实现了这一点。只需确保你的事件委托代码在 SVG 内容更新之前已经执行过即可。

2 个回答

因为你之前的事件是绑定在path1上的,新增的元素虽然class也是path1,但已经不是同一个元素了。

对于这种情况,通常使用冒泡的原理,把事件绑定在上级不被移除的元素上,比如$('#svg-1').on('click', '.class1 .class2 .path1', function(){...})

动态更新html后,原先元素上绑定的事件随着原先元素的更新失效了,对新更新的元素重新绑定一次即可:

$('#svg-1').html('<g class="class1"><g role="group" class="class2"><g><g fill="#93c317" class="path1" stroke="#ffffff" stroke-width="1" opacity="1" id="id2"><g><g shape-rendering="auto"><path d="........."></path></g></g></g></g></g></g>');
$('.class1 .class2 .path1').on("click", function() {  alert('12345'); });
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏