简体   繁体   English

如何让SVG的透明部分可以点击?

[英]How to make transparent part of SVG clickable?

I have an SVG that uses:hover to change color.我有一个 SVG 使用:hover 来改变颜色。 It only works when I hover over the solid part of the SVG, not the transparent part.它仅在我 hover 超过 SVG 的实心部分时有效,而不是透明部分。 I'm wondering how you could make the SVG interact with the mouse hovering anywhere over the whole SVG. The point of this is to make the SVG a link and the link only clickable on certain portions of the SVG. I don't just want a solution to this particular instance but a solution that works for many instances (If I wanted different parts of the SVG clickable.) The elements in my SVG are directly connected to CSS and grouped with a <g> tag to group the clickable elements.我想知道如何使 SVG 与鼠标悬停在整个 SVG 的任何位置进行交互。这样做的目的是使 SVG 成为一个链接,并且该链接只能在 SVG 的某些部分上单击。我不只是想要这个特定实例的解决方案但是适用于许多实例的解决方案(如果我想要 SVG 的不同部分可点击。)我的 SVG 中的元素直接连接到 CSS 并使用 <g> 标签分组以对可点击元素进行分组。

Edit: the SVG is in an object tag编辑:SVG 在 object 标签中

SVG SVG

<?xml-stylesheet type="text/css" href="svg.css" ?>
<svg xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg3036" version="1.1" inkscape:version="0.48.2 r9819" width="58" height="58">
         <g class="test">
  <path d="M 8.1 32.8 C 7.1 30.1 0.3 -4.6 11.1 4.9 21.9 14.5 15.9 12.8 29 12.8 42.1 12.9 36.1 14.6 46.9 5.1 57.7 -4.5 50.9 30.3 49.9 32.9 48.9 35.6 37.6 54.8 29 54.7 20.4 54.6 9.1 35.4 8.1 32.8 z" id="path3119" inkscape:connector-curvature="0" sodipodi:nodetypes="zzzzzzz" class="wolf"/>
  <path d="M 31.5 23.3 46.6 21" id="path5212" inkscape:connector-curvature="0" sodipodi:nodetypes="cc" class="eyes"/>
  <path d="M 33 23 C 32.3 33.9 45 22 45.2 21" id="path5260" inkscape:connector-curvature="0" sodipodi:nodetypes="cc" class="eyes"/>
  <path sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path5262" d="M 26.5 23.3 11.4 21" class="eyes"/>
  <path sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path5264" d="M 25 23 C 25.7 33.9 13 22 12.8 21" class="eyes"/>
  </g>
</svg>

CSS CSS

.wolf{
    fill:   none;
    fill-opacity:   0;
    stroke-width:   3.672px;
    stroke-linejoin:    round;
} /*.wolf:hover {
    stroke: #777777;
}*/

.eyes{
    fill:   none;
    fill-opacity: 0;
    stroke-width:   1.26708329px;
}

.test {
    stroke: #5ff6ff;
} .test:hover {
    stroke: #555555;
}     

JSfiddle JSfiddle

SVG2 adds a new keyword bounding-box to 'pointer-events' to make this easier. SVG2为'pointer-events'添加了一个新的关键字bounding-box ,以使其更容易。 It applies to groups as well as to shapes, in your example it would become: 它适用于组和形状,在您的示例中它将变为:

.test {
  pointer-events: bounding-box;
  stroke: #5ff6ff;
}
.test:hover {
  stroke: #555555;
}

See jsfiddle . jsfiddle Right now that should work in Chrome Canary or Opera Dev builds. 现在,它应该适用于Chrome Canary或Opera Dev版本。

It depends on the shapes, but it's possible to get it working in the currently shipping browsers too. 这取决于形状,但也可以在当前发布的浏览器中使用它。 Eg by using pointer-events="all" on the largest shape, and then using CSS selectors creatively to get the stroke applied where you want it. 例如,在最大的形状上使用pointer-events="all" ,然后创造性地使用CSS选择器将笔画应用到您想要的位置。 It's a bit tricky since you probably want the stroke to apply to the group although the actually hovered element is the shape inside the group. 这有点棘手,因为您可能希望将笔划应用于组,尽管实际上悬停的元素是组内的形状。

