如何在<a> clickable</a>内制作具有悬停效果的SVG图像

时间:2014-06-05 12:27:00

标签: html css svg

想象一下,我们有一个包含SVG图标的锚点,其中包含悬停效果和一些文字。

http://svgtest.tomasreichmann.cz/images/grafika.svg

让我们假设图标是在指向不同网址的各种链接中多次使用。

  • SVG应该在一个单独的文件中,而不是内联
  • 链接不应嵌入SVG文件
  • 悬停效果应该有效
  • JS和noscript后退到PNG是公平的游戏

嵌入SVG的方法

对象:

<a href="http://tomasreichmann.cz/" >
    <object data="http://svgtest.tomasreichmann.cz/images/grafika.svg" type="image/svg+xml">
    </object>
    Link
</a>

图像

<a href="http://tomasreichmann.cz/" >
    <img src="http://svgtest.tomasreichmann.cz/images/grafika.svg" alt="" />
    Link
</a>

演示 http://jsfiddle.net/YZkj9/

这真的不可能实现吗? 这是没有人使用SVG的原因,即使它自IE9以来一直受支持吗?

感谢您的时间和精力,你们真棒!

2 个答案:

答案 0 :(得分:3)

事实上,SVG可以用javascript操纵。问题是,当尝试使用jQuery选择时,SVG对象非常错误,所以你必须至少使用常规的javascript进行选择。

让我们说(就像我的情况一样)你将对象包装在div和href标签中;它会看起来像这样:

<div id="mp3-link">
  <a href="http://your-url.com">
    <object type="image/svg+xml" class="mp3-svg" id="object-svg" data="your-svg-url.com"></object>
  </a>
</div>

对象标签将吐出的代码看起来像这样(在我的例子中,MP3下载链接)。

<div id="mp3-link">
<a href="http://google.com">
<object type="image/svg+xml" class="mp3-svg" id="object-svg">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 612 792" style="enable-background:new 0 0 612 792;" xml:space="preserve">
    <defs>
    <style type="text/css"><![CDATA[
        .fill-blue {
            fill:inherit;
            stroke-width:0;
        }
        .mp3 {
            font-family:'Lato-Bold'; 
            stroke-width:0;
        }
        .stroke-blue {
            fill-opacity:0;
            stroke:inherit;
            stroke-width:inherit;
            stroke-miterlimit:inherit;
        }
        #hover-me:hover {
            stroke:#3c4147;
            fill:#3c4147;
        }
        #hover-me {
            stroke:#227AA5;
            stroke-width:22;
            stroke-miterlimit:10;
            fill:#227AA5;
        }
    ]]></style>
</defs>
<g id="hover-me">
<text transform="matrix(0.7813 0 0 1 216.4761 524.5479)" class="mp3 fill-blue hover-me" style="font-size:193.4593;">MP3</text>
<path class="stroke-blue hover-me" d="M377.1,560.5v79 c0,6.2-5,11.2-11.2,11.2H30.6c-6.2,0-11.2-5-11.2-11.2V153.1c0-6.2,5-11.2,11.2-11.2h235.2c6.2,0,111.3,121.2,111.3,121.2v80.7  M593.7,535.4V373.5c0-11-9-20-20-20H189.2c-11,0-20,9-20,20v161.8c0,11,9,20,20,20h384.6C584.7,555.4,593.7,546.4,593.7,535.4z"/>
<path class="page-flap fill-blue hover-me" d="M272,164.5l46.3,50.4l46.7,52.6v2.4h-93V164.5 M267,131h-18v145.1c0,9.4,7.7,17,17.2,17H388v-34.2   l-52.6-59.3l-53.9-58.7L267,131L267,131z"/>
</g>
</svg>

</object>
</a>
</div>

