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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2296097/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 02:15:26  来源:igfitidea点击:

Making an svg image object clickable with onclick, avoiding absolute positioning

htmlcsssvg

提问by user256410

I have tried to change the images on my site from imgto svg, changing imgtags to embedand objecttags. But, implementing the onclickfunction, which previously was contained in the imgtag, is proving most difficult.

我试图将我网站上的图像从更改imgsvg,将img标签更改为embedobject标签。但是,实现onclick以前包含在img标签中的功能被证明是最困难的。

I found onclickhad no effect when placed inside the objector embedtag.

我发现onclick放置在objectorembed标签内时没有效果。

So, I made a divexclusively for the svg, and placed onclickin this divtag. But, no effect unless visitor clicks on the edges/padding of the image.

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

I have read about overlaying a div, but am trying to avoid using absolutepositioning, or specifying positionat all.

我已经阅读了关于覆盖 a 的内容div,但我试图避免使用absolute定位或完全指定position

Is there another way to apply onclick to a svg?

有没有另一种方法可以将 onclick 应用于 svg?

Has anyone encountered this problem? Questions and suggestions are welcome.

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

回答by RGB

You can have an onclick event in the svg itself, I do this all the time in my work. make a rect over the space of your svg, (so define it last, remember svg uses the painters model)

您可以在 svg 本身中设置一个 onclick 事件,我在工作中一直这样做。在你的 svg 的空间上做一个矩形,(所以最后定义它,记住 svg 使用画家模型)

rect.btn {
  stroke:#fff;
  fill:#fff;
  fill-opacity:0;
  stroke-opacity:0;
}

then as an attribute to the rect add the onclick (this can be done with js or jquery as well).

然后作为 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>

this will work in most modern browsers, http://caniuse.com/svg...though if you need cross compatability, you can implement Google Chrome Frame. http://www.google.com/chromeframe

这将适用于大多数现代浏览器,http://caniuse.com/svg...不过如果您需要交叉兼容性,您可以实现 Google Chrome Frame。http://www.google.com/chromeframe

回答by codepuppy

This started as a comment on RGB's solution but I could not fit it in so have converted it to an answer. The inspiration for which is entirely RGB's.

这开始是对 RGB 解决方案的评论,但我无法适应它,因此已将其转换为答案。其灵感完全是RGB。

RGB's solution worked for me. However, I wished to note a couple of points which may help others arriving at this post (like me) who are not that familiar which SVG and who may very well have generated their SVG file from a graphics package (as I had).

RGB 的解决方案对我有用。但是,我想指出几点,它们可能会帮助到这篇文章的其他人(像我一样),他们不太熟悉哪种 SVG 并且很可能已经从图形包中生成了他们的 SVG 文件(就像我一样)。

So to apply RGB's solutions I used:

因此,要应用我使用的 RGB 解决方案:

The CSS

CSS

 <style>
    rect.btn {
        stroke:#fff;
        fill:#fff;
        fill-opacity:0;
        stroke-opacity:0;
    }
</style>

The jquery script

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>

The HTML to code the inclusion of your pre-existing SVG file in the group tag inside the SVG code.

用于编码将您预先存在的 SVG 文件包含在 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>

However, in my case I have several SVG icons which I wish to be clickable and incorporating each of these into the SVG tag was starting to become cumbersome.

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

So as an alternative approach where I could employ Classes I used jquery.svg. This is probably a shameful application of this plugin which can do all sorts of stuff with SVG's. But it worked using the following code:

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

where HTML

其中 HTML

<div class="svgload" style="width: 10px; height: 10px;"></div>

The advantage to my thinking is that I can use the appropriate class where ever the icons are needed and avoid quite a lot of code in the body of the HTML which aids readability. And I only need to incorporate the pre-existing SVG file once.

我的想法的优点是我可以在需要图标的地方使用适当的类,并避免在 HTML 正文中使用大量代码来提高可读性。我只需要合并预先存在的 SVG 文件一次。

