使一个html svg对象也是一个可点击的链接

时间:2012-07-07 10:05:16

标签: html object svg anchor

我的HTML页面中有一个SVG对象并将其包装在一个锚点中,因此当单击svg图像时,它会将用户带到锚点链接。

<a href="http://www.google.com/">
    <object data="mysvg.svg" type="image/svg+xml">
        <span>Your browser doesn't support SVG images</span>
    </object>
</a>

当我使用此代码块时,单击svg对象不会将我带到谷歌。在IE8中&lt;范围文本是可点击的。

我不想修改我的svg图像以包含标签。

我的问题是,如何才能使svg图像可点击?

13 个答案:

答案 0 :(得分:192)

实际上,解决这个问题的最佳方法是...&lt; object&gt;标签,使用:

pointer-events: none;

注意:安装了广告拦截器插件的用户在悬停时会在右上角看到一个类似于标签的[Block](与flash横幅广告相同)。通过设置此css,它也会消失。

http://jsfiddle.net/energee/UL9k9/

答案 1 :(得分:32)

我遇到了同样的问题并设法解决了这个问题:

将元素设置为block或inline-block

来包装对象
<a>
    <span>
        <object></object>
    </span>
</a>

添加到<a>代码:

display: inline-block;
position: relative; 
z-index: 1;

<span>代码:

display: inline-block;

<object>代码:

position: relative; 
z-index: -1

请在此处查看示例:http://dabblet.com/gist/d6ebc6c14bd68a4b06a6

通过评论20 https://bugzilla.mozilla.org/show_bug.cgi?id=294932

找到

答案 2 :(得分:30)

我想对此表示赞赏,但我在这里找到了解决方案:

https://teamtreehouse.com/forum/how-do-you-make-a-svg-clickable

将以下内容添加到锚点的css中:

a.svg {
  position: relative;
  display: inline-block; 
}
a.svg:after {
  content: ""; 
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left:0;
}


<a href="#" class="svg">
  <object data="random.svg" type="image/svg+xml">
    <img src="random.jpg" />
  </object>
</a>

链接适用于svg和后备。

答案 3 :(得分:20)

您也可以在SVG的底部(在结束</svg>标记之前)粘贴这样的内容:

<a xmlns="http://www.w3.org/2000/svg" id="anchor" xlink:href="/" xmlns:xlink="http://www.w3.org/1999/xlink" target="_top">
    <rect x="0" y="0" width="100%" height="100%" fill-opacity="0"/>
</a>

然后修改链接以适应。我已经使用了100%的宽度和高度来覆盖它所处的SVG。这项技术归功于Clearleft.com的智能人员 - 这是我第一次看到它使用的地方。

答案 4 :(得分:19)

最简单的方法是不使用&lt; object&gt;。而是使用&lt; img&gt;标签和锚应该可以正常工作。

答案 5 :(得分:18)

理查德解决方案的简化。至少在Firefox,Safari和Opera中起作用:

<a href="..." style="display: block;">
    <object data="..." style="pointer-events: none;" />
</a>

有关其他解决方案,请参阅http://www.noupe.com/tutorial/svg-clickable-71346.html

答案 6 :(得分:9)

要在所有浏览器中完成此操作,您需要结合使用@energee,@ Richard和@Feuermurmel方法。

<a href="" style="display: block; z-index: 1;">
    <object data="" style="z-index: -1; pointer-events: none;" />
</a>

添加:

  • pointer-events: none;可在Firefox中使用。
  • display: block;让它在Chrome和Safari中运行。
  • z-index: 1; z-index: -1;也可以在IE中使用。

答案 7 :(得分:3)

我通过编辑svg文件解决了这个问题。

我将整个svg图形的xml包装在具有click事件的组标记中,如下所示:

<svg .....>
<g id="thefix" onclick="window.top.location.href='http://www.google.com/';">
 <!-- ... your graphics ... -->
</g>
</svg>

解决方案适用于支持对象svg脚本的所有浏览器。 (默认情况下,对象元素中的img标记适用于不支持svg的浏览器,并且您将涵盖各种浏览器)

答案 8 :(得分:2)

我试过这个干净简单的方法,似乎适用于所有浏览器。 在svg文件中:

&#13;
&#13;
<svg>
<a id="anchor" xlink:href="http://www.google.com" target="_top">
  
<!--your graphic-->
  
</a>
</svg>
  
&#13;
&#13;
&#13;

