通过 onclick 使 svg 图像对象可点击,避免绝对定位

我已经尝试改变我的网站上的图像从 imgsvg,改变 img标签到 embedobject标签。但是,实现以前包含在 img标记中的 onclick函数被证明是最困难的。

我发现 onclick在放置在 objectembed标签内时没有任何作用。

因此,我为 svg 专门制作了一个 div,并将 onclick放在这个 div标记中。但是,除非访问者点击图像的边缘/填充,否则没有效果。

我已经阅读了有关覆盖 div,但我试图避免使用 absolute定位,或指定 position在所有。

还有其他方法可以将 onclick 应用于 svg 吗?

有人遇到过这个问题吗? 欢迎提出问题和建议。

175604 次浏览

您是否考虑过使用 CSS z-index属性使容器 dev 位于 svg 的“顶部”?因为 div (可能)是透明的,所以您仍然可以看到与之前完全一样的图像。

我相信,这是解决你的问题的最佳实践,非黑客,预期的方法。z-index只适用于具有 fixedrelativeabsolute属性的 position元素。但是,您实际上并不需要移动对象。

例如:

<style>
.svgwrapper {
position: relative;
z-index: 1;
}
</style>
<div class="svgwrapper" onClick="function();">
<object src="blah" />
</div>

不管怎样,完全不使用 onClick 而是使用 javascript 绑定 click 事件会更优雅和安全一些。不过这完全是另一个问题。

假设你不需要跨浏览器支持(没有 IE 插件是不可能的) ,你试过使用 作为背景图像吗?

当然是实验性的,但我觉得应该提一下。

我在 Firefox、 Chrome、 Safari 和 Opera 的最新版本中都得到了这个功能。

它依赖于对象前面的一个透明 div,该 div 具有绝对位置和设置的宽度和高度,因此它覆盖下面的对象标记。

在这里,我已经有点懒惰和使用内联风格:

<div id="toolbar" style="width: 600px; height: 100px; position: absolute; z-index: 1;"></div>
<object data="interface.svg" width="600" height="100" type="image/svg+xml">
</object>

我使用以下 JavaScript 将一个事件挂接到它:

<script type="text/javascript">
var toolbar = document.getElementById("toolbar");
toolbar.onclick = function (e) {
alert("Hello");
};
</script>

您可以在 svg 本身中有一个 onclick 事件,我在工作中一直这样做。在 svg 的空间上做一个 rect (最后定义它,记住 svg 使用的是 painters 模型)

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" width="10" height="10" onclick="alert('click!')" />
</g>
</svg>
</div>

这将工作在几乎所有的浏览器: http://caniuse.com/svg

您可以使用以下代码:

<style>
.svgwrapper {
position: relative;
}
.svgwrapper {
position: absolute;
z-index: -1;
}
</style>


<div class="svgwrapper" onClick="function();">
<object src="blah" />
</div>

B3ng0编写了类似的代码,但是不能工作。

这开始作为一个 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 代码中的 group 标记中包含预先存在的 SVG 文件的 HTML 代码。

<div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<image x="0" y="0" width="10" height="10"
xlink:href="../_public/_icons/booked.svg" width="10px"/>
<rect class="btn" x="0" y="0" width="10" height="10"/>


</g>
</svg>
</div>

然而,在我的例子中,我有几个 SVG 图标,我希望可以点击,并将其中的每一个合并到 SVG 标记中开始变得很麻烦。

因此,作为一种可以使用 Class 的替代方法,我使用 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 的 load 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>

它只需用 <img/>替换 <embed/>标记并删除 type 属性即可。

例如,在我的代码中,代替:

<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 和谷歌浏览器,我希望其他浏览器也能这样。

也许您正在寻找的是 SVG 元素的 指针事件属性,您可以在 SVG w3C 工作组文档中阅读该属性。

您可以使用 CSS 来设置当单击 SVG 元素时会发生什么,等等。

当使用 <object>嵌入同源 SVG 时,可以使用 objectElement.contentDocument.rootElement访问内部内容。从那里,您可以很容易地附加事件处理程序(例如,通过 onclickaddEventListener()等)

例如:

var object = /* get DOM node for <object> */;
var svg = object.contentDocument.rootElement;
svg.addEventListener('click', function() {
console.log('hooray!');
});

请注意,这是 不可能,用于跨原始 <object>元素,除非您还控制 <object>原始服务器,并且可以在那里设置 CORS 头。对于没有 CORS 头的跨来源病例,访问 contentDocument被阻止。

如果只使用内联 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>

通过 Click event 单击 <object>中的 SVG 的 <g>元素。百分百有效。看看 <svg>中嵌套的 javascript。如果要重定向父页,不要忘记插入 window.parent.location.href=

Https://www.tutorialspoint.com/svg/svg_interactivity.htm

我将‘ svg’标记包装在‘ a’标记中,并将 onClick 事件放在‘ a’标记中

如果您可以将 svg 封装在另一个元素(例如 a)中并将 onclick放在封装器中,那么 svg {pointer-events: none;} CSS 就可以完成这项工作。