在 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,它应该与您尝试执行的操作非常相似。它使用
还请注意,***的 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 元素?