在 JavaScript 中单击 SVG 路径元素时事件侦听器未按预期工作

问题描述 投票:0回答:1

如何检测元素或其子元素是否被点击

我有一个包含多个 SVG 图标的父元素,每个图标都有一个名为

name
的属性设置为特定值。我将点击事件附加到父元素。如果单击的元素具有等于
name
的属性
setGameState
,并且想要执行一些操作,它不会按预期工作,因为有时
event.target
指向
path
内的
SVG
元素,所以如果条件是不工作。

const ele = document.getElementById("parent");
ele.addEventListener("click", (event) => {
  let target = event.target;
  console.log(target);
  if (target.getAttribute("name") == "setGameState") {
    //do other stuff
    console.log("svg with name setGameState clicked");
  }
});
<div id="parent">
  <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" name="setGameState" data-gamestate="true" class="topbar-icon" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><g><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM10.622 8.415l4.879 3.252a.4.4 0 0 1 0 .666l-4.88 3.252a.4.4 0 0 1-.621-.332V8.747a.4.4 0 0 1 .622-.332z"></path></g>
  </svg>
  <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" name="setGameState" data-gamestate="false" class="topbar-icon" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><g><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM10.622 8.415l4.879 3.252a.4.4 0 0 1 0 .666l-4.88 3.252a.4.4 0 0 1-.621-.332V8.747a.4.4 0 0 1 .622-.332z"></path></g></svg>
</div>

javascript jquery reactjs
1个回答
1
投票

您的问题在此处描述: https://gomakethings.com/detecting-click-events-on-svgs-with-vanilla-js-event-delegation/

可以使用

closest()
方法查找(潜在的)父 SVG 元素来解决。 https://developer.mozilla.org/en-US/docs/Web/API/Element/closest

在这里,我建议变量

btn
应该包含被点击的 SVG 元素或 null,如果其他元素(如父 DIV)被点击。

另一个(经典)解决方案可能是将 SVG 放在一个单独的文件 (mybutton.svg) 中,并使用 IMG 标签在 HTML 中引用它:

<IMG src="mybutton.svg" />

const ele = document.getElementById("parent");
ele.addEventListener("click", (event) => {
  let target = event.target;
  let btn = target.closest("svg");    // <- get clicked SVG element
  console.log("target tag="+target.tagName+" btn.tag="+btn?.tagName);
  // check that user clicked an SVG element and it has the right name:
  if (btn && btn.getAttribute("name") == "setGameState") {
    //do other stuff
    console.log("svg with name setGameState clicked");
  }
});
<div id="parent" style="border: 1px solid blue;">
  <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" name="setGameState" data-gamestate="true" class="topbar-icon" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><g><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM10.622 8.415l4.879 3.252a.4.4 0 0 1 0 .666l-4.88 3.252a.4.4 0 0 1-.621-.332V8.747a.4.4 0 0 1 .622-.332z"></path></g>
  </svg>
  <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" name="setGameState" data-gamestate="false" class="topbar-icon" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><g><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM10.622 8.415l4.879 3.252a.4.4 0 0 1 0 .666l-4.88 3.252a.4.4 0 0 1-.621-.332V8.747a.4.4 0 0 1 .622-.332z"></path></g></svg>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.