如何为图形标签设置点击监听器?

How to set on click listener for figure tag?

我有以下简单的 html 文档:

<!DOCTYPE html>
<html>
<head>
</head>

<body>
    <figure>
        <object class="" type="image/svg+xml" data="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350"></object>
    </figure>
</body>

<script>
    var figures = document.querySelectorAll('figure')
    for (let figure of figures) {
        figure.addEventListener("click", function () {
            console.log("hello")
        })
    }
</script>

</html>

但是,当我点击图片时没有任何反应。是否可以为图形标签设置点击侦听器,如果不能,我可以使用哪些替代方案?

您可以像添加任何其他元素一样向 figure 元素添加单击事件处理程序。当您的 JavaScript 运行并尝试绑定点击事件时,您的图形元素有可能不存在于 DOM 中。要尝试的一件事是确保您的图形数组如您所愿地返回。另一件要看的事情是在你的 for of 循环中你的 figure 变量是你所期望的。

const myFigure = document.querySelector('#myFigure');
myFigure.onclick = (evt) => {
  console.log('I was just clicked');
}
<figure id="myFigure">
  <img src="https://via.placeholder.com/350x150" />
</figure>

var figures = document.getElementsByTagName('figure');
for (let i = 0; i < figures.length; i++) {
    figures[i].onclick = function (e) {
        console.log("hello from figure: " + i);
    };
}
<figure>
  <img style="width: 100px; height: 100px;" src="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350" />
</figure>
<br><br>
<figure>
  <img style="width: 100px; height: 100px;" src="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350" />
</figure>
<br><br>
<figure>
  <img style="width: 100px; height: 100px;" src="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350" />
</figure>
<br><br>
<figure>
  <img style="width: 100px; height: 100px;" src="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350" />
</figure>

问题不在于 figure,而在于 object tag。此标记在嵌套上下文中运行,不会将事件传播回 parent;因此,当您单击由 object 加载的图形时,它不会从嵌入式 object 返回,永远不会到达您的 figure.

上的单击

The object tag is meant to run embedded applications (flash apps back in the day) so it has an abnormal behaviour similar to iframe, there are a lot of security concerns.

您可以使用 img 来加载您的 svg 而不是 object,它会以相同的方式加载并且这确实会触发事件返回到 parent,因此触发了对 parent figure.

的点击
<figure>
  <img width="100" height="100" src="./path/to/img.svg">
</figure>

下面有一个片段显示了使用 objectimg 加载图像时的不同行为,第二个触发了点击。

var figures = document.querySelectorAll('figure')
for (let figure of figures) {
  figure.addEventListener("click", function() {
    console.log("hello")
  })
}
<figure>
  <figcaption>I'm an object and I don't propagate events back to my parent</figcaption>
  <object width="100" height="100" type="image/svg+xml" data="https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg"></object>
</figure>

<figure>
  <figcaption>I'm an img and I propagate events back to my parent</figcaption>
  <img width="100" height="100" src="https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg">
</figure>