想象一下,我们有一个包含带有悬停效果和一些文本的SVG图标的锚点。
http://svgtest.tomasreichmann.cz/images/grafika.svg
让我们假设图标是指向不同URL的各种链接中多次使用的图标。
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以来一直受支持吗?
谢谢你的时间和精力,你们真棒!
Imagine we have an anchor containing an SVG icon with a hover effect and some text.
http://svgtest.tomasreichmann.cz/images/grafika.svg
Let's assume the icon is ment to be used multiple times in various links pointing to different URLs.
the SVG should be in a separate file not inline the link shouldn't be embeded inside the SVG file the hover effect should work JS and noscript fallback to PNG is fair gameWays to embed SVG
object:
<a href="http://tomasreichmann.cz/" > <object data="http://svgtest.tomasreichmann.cz/images/grafika.svg" type="image/svg+xml"> </object> Link </a>image
<a href="http://tomasreichmann.cz/" > <img src="http://svgtest.tomasreichmann.cz/images/grafika.svg" alt="" /> Link </a>Demo http://jsfiddle.net/YZkj9/
Is this really impossible to achieve? Is this the reason nobody uses SVGs even though it's supported since IE9?
Thank you for your time and effort, you guys are great!
最满意答案
事实上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的内部元素(在本例中为“#hover-me”)并附加一个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不允许你导入一个对象,所以你必须在实际的网页上尝试这个代码
有关使用javascript选择SVG元素的更多信息
编辑
在进一步研究之后,我想出了一种更优化的方法:
通过使用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图像的悬停功能。
SVG's can in fact be manipulated with javascript. The catch, is that SVG objects are very buggy when attempting to be selected with jQuery, so you have to use regular javascript in making your selections at least.
Let's say (like in my case) you wrap your object in a div and an href tag; it's going to look something like this:
<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>And the code that the object tag is going to spit out is going to look something like this (in my case, an MP3 downloads link).
<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>What we need to do, is select an inner element of the svg (in this case, "#hover-me") and attach a javascript function to it:
//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.onloadSo now, we've created a function that will find the link that wraps the object using javascript, and then it will navigate the user to that link using jQuery.
I tried to attach a jsfiddle, but jsfiddle's don't allow you to import an object so you'll have to try this code out on an actual web page
More info in selecting SVG elements with javascript
Edit
After looking into this further, I came up with an even more optimized way to do this:
By using javascript to actually change the styling of the hover, we can then allow the svg image to operate like a normal link (right click options, status window in the lower corner, etc)
So in this case using the same svg markup and adding a class to our link
<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>We can use this code to change the styling of the svg when the link is hovered:
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"); }); } };Lastly, we'll need a little css in order to make it so that the link is on top of the svg
.a-svg:after { top:0; bottom:0; left:0; right:0; position:absolute; content""; } #mp3-link { position:relative; height:140px; width:140px; }Now we have a fully functional link with a hover capability for our svg image.
更多推荐
发布评论