Edit:Here is a neater version of the script courtesy of Keith Wood: using .svg's load URL setting.

编辑:这是 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>

回答by peter

If you just use inline svg there is no problem.

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

回答by Richard Garside

I got this working accross the latest versions of Firefox, Chrome, Safari and Opera.

我在最新版本的 Firefox、Chrome、Safari 和 Opera 上都能正常工作。

It relies on a transparent div before the object that has absolute position and set width and height so it covers the object tag below.

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

Here it is, I've been a bit lazy and used inline styes:

在这里,我有点懒惰并使用了内联样式:

<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>

I used the following JavaScript to hook up an event to it:

我使用以下 JavaScript 将事件连接到它:

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

回答by Mihai Daniel Frumu?elu

It worked by simply replacing the <embed/>tag with <img/>and deleting the type attribute.

它的工作原理是简单地用type 属性替换<embed/>标签<img/>并删除它。

For instance, in my code, instead of:

例如,在我的代码中,而不是:

<embed src=\"./images/info_09c.svg\" type=\"image/svg+xml\" width=\"45\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'> 

which does not answer the clicking, I wrote:

这不回答点击,我写道:

<img src=\"./images/info_09c.svg\" height=\"25\" width=\"25\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'> 

It works in Internet Explorer and Google Chrome, and I hope that in the other browsers too.

它适用于 Internet Explorer 和 Google Chrome,我希望也适用于其他浏览器。

回答by candu

When embedding same-origin SVGs using <object>, you can access the internal contents using objectElement.contentDocument.rootElement. From there, you can easily attach event handlers (e.g. via onclick, addEventListener(), etc.)

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

For example:

例如:

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

Note that this is not possiblefor cross-origin <object>elements unless you also control the <object>origin server and can set CORS headers there. For cross-origin cases without CORS headers, access to contentDocumentis blocked.

请注意,这对于跨源元素是不可能的<object>除非您还控制<object>源服务器并可以在那里设置 CORS 标头。对于没有 CORS 标头的跨域情况,将contentDocument阻止访问。

回答by Oleg Torbasow

You could use following code:

您可以使用以下代码:

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

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

b3ng0 wrote similar code but it does not work. z-index of parent must be auto.

b3ng0 写了类似的代码,但它不起作用。parent 的 z-index 必须是 auto。

回答by b3ng0

Have you looked into using the CSS z-indexproperty to make the container dev be "on top" of the svg? Because the div is (presumably) transparent, you will still see the image exactly as before.

您是否考虑过使用 CSSz-index属性使容器 dev 位于 svg 的“顶部”?因为 div 是(大概)透明的,所以您仍然会像以前一样看到图像。

This, I believe, is the best-practice, non-hack, intended way of solving your problem. z-indexis only useful for elements that have a positionproperty of fixed, relative, or, as you've heard, absolute. However, you don't actually have to move the object.

我相信,这是解决问题的最佳实践,非黑客,预期的方式。z-index仅适用于有一个元素有用position的特性fixedrelative或者,你听说过,absolute。但是,您实际上不必移动对象。

For example:

例如:

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

For what it's worth, it would also be a little more elegant and safe to not use onClick at all, but instead to bind the click event using javascript. That's another issue altogether, though.

就其价值而言,根本不使用 onClick 而是使用 javascript 绑定单击事件也会更加优雅和安全。不过,这完全是另一个问题。

回答by Russell Leggett

Assuming you don't need cross browser support (which is impossible without a plugin for IE), have you tried using svg as a background image?

假设您不需要跨浏览器支持(如果没有 IE 插件是不可能的),您是否尝试过使用svg 作为背景图像

Experimental stuff for sure, but thought I would mention it.

肯定是实验性的东西,但我想我会提到它。

回答by Danny Bullis

Perhaps what you're looking for is the SVG element's pointer-eventsproperty, which you can read about at the SVG w3C working group docs.

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

You can use CSS to set what happens to the SVG element when it is clicked, etc.

您可以使用 CSS 设置单击 SVG 元素时发生的情况等。