Another alternative is to script it using mouseenter and mouseleave events on the <g> element. 另一种方法是使用<g>元素上的mouseentermouseleave事件编写脚本。

You can include pointer-events="visible" in the test <g> and a function call where the function is in the parent HTML (This tested OK in IE/CH/FF) eg 您可以在测试<g>包含指针事件=“可见”,并在函数调用中包含函数在父HTML中(这在IE / CH / FF中测试正常),例如

<svg xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg3036" version="1.1" inkscape:version="0.48.2 r9819" width="58" height="58">
         <g pointer-events="visible" onclick="parent.testHover()" class="test" fill="none" stroke="black" stroke-width="2">
  <path d="M 8.1 32.8 C 7.1 30.1 0.3 -4.6 11.1 4.9 21.9 14.5 15.9 12.8 29 12.8 42.1 12.9 36.1 14.6 46.9 5.1 57.7 -4.5 50.9 30.3 49.9 32.9 48.9 35.6 37.6 54.8 29 54.7 20.4 54.6 9.1 35.4 8.1 32.8 z" id="path3119" inkscape:connector-curvature="0" sodipodi:nodetypes="zzzzzzz" class="wolf"/>
  <path d="M 31.5 23.3 46.6 21" id="path5212" inkscape:connector-curvature="0" sodipodi:nodetypes="cc" class="eyes"/>
  <path d="M 33 23 C 32.3 33.9 45 22 45.2 21" id="path5260" inkscape:connector-curvature="0" sodipodi:nodetypes="cc" class="eyes"/>
  <path sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path5262" d="M 26.5 23.3 11.4 21" class="eyes"/>
  <path sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path5264" d="M 25 23 C 25.7 33.9 13 22 12.8 21" class="eyes"/>
  </g>
</svg>

EDIT - Added. 编辑 - 添加。

I've tested using your svg as the src for an <img> rather than an <object> and placed it in a link. 我已经测试过使用svg作为<img>而不是<object>的src并将其放在链接中。 That works, is clickable in all browsers. 这是可行的,可在所有浏览器中点击。 There is no need to add the pointer-events or functiont call. 无需添加指针事件或功能调用。 Therefore you could use img rather than object. 因此你可以使用img而不是object。

The existing 'pointer events' answers to this question helped me get to this solution: 现有的“指针事件”这个问题的答案帮助我找到了这个解决方案:

<svg id="example" pointer-events="bounding-box" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 300">

The pointer-events="bounding-box" is best placed within the SVG tag if you have transparent areas you want to be clickable, eg with an icon or (as above) a logo that links to a website homepage with an embedded link (defined as xlink:href). 如果你想要可点击的透明区域, pointer-events="bounding-box"最好放在SVG标签内,例如带有图标或(如上所示)标识链接到带有嵌入链接的网站主页(定义为xlink:href)。

If you want a valid html document in the end. 如果你想要一个有效的HTML文档。 Surround the svg element with an anchor tag if you are planning in turning it into a link. 如果您打算将其转换为链接,请使用锚标记环绕svg元素。

Also do not forget to turn the link into a block or inline-block element. 另外,不要忘记将链接转换为块或内联块元素。 (This depending on your needs) (这取决于您的需求)

There is a hack you can do by using a filter. 使用过滤器可以做到黑客攻击。 Filter effects can change fills to transparent without changing their clickability. 滤镜效果可以将填充更改为透明,而不会更改其可点击性。 Below, you add a semi-transparent fill to your graphic, but then use a filter to remove it. 在下面,您将为图形添加半透明填充,但随后使用过滤器将其删除。

.wolf{
    fill:   blue;
     fill-opacity:  0.09;
    stroke-width:   3.672px;
    stroke-linejoin:    round;
} /*.wolf:hover {
    stroke: #777777;
}*/

