如何在svg文档内的标签上创建一个事件“mouseover”(使用object标签调用)

时间:2016-03-07 12:54:22

标签: javascript svg

我有一个带有一些rect元素的svg图像,所有这些都由ID识别。 我插入我的svg:

<object id="svgObject" type="image/svg+xml" data="img/svg/monSvg.svg"></object>

因此,要访问内部的rect元素,我需要使用以下代码:

document.getElementById("svgObject").addEventListener("load",function(){

    var svgObject = document.getElementById("svgObject");
    var svgDoc = svgObject.contentDocument;
    var svgItem = svgDoc.getElementById("monID");
    svgItem.style.display ="inline" ;   
    svgItem.style.fill = "red";
    svgItem.style.strokeWidth = "0";

   });

所以这段代码有效。但是我希望在我的“svgItem”上添加一个鼠标,并尝试使用addEventListner,onmouseover等...但它不起作用...我的事件无法在Object标签文档中访问...

有人有解决这个问题的方法吗?

感谢您的帮助。

罗曼。

1 个答案:

答案 0 :(得分:1)

说实话,我的第一个猜测是你无法在<object>中定位单个SVG元素,但我有所纠正。至少在Firefox(开发者编辑器),Opera(开发者编辑器)和Safari(9.0.2)中。

重现的步骤:

HTML / JS

<script>
    function onoff(elm) {
        elm.addEventListener('mouseover', function(e) {
            elm.style.fill = '#f90';
        });
        elm.addEventListener('mouseout', function(e) {
            elm.style.fill = '';
        });
    }

    window.addEventListener('load', function(e) {
        var doc = document.querySelector('#sample'),
            svg = doc.contentDocument || doc.getSVGDocument(),
            path = svg.querySelectorAll('path'),
            i;

        for (i = 0; i < path.length; ++i) {
            onoff(path[i]);
        }
    });
</script>

the SVG I used

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <g fill="#F00" stroke="#3b5998" stroke-width="4">
    <path d="M28,6h44v16l-22,21l-22-21z" fill="#6d84b4"/>
    <path d="M28,95h44v-16l-22-21l-22,21z" fill="#6d84b4"/>
    <path d="M6,30v42h15l21-21l-21-21z" fill="#afbfde"/>
    <path d="M95,30v42h-15l-21-21l21-21z" fill="#afbfde"/>
  </g>
</svg>

现在,正如我通常会尝试直接从文件系统运行它,它将无法工作,两个文件必须从必须是网络服务器的same origin提供,否则SVG将加载,但您无法使用脚本访问它。

这只是其中一个警告,而不是最棘手的问题。 我个人不喜欢单独访问<object>内容作为文档的想法,因为它很麻烦,您的里程可能会根据您需要支持的浏览器而有所不同。我只是将<svg>嵌入到HTML中,并且可以使用纯CSS来处理悬停状态。

在这种情况下,您只需添加一个简单的规则

path:hover {
  fill: '#f90';
}

在你的问题中,你有以下一行

svgItem.style.display = "inline" ;

SVG元素没有display - flow的概念,虽然有某种流程,但您通常需要准确指定绘制元素的位置和方式。

最后,您可能想知道why I used both .contentDocument and .getSVGDocument()