在对象中的 SVG 元素上捕获鼠标事件,也是它的父容器 div

Posted

技术标签:

【中文标题】在对象中的 SVG 元素上捕获鼠标事件,也是它的父容器 div【英文标题】:Capture mouse events on SVG element in object, and also it's parent container div 【发布时间】:2016-10-07 20:24:21 【问题描述】:

我在加载 html 中的 SVG 文件时遇到了一个奇怪的问题。我将点击事件附加到 SVG 文件中的特定元素,效果很好。但是,我还需要将鼠标和触摸事件附加到它的父 div。似乎 SVG 对象正在捕获鼠标事件,因此它们不会冒泡到父 div。因此,我尝试将 SVG 上的指针事件设置为无。在这种情况下,父 div 接收鼠标事件,但现在子 SVG 元素不再接收鼠标事件。我尝试将子 svg 元素设置为指针事件:全部,但它仍然没有得到鼠标事件。我在这里做错了什么?

这是我嵌入 SVG 文件的方式:

 <div
  id="map"
  ng-pinchable
  scale-factor="2"
  max-zoom="2"
 >
   <object data="./media/map.svg" type="image/svg+xml"
     id="mapsvg"  ></object>
</div>

这是我通过 JS 向 SVG 元素添加事件的方式:

//add event listeners to stations
                var el = $scope.svgDoc.getElementById("station-test");
      el.style.pointerEvents = "all";
                el.addEventListener("mouseup",
                        function()
                            $scope.stationClicked("some id");
                        
                    );
      , false);

在这里,我将事件添加到持有 SVG 对象的父“地图”div:

 el.addEventListener("click", function() console.log("Hello World!"); );
 el.addEventListener("mousedown", function() console.log("mousedown"); );

提前致谢!

【问题讨论】:

getElementById("station-test") 我没有看到 ID 为“station-test”的元素。请澄清。 【参考方案1】:

好吧,到目前为止,我无法弄清楚为什么 SVG 元素没有获得点击事件,所以我只是创建了一个 JS 函数,它遍历所有子元素,并将鼠标的位置与边界矩形进行比较SVG 对象,本质上是按照我的预期重新创建点击行为。

$scope.onClickMap = function(event)
  console.log("on click map");
  var markers = $scope.svgDoc.querySelectorAll('*[id^="station"]');
  for(i=0;i<markers.length;i++)
    console.log("found markers: ",markers[i]);
    var rect = markers[i].getBoundingClientRect();
    if(event.offsetX > rect.left)
      if(event.offsetX < rect.right)
        if(event.offsetY > rect.top)
          if(event.offsetY < rect.bottom)
            $scope.stationClicked("some id");
  

所以它现在对我有用,但我很想知道为什么点击事件没有按预期触发/冒泡,如果有人知道这样做的更好方法的话。谢谢。

【讨论】:

您是否尝试将 svg 代码直接粘贴到 元素中的 html 中?它经常解决很多这样的问题。 @AliSomay 我考虑过这一点,但我宁愿不这样做,因为我希望能够继续编辑 SVG 文件,而不必每次进行更改时都复制和粘贴代码。虽然,我意识到我也可以为这类事情创建一个 grunt/gulp 任务,但它引出了一个问题,解决问题的最有效途径是什么?就我而言,我已经通过上述方法让它工作了。不过感谢您的建议。

以上是关于在对象中的 SVG 元素上捕获鼠标事件,也是它的父容器 div的主要内容,如果未能解决你的问题,请参考以下文章

Java中的事件监听机制

从 PIXI.js 中的同级或父 DOM 元素捕获鼠标事件

如何将鼠标悬停在子元素上而不悬停在 CSS 中的父元素上?

javaScript事件委托

js学习笔记26----事件冒泡,事件捕获

jquery事件冒泡