.eyes{
    fill:   none;
    fill-opacity: 0;
    stroke-width:   1.26708329px;
}

    <defs>
        <filter id="greenscreen">
        <feComponentTransfer>
            <feFuncA type="table" tableValues="0 0 .2 .3 .4 .5 .6 .7 .8 .9 1"/>
        </feComponentTransfer>
    </filter>
    </defs>
  <g class="test" filter="url(#greenscreen)">

etc.

Edit: svg:hover .test { stroke: #555555} 编辑: svg:hover .test { stroke: #555555}

Ignore previous answer (below) it was addressing a different issue. 忽略之前的答案(下面),它正在解决另一个问题。

Create an empty transparent object - ie <rect> that's the size and shape of the <svg> and place it just before the </a></svg> (don't wrap!). 创建一个空的透明对象 - 即<rect> ,它是<svg>的大小和形状,并将它放在</a></svg> (不要换行!)。

I posted this question all the way back in 2014. Essentially I was trying to solve two problems, how do I make an svg retain hover effects on a transparent part of an svg(specifically with an svg being used in an object tag so I can use hover effects easily), and how do I make it so that individual aspects of the svg can be used as independent links.我早在 2014 年就发布了这个问题。基本上我试图解决两个问题,我如何使 svg 在 svg 的透明部分保留 hover 效果(特别是 svg 在 object 标签中使用,这样我就可以轻松使用 hover 效果),以及如何使 svg 的各个方面可以用作独立链接。

I tried a lot of complicated solutions, and eventually found a very simple solution to the first problem.我尝试了很多复杂的解决方案,最终找到了第一个问题的非常简单的解决方案。 Simply set a fill (any color will do as long as it's not set to fill: none ), and set fill-opacity: 0 .只需设置一个fill (任何颜色都可以,只要它没有设置为fill: none ),然后设置fill-opacity: 0 This retains the pointer-click events, while keeping the svg transparent.这保留了指针单击事件,同时保持 svg 透明。 This makes perfect sense in hindsight, but can be confusing if you are using a pre-made svg where the fill may have been set to none(appropriately so.)事后看来,这很有意义,但如果您使用的是预制的 svg,其中fill可能已设置为无(适当地如此),则可能会造成混淆。

Here's an example of what that might look like in practice:这是在实践中可能看起来像的示例:

<circle cx="100" cy="75" r="50" style="fill: green; fill-opacity: 0;" />

This will create a circle that will retain any pointer-events(such as hover), despite being completely transparent.这将创建一个圆圈,该圆圈将保留任何指针事件(例如悬停),尽管它是完全透明的。

I probably should have posted an answer at the time with this solution, because I assume that's the problem that most people who found this question were probably looking for a solution for.当时我可能应该用这个解决方案发布一个答案,因为我认为这是大多数发现这个问题的人可能正在寻找解决方案的问题。 But at the time I felt like the answer was unfinished.但当时我觉得答案没有完成。 I forgot about this question, and my solution to the first problem.我忘记了这个问题,以及我对第一个问题的解决方案。 But I decided I should revisit this question and give some much needed closure.但我决定我应该重新审视这个问题并给出一些急需的结论。

Since I asked this question, <a> tags within svg's have received an update, and now it is quite simple to apply links to individual parts of an svg. It works exactly as you would imagine: <a href="" target="_blank">...Your SVG element here</a> which was not exactly the case before(or at least I didn't understand how it worked before).自从我问了这个问题后,svg 中的<a>标签得到了更新,现在可以非常简单地将链接应用到 svg 的各个部分。它的工作原理与您想象的完全一样: <a href="" target="_blank">...Your SVG element here</a>以前不是这样的(或者至少我以前不明白它是如何工作的)。 Second problem solved!第二个问题解决了!

Here is a code sandbox that shows the solution working, explained in the context of an svg, embedded with the <object> tag: Working Demo这是一个显示解决方案工作的代码沙箱,在 svg 的上下文中进行了解释,嵌入了<object>标签: Working Demo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM