在 javascript 中的嵌入式 SVG 元素上添加点击事件

Posted

技术标签:

【中文标题】在 javascript 中的嵌入式 SVG 元素上添加点击事件【英文标题】:Add click event on elements of an embedded SVG in javascript 【发布时间】:2012-04-14 06:34:19 【问题描述】:

我得到this SVG image from Wikipedia 并使用此代码将其嵌入到网站中:

<embed src="circle1.svg" type="image/svg+xml"/>

如果你运行它,你可以检查元素并查看源代码。图像中的所有国家都是独立的元素。如果我点击一个国家,我想提醒那个国家的 id,因为每个国家在 SVG 中都有一个由两个字母组成的 id。有谁知道这样做的方法?如果我把它放在一个元素中会更容易吗?

【问题讨论】:

【参考方案1】:

这是一个example,它应该与您尝试执行的操作非常相似。它使用 而不是 ,但这只是一个小细节。关于如何从父文档获取嵌入文档的 DOM,请参见另一个 example,两者之间略有不同。

还请注意,***的 svg 地图非常大,因此您需要在实际使用网站之前优化 svg,例如 SVG Cleaner 或 SVG Scour。

【讨论】:

是的,这几乎正是我想要做的。但它只是我还是第一个示例仅适用于 Internet Explorer? 它在 Opera 中也能正常工作。但是 webkit 和 gecko 似乎不能在 display:none 子树中的元素上正确计算 bbox。我已经用可见性替换了那些:隐藏,现在悬停标签显示在所有浏览器中。 Safari 10 无法设置嵌入式 SVG 的颜色 @BrianStallter 好的,是的,在 Chrome Canary v61 中,导出按钮只是弹出一个空窗口,也许是 Chrome 中的一些新策略?它在 Chrome v59 中运行良好。【参考方案2】:

如果您的 SVG 包含在 DOM 中,您可以使用与基本 html 相同的方式将事件侦听器附加到单独的元素。使用 jQuery 的一个例子是:http://jsfiddle.net/EzfwV/

更新:大多数现代浏览器都支持内联 svg,因此要将源代码加载到 DOM 中,您所要做的就是从资源中加载它(使用类似 jQuery 的 load() 之类的东西)。

编辑:更具体的例子http://jsfiddle.net/EzfwV/3/

【讨论】:

我尝试将 svg 加载到 id 为“map”的 div 中。但是我收到警报,我看不到 svg 图像 $('#map').svg(); var svg = $('#map').svg('get'); svg.load('images/world.svg',onLoad: function() alert('ready'); ); 你的问题是你试图将 world.svg 加载到现有的 svg 标签中? (我想)。尝试类似 $('#map').load('images/world.svg', function() alert('ready'));【参考方案3】:

好的,使用您的 cmets 我找到了问题的答案。我在 svg 本身中添加了这段代码。

<script type="text/javascript"> <![CDATA[
    function addClickEvents() 
        var countries = document.getElementById('svg1926').childNodes;
        var i;
        for (i=0;i<countries.length;i++)
            countries[i].addEventListener('click', showCountry);
        
    

    function showCountry(e) 
        var node = e.target;
        if (node.id != 'ocean') 
            node = getCorrectNode(node);
        
        alert(node.id);
    

    function getCorrectNode(node) 
        if (node.id.length == 2 || node.id == 'lakes') 
            return node;
        
        return getCorrectNode(node.parentNode);
    
]]> </script>

函数 addClickEvents 在 svg 加载时触发。 但我还有另一个问题。我必须使用

将此 svg(带有代码)嵌入到 HTML 文档中
<embed src="circle1.svg" type="image/svg+xml" />

我必须将它放入 HTML 文档中的 div 中,而不是提醒 id。 如何从 svg 中获取此 id?

【讨论】:

【参考方案4】:

2016 年 7 月更新

现在可以响应来自embed 元素的事件,条件是您嵌入了来自同一域的内容。我以 JSFiddle 的形式创建了一个快速演示。最重要的是可以通过embeddingElement.@987654322@访问嵌入的文档。从那里,可以访问 SVG 元素并安装点击事件处理程序。

实现说明:在演示中,我将事件处理程序添加到所有path 元素。出于性能原因,您可能希望将单个事件处理程序添加到 SVG,然后在处理程序中使用事件目标。编辑:就像在这个 updated Fiddle.

旧答案

快速的谷歌搜索给我带来了here。我想这就是你问题的答案,对吧?

在这里总结一下:不可能在embed 元素上捕获事件,不幸的是,唯一的解决方案是修改 SVG 文件。

这是一个如何将 JavaScript 嵌入 SVG 文件的小示例 (JSFiddle)。它基于来自 IBM developerWorks 的 example。

<svg>
  <script type="text/javascript">
    <![CDATA[
    var redVal = 0;
    var greenVal = 0;
    var blueVal = 0;

    function changeCol(evt) 
       redVal = Math.round(Math.random() * 255);
       greenVal = Math.round(Math.random() * 255);
       blueVal = Math.round(Math.random() * 255);
       evt.target.setAttribute("fill",
             "rgb(" + redVal + "," + greenVal + "," + blueVal + ")");

    
    // ]]>
  </script>
  <circle cx="200" cy="200" r="100" fill="blue"
          onclick="changeCol(evt)" />
</svg>

【讨论】:

没有。我不想在整个 svg 中添加点击事件,而是在其中的每一层上添加多个点击事件 大安:你确定吗?根据答案,如果不将 javascript 嵌入到 SVG 文档中,您将无法处理点击事件。事实上,您甚至看不到 embed 元素上的事件,更不用说 SVG 元素上的事件了。我不知道该文件的许可等,但如果可以,我建议您编辑文档以添加点击处理程序。 这正是我的想法。我已经编辑了我的答案,以包含另一个解释如何做到这一点的教程。 所以我必须在 svg 中手动添加每个国家/地区的点击事件,然后将代码粘贴到 html 文档中? 当我尝试这段代码时,我得到“evt.getTarget 不是一个函数”。我必须改用 evt.target。【参考方案5】:

一个简单的方法是

使用 javascript 在 SVG 中动态创建路径 动态添加样式 向路径添加事件 附加到现有的 SVG。

脚本

 <svg id="mySvg"></svg>

var XMAX = 500;
var YMAX = 500;
var _xx=10;
var _reg=100;
var _l=10;
// Create PATH element
for(var x=1;x<20;x++)

var pathEl = document.createElementNS("http://www.w3.org/2000/svg", "path");
pathEl.setAttribute('d','M'+_l+' 100 Q 100  300 '+_l+' 500' );
pathEl.style.stroke = 'rgb('+(_reg)+',0,0)';
pathEl.style.strokeWidth = '5';
pathEl.style.fill = 'none';
    $(pathEl).mousemove(function(evt)$(this).css("strokeWidth":"3","stroke":"#ff7200").hide(100).show(500).css("stroke":"#51c000"));

$('#mySvg').append(pathEl);
_l+=50;

Live Demo in JSFiddle

【讨论】:

以上是关于在 javascript 中的嵌入式 SVG 元素上添加点击事件的主要内容,如果未能解决你的问题,请参考以下文章

如何检查嵌入的 SVG 文档是不是加载到 html 页面中?

嵌入在对象元素中的 SVG 上的鼠标指针悬停/jquery 单击事件不起作用

如何使用 JavaScript 在 <object> 标记内选择 SVG 元素?

使用嵌入或对象标签中的元素

在 HTML 中嵌入外部 SVG 以进行 JavaScript 操作

带有 SVG 文档的 jQuery