使用 onclick 使 svg 图像对象可点击,避免绝对定位
Posted
技术标签:
【中文标题】使用 onclick 使 svg 图像对象可点击,避免绝对定位【英文标题】:Making an svg image object clickable with onclick, avoiding absolute positioning 【发布时间】:2011-01-18 18:15:03 【问题描述】:我尝试将我网站上的图片从img
更改为svg
,将img
标签更改为embed
和object
标签。但是,实现以前包含在img
标签中的onclick
函数被证明是最困难的。
我发现onclick
放在object
或embed
标签内时没有效果。
所以,我专门为 svg 制作了一个 div
,并将 onclick
放在这个 div
标记中。但是,除非访问者点击图像的边缘/填充,否则无效。
我已经阅读了关于覆盖div
的信息,但我试图避免使用absolute
定位,或者根本不指定position
。
还有其他方法可以将 onclick 应用于 svg 吗?
有人遇到过这个问题吗?欢迎提出问题和建议。
【问题讨论】:
【参考方案1】:您可以在 svg 本身中有一个 onclick 事件,我在工作中一直这样做。在你的 svg 的空间上做一个矩形,(所以最后定义它,记住 svg 使用画家模型)
rect.btn
stroke:#fff;
fill:#fff;
fill-opacity:0;
stroke-opacity:0;
然后作为 rect 的属性添加 onclick(也可以使用 js 或 jquery 完成)。
<div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<circle ... //your img svg
<rect class="btn" x="0" y="0" onclick="alert('click!')" />
</g>
</svg>
</div>
这几乎适用于所有浏览器:http://caniuse.com/svg
【讨论】:
是的,这对我有用,只是想添加一些 cmets/澄清。请查看提交的答案。 不错的解决方案。对于 CSS,似乎只需要fill-opacity: 0
。为什么要设置stroke
、fill
和stroke-opacity
?
它们的存在只是为了明确,以防止任何其他样式侵入。
这个答案的代码不相关,因为最初的问题是关于使用带有嵌入或对象标签的 svg。在任何情况下它都会起作用,但不应推荐,因为将 UI 代码放在图像文件中是没有意义的。
@DAG 操作并没有指定他想要使用对象或嵌入,只是提到它们是他尝试过的事情。【参考方案2】:
如果您可以将 svg 包装在另一个元素中(例如 a
)并将 onclick
放在包装器上,svg pointer-events: none;
CSS 就可以解决问题。
【讨论】:
【参考方案3】:我将“svg”标签包裹在“a”标签中,并将 onClick 事件放在“a”标签中
【讨论】:
【参考方案4】:通过点击事件在<object>
中点击SVG 的<g>
元素。工作 100%。看看<svg>
中的嵌套javascript。如果要重定向父页面,请不要忘记插入window.parent.location.href=
。
https://www.tutorialspoint.com/svg/svg_interactivity.htm
【讨论】:
【参考方案5】:这开始是对 RGB 解决方案的评论,但我无法适应它,因此将其转换为答案。其灵感完全来自 RGB。
RGB 的解决方案对我有用。但是,我想指出几点可能会帮助其他人(如我)到达这篇文章,他们不太熟悉哪个 SVG,并且很可能从图形包生成了他们的 SVG 文件(就像我一样)。
所以要应用我使用的 RGB 解决方案:
CSS
<style>
rect.btn
stroke:#fff;
fill:#fff;
fill-opacity:0;
stroke-opacity:0;
</style>
jquery 脚本
<script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script>
<script type="text/javascript">
$("document").ready(function()
$(".btn").bind("click", function(event)alert("clicked svg"));
);
</script>
用于编码将您预先存在的 SVG 文件包含在 SVG 代码内的组标记中的 html。
<div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<image x="0" y="0"
xlink:href="../_public/_icons/booked.svg" />
<rect class="btn" x="0" y="0" />
</g>
</svg>
</div>
但是,就我而言,我有几个 SVG 图标,我希望它们是可点击的,并且将这些图标中的每一个都合并到 SVG 标记中开始变得很麻烦。
因此,作为一种可以使用类的替代方法,我使用了 jquery.svg。这可能是这个插件的一个可耻的应用程序,它可以用 SVG 做各种各样的事情。但它使用以下代码工作:
<script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script>
<script type="text/javascript" src="jquery.svg.min.js"></script>
<script type="text/javascript">
$("document").ready(function()
$(".svgload").bind("click", function(event)alert("clicked svg"));
for (var i=0; i < 99; i++)
$(".svgload:eq(" + i + ")").svg(
onLoad: function()
var svg = $(".svgload:eq(" + i + ")").svg('get');
svg.load("../_public/_icons/booked.svg", addTo: true, changeSize: false);
,
settings:
);
);
</script>
HTML 在哪里
<div class="svgload" style="width: 10px; height: 10px;"></div>
我的想法的好处是,我可以在需要图标的地方使用适当的类,并避免在 HTML 正文中使用大量有助于可读性的代码。而且我只需要将预先存在的 SVG 文件合并一次。
编辑:这是由 Keith Wood 提供的更简洁的脚本版本:使用 .svg 的加载 URL 设置。
<script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script>
<script type="text/javascript" src="jquery.svg.min.js"></script>
<script type="text/javascript">
$("document").ready(function()
$('.svgload').on('click', function()
alert('clicked svg new');
).svg(loadURL: '../_public/_icons/booked.svg');
);
</script>
【讨论】:
【参考方案6】:如果你只使用 inline svg 没有问题。
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" style="width: 3.5in; height: 1in">
<circle id="circle1" r="30" cx="34" cy="34" onclick="circle1.style.fill='yellow';"
style="fill: red; stroke: blue; stroke-width: 2"/>
</svg>
【讨论】:
【参考方案7】:使用<object>
嵌入同源SVG 时,您可以使用objectElement.contentDocument.rootElement
访问内部内容。从那里,您可以轻松附加事件处理程序(例如,通过onclick
、addEventListener()
等)
例如:
var object = /* get DOM node for <object> */;
var svg = object.contentDocument.rootElement;
svg.addEventListener('click', function()
console.log('hooray!');
);
请注意,对于跨域 <object>
元素,这是不可能,除非您还控制 <object>
源服务器并且可以在那里设置 CORS 标头。对于没有 CORS 标头的跨域情况,对 contentDocument
的访问被阻止。
【讨论】:
【参考方案8】:也许您正在寻找的是 SVG 元素的 pointer-events 属性,您可以在 SVG w3C working group docs 上阅读。
您可以使用 CSS 来设置 SVG 元素在被单击时发生的情况等。
【讨论】:
【参考方案9】:只需将<embed/>
标记替换为<img/>
并删除类型属性即可。
例如,在我的代码中,而不是:
<embed src=\"./images/info_09c.svg\" type=\"image/svg+xml\" width=\"45\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'>
没有回答点击,我写道:
<img src=\"./images/info_09c.svg\" height=\"25\" width=\"25\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'>
它可以在 Internet Explorer 和 Google Chrome 中使用,我希望其他浏览器也可以。
【讨论】:
我猜你正在转义 xml 或其他东西的引用,但这至少在 IE 中有效,当它在 尝试用 img src 替换 【参考方案10】:您可以使用以下代码:
<style>
.svgwrapper
position: relative;
.svgwrapper
position: absolute;
z-index: -1;
</style>
<div class="svgwrapper" onClick="function();">
<object src="blah" />
</div>
b3ng0 写了类似的代码,但它不起作用。父级的 z-index 必须是自动的。
【讨论】:
【参考方案11】:我在最新版本的 Firefox、Chrome、Safari 和 Opera 上都能正常工作。
它依赖于具有绝对位置并设置宽度和高度的对象之前的透明div,因此它覆盖了下面的对象标签。
在这里,我有点懒,使用了内联样式:
<div id="toolbar" style="width: 600px; height: 100px; position: absolute; z-index: 1;"></div>
<object data="interface.svg" type="image/svg+xml">
</object>
我使用以下 JavaScript 将事件连接到它:
<script type="text/javascript">
var toolbar = document.getElementById("toolbar");
toolbar.onclick = function (e)
alert("Hello");
;
</script>
【讨论】:
【参考方案12】:假设您不需要跨浏览器支持(如果没有 IE 插件,这是不可能的),您是否尝试过使用 svg as a background image?
当然是实验性的东西,但我想我会提到它。
【讨论】:
好主意,但缺乏 Firefox 支持让我放弃了这个主意。【参考方案13】:您是否考虑过使用 CSS z-index
属性使容器 dev 位于 svg 的“顶部”?因为 div 是(大概)透明的,所以您仍然会看到与以前完全相同的图像。
我相信,这是解决您的问题的最佳实践、非 hack、预期的方法。 z-index
仅对具有position
属性为fixed
、relative
或正如您所听说的absolute
的元素有用。但是,您实际上不必移动对象。
例如:
<style>
.svgwrapper
position: relative;
z-index: 1;
</style>
<div class="svgwrapper" onClick="function();">
<object src="blah" />
</div>
对于它的价值,完全不使用onClick,而是使用javascript绑定click事件也会更加优雅和安全。不过,这完全是另一个问题。
【讨论】:
以上是关于使用 onclick 使 svg 图像对象可点击,避免绝对定位的主要内容,如果未能解决你的问题,请参考以下文章