答案 9 :(得分:1)

我只是简单地使用

Multi threaded access requested by thread Thread[pool-5-thread-1,5,main] but is not allowed for language(s) js.

除了我试图应用 :hover 状态外,它工作正常。把我带到这里的是当我使用

        <a href="#">
            <img src="../../assets/images/logo.svg" alt="">
        </a>

我丢失了链接并在 DevTools 中注意到链接仍然出现在 SVG 周围,但 :hover 状态有效。利用 energee 的优雅回答,我的链接有效,但当然我失去了:悬停。因此,对于将 :hover 更改应用到 SVG 而言,对象标记似乎不是一个很好的解决方案。

我很好奇,你为什么不使用 img 标签来显示没有任何特殊添加的 SVG,比如 :hover?使用 img 标签也适用于 a 标签。

答案 10 :(得分:0)

请勿使用<object>。这是一个适用于<a><svg>标签的解决方案:

<a href="<your-link>" class="mr-5 p-1 border-2 border-transparent text-gray-400 rounded-full hover:text-white focus:outline-none focus:text-white focus:bg-red-700 transition duration-150 ease-in-out" aria-label="Notifications">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="30" 
    height="30"><path class="heroicon-ui" fill="#fff" d="M17 16a3 3 0 1 1-2.83 
    2H9.83a3 3 0 1 1-5.62-.1A3 3 0 0 1 5 12V4H3a1 1 0 1 1 0-2h3a1 1 0 0 1 1 
    1v1h14a1 1 0 0 1 .9 1.45l-4 8a1 1 0 0 1-.9.55H5a1 1 0 0 0 0 2h12zM7 12h9.38l3- 
   6H7v6zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm10 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
    </svg>
</a>

答案 11 :(得分:0)

这已经很晚了,但我想知道为什么 energee's solution 有效:具体来说,<object> 元素如何影响其父元素。

tl;dr 您不能点击包含 <object> 元素的锚点,因为点击事件被 <object> 元素内部的任何内容捕获,然后不会冒泡退出。

jsfiddle


扩展原始问题中描述的症状:锚元素内的 <object> 元素不仅会导致锚点变得不可点击,而且 <object> 元素似乎是 < 的子元素strong>任何元素都会导致 clickmousedownmouseup 事件(也可能是触摸事件)不会在父元素上触发,(当您在 <object> 的边界矩形内点击。)

<span>
    <object type="image/svg+xml" data="https://icons.getbootstrap.com/icons/three-dots.svg">
    </object>
</span>
document
    .querySelector('span')
    .addEventListener('click', console.log) // will not fire

现在,<object> 元素的行为有点“像”<iframe>,因为它们将建立新的浏览上下文,包括当内容是 <svg> 文档时。 在 JavaScript 中,这通过 HTMLObjectElement.contentDocumentHTMLObjectElement.contentWindow 属性的存在体现出来。

这意味着如果您向 <svg> 内的 <object> 元素添加事件侦听器:

document
    .querySelector('object')
    .contentDocument  // returns null if cross-origin: the same-origin policy
    .querySelector('svg')
    .addEventListener('click', console.log)

然后单击图像,您将看到正在触发的事件。

那么 pointer-events: none; 解决方案为何有效:

  • 如果没有这种样式,任何被认为是“交互式”的 MouseEvent(例如 clickmousedown,但不是 mouseenter)都会被发送到嵌套的<object> 内的浏览上下文,永远不会冒泡出来。

  • 使用这种样式,MouseEvent 不会首先发送到 <object>,然后 <object> 的父元素将像往常一样接收事件.

这也应该解释了 z-index 解决方案:只要您可以防止将 click 事件发送到嵌套文档,点击应该会按预期工作。

(在我的测试中,只要父元素不是 z-index 并且 inline 被定位并且具有负 <object>z-index 解决方案将起作用)< /p>

(或者,您可以找到一种方法来备份事件):

let objectElem = document.querySelector('object')
let svgElemt = objectElem.contentDocument.querySelector('svg')

svgElem.addEventListener('click', () => {
    window.postMessage('Take this click event please.')
    // window being the outermost window
})

window.addEventListener('message', console.log)

答案 12 :(得分:-4)

使用javascript并为onClick - 元素添加object - 属性:

<object data="mysvg.svg" type="image/svg+xml" onClick="window.location.href='http://google.at';">
    <span>Your browser doesn't support SVG images</span>
</object>