我们需要做的是选择svg的内部元素(在这种情况下,&#34;#hover-me&#34;)并附加一个javascript函数:

//this is important, as the svg tends to load a little later than the rest of the elements
window.onload=function() {

    // Get the Object by ID
    var theObject = document.getElementById("object-svg");
    // Get the SVG document inside the Object tag
    var svgDoc = theObject.contentDocument;
    // Get one of the SVG items by ID;
    var svgItem = svgDoc.getElementById("hover-me");

    //our javascript selector
    svgItem.addEventListener('click', function() { 
    //here, I'm using jQuery to select the parent and get the href. This is so you can see that jQuery is possible, just not for the selection portion of the code
    var svgHref = $(theObject).parent().attr("href");
    //now, we navigate to the external href. I chose to open in new window.
    var win = window.open(svgHref, '_blank');
    win.focus();
  });
}; //window.onload

现在,我们已经创建了一个函数,它将使用javascript找到包装对象的链接,然后它将使用jQuery将用户导航到该链接。

我试图附上一个jsfiddle,但是jsfiddle不允许你导入一个对象,所以你必须在实际的网页上试用这个代码

More info in selecting SVG elements with javascript

修改

在进一步研究之后,我想出了一种更优化的方法:

通过使用javascript实际更改悬停的样式,我们可以允许svg图像像普通链接一样操作(右键单击选项,下角的状态窗口等)

所以在这种情况下使用相同的svg标记并在链接中添加一个类

<div id="mp3-link">
  //we'll call our link "a-svg"
  <a href="http://your-url.com" class="a-svg">
<object type="image/svg+xml" class="mp3-svg" id="object-svg" data="your-svg-url.com"></object>
  </a>
</div>

我们可以使用此代码在链接悬停时更改svg的样式:

window.onload=function() {
//get our link
var theA = document.getElementsByClassName("a-svg");
//loop through all of these (jQuery does this by default, but we're forced to use regular javascript
for(var i=0;i<theA.length;i++){
    //when the user hovers over the link...
    theA[i].addEventListener('mouseover', function() { 
    var thisObject = this.getElementsByClassName('mp3-svg')[0];
    var svgDoc = thisObject.contentDocument;
    // Get one of the SVG items by ID;
    var svgItem = svgDoc.getElementById("hover-me");
    //change the attributes of the svg
    svgItem.setAttribute("fill", "#3c4147");
    svgItem.setAttribute("stroke", "#3c4147");
});
//now revert the changes when the mouse leaves
theA[i].addEventListener('mouseleave', function() { 
    var thisObject = this.getElementsByClassName('mp3-svg')[0];
    var svgDoc = thisObject.contentDocument;
    // Get one of the SVG items by ID;
    var svgItem = svgDoc.getElementById("hover-me");
    svgItem.setAttribute("fill", "#227aa5");
    svgItem.setAttribute("stroke", "#227aa5");
});
}   
};

最后,为了使链接位于svg之上,我们需要一点点css

.a-svg:after {
  top:0;
  bottom:0;
  left:0;
  right:0;
  position:absolute;
  content"";
}
#mp3-link {
  position:relative;
  height:140px;
  width:140px;
}

现在我们有一个功能齐全的链接,为我们的svg图像提供悬停功能。

答案 1 :(得分:2)

由于您发现图片不支持互动,因此对象不支持用作链接。如果它们是对象,您可以深入了解图像,并使用DOM或...

修改链接属性

使用两张图片,一张在另一张图片的上方。顶部的图像是您现在拥有的图像,而底部的图像将是悬停图像的静态版本,即编辑您现在拥有的图像并更改填充,使其看起来像悬停版本并将其另存为单独的文件。

现在,将图像置于顶部,在悬停时将其不透明度转换为0。您希望将图像置于绝对位置,以便它们彼此叠加。像这样......

<a href="http://tomasreichmann.cz/" >
    <img src="http://svgtest.tomasreichmann.cz/images/grafika-hover.svg" alt="" />
    <img class="top" src="http://svgtest.tomasreichmann.cz/images/grafika.svg" alt="" />
    Link
</a>

img {
  position:absolute;
  left:0;
  -webkit-transition: opacity 0.3s; 
  -moz-transition: opacity 0.3s; 
  -ms-transition: opacity 0.3s; 
  -o-transition: opacity 0.3s; 
  transition: opacity 0.3s;
}

img.top:hover {
  opacity:0;
}