这是我提出的一段方便的代码的自我问答。
目前,还没有一种简单的方法来嵌入SVG图像,然后通过CSS访问SVG元素。使用JS SVG框架有多种方法,但如果您所做的只是制作一个带有翻转状态的简单图标,那么这些方法就过于复杂了。
所以这就是我想到的,我认为这是迄今为止在网站上使用SVG文件的最简单的方法。它的概念来自于早期的文本到图像替换方法,但据我所知,还从未用于svg。
问题是这样的:
我如何在CSS中嵌入SVG并改变其颜色而不使用JS-SVG框架?
这是我提出的一段方便的代码的自我问答。
目前,还没有一种简单的方法来嵌入SVG图像,然后通过CSS访问SVG元素。使用JS SVG框架有多种方法,但如果您所做的只是制作一个带有翻转状态的简单图标,那么这些方法就过于复杂了。
所以这就是我想到的,我认为这是迄今为止在网站上使用SVG文件的最简单的方法。它的概念来自于早期的文本到图像替换方法,但据我所知,还从未用于svg。
问题是这样的:
我如何在CSS中嵌入SVG并改变其颜色而不使用JS-SVG框架?
当前回答
如果您希望jQuery处理DOM中的所有svg元素,并且DOM的大小合理,那么所选的解决方案是很好的。但是如果您的DOM很大,并且您决定动态加载DOM的一部分,那么为了更新svg元素而重新扫描整个DOM确实没有意义。相反,使用jQuery插件来做到这一点:
/**
* A jQuery plugin that loads an svg file and replaces the jQuery object with its contents.
*
* The path to the svg file is specified in the src attribute (which normally does not exist for an svg element).
*
* The width, height and class attributes in the loaded svg will be replaced by those that exist in the jQuery object's
* underlying html. Note: All other attributes in the original element are lost including the style attribute. Place
* any styles in a style class instead.
*/
(function ($) {
$.fn.svgLoader = function () {
var src = $(this).attr("src");
var width = this.attr("width");
var height = this.attr("height");
var cls = this.attr("class");
var ctx = $(this);
// Get the svg file and replace the <svg> element.
$.ajax({
url: src,
cache: false
}).done(function (html) {
let svg = $(html);
svg.attr("width", width);
svg.attr("height", height);
svg.attr("class", cls);
var newHtml = $('<a></a>').append(svg.clone()).html();
ctx.replaceWith(newHtml);
});
return this;
};
}(jQuery));
在html中,按如下方式指定svg元素:
<svg src="images/someSvgFile.svg" height="45" width="45" class="mySVGClass"/>
并应用插件:
$(".mySVGClass").svgLoader();
其他回答
首先,在HTML中使用IMG标记来嵌入SVG图形。我使用Adobe Illustrator来制作图形。
<img id="facebook-logo" class="svg social-link" src="/images/logo-facebook.svg"/>
这就像你如何嵌入一个普通的图像。注意,您需要将IMG设置为svg类。“社会链接”类只是举个例子。ID不是必需的,但很有用。
然后使用jQuery代码(在单独的文件中或内联在HEAD中)。
/**
* Replace all SVG images with inline SVG
*/
jQuery('img.svg').each(function(){
var $img = jQuery(this);
var imgID = $img.attr('id');
var imgClass = $img.attr('class');
var imgURL = $img.attr('src');
jQuery.get(imgURL, function(data) {
// Get the SVG tag, ignore the rest
var $svg = jQuery(data).find('svg');
// Add replaced image's ID to the new SVG
if(typeof imgID !== 'undefined') {
$svg = $svg.attr('id', imgID);
}
// Add replaced image's classes to the new SVG
if(typeof imgClass !== 'undefined') {
$svg = $svg.attr('class', imgClass+' replaced-svg');
}
// Remove any invalid XML tags as per http://validator.w3.org
$svg = $svg.removeAttr('xmlns:a');
// Replace image with new SVG
$img.replaceWith($svg);
}, 'xml');
});
上面的代码所做的是查找所有带有“svg”类的IMG,并将其替换为链接文件中的内联svg。最大的优势是它允许你现在使用CSS来改变SVG的颜色,如下所示:
svg:hover path {
fill: red;
}
我编写的jQuery代码还跨原始图像ID和类进行移植。所以这个CSS也可以工作:
#facebook-logo:hover path {
fill: red;
}
Or:
.social-link:hover path {
fill: red;
}
你可以在这里看到一个它工作的例子: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html
我们有一个更复杂的版本,包括缓存: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90
如果可以在页面中包含文件(PHP include或通过您选择的CMS包含),则可以添加SVG代码并将其包含到页面中。这与将SVG源粘贴到页面相同,但使页面标记更清晰。
这样做的好处是,您可以通过CSS将SVG的某些部分用于悬停—不需要javascript。
http://codepen.io/chriscoyier/pen/evcBu
你只需要使用这样的CSS规则:
#pathidorclass:hover { fill: #303 !important; }
注意!important位是覆盖填充颜色所必需的。
我用AngularJS写了一个指令来解决这个问题。它可在这里- ngReusableSvg。
它在SVG元素被呈现后替换它,并将其放置在div元素中,使其CSS易于更改。这有助于在不同的地方使用相同的SVG文件,使用不同的大小/颜色。
用法很简单:
<object oa-reusable-svg
data="my_icon.svg"
type="image/svg+xml"
class="svg-class"
height="30" // given to prevent UI glitches at switch time
width="30">
</object>
之后,你就可以轻松地拥有:
.svg-class svg {
fill: red; // whichever color you want
}
因为SVG基本上是代码,所以您只需要内容。我使用PHP来获取内容,但您可以使用任何您想要的内容。
<?php
$content = file_get_contents($pathToSVG);
?>
然后,我已经打印内容“是”在一个div容器
<div class="fill-class"><?php echo $content;?></div>
最后将规则设置为CSS上的容器的SVG子元素
.fill-class > svg {
fill: orange;
}
我用SVG材质图标得到了这个结果:
Firefox 59.0.2(64位)Linux
谷歌Chrome66.0.3359.181 (Build official)(64位)Linux
Opera 53.0.2907.37 Linux
下面是knockout.js基于公认答案的一个版本:
重要:它实际上也需要jQuery来替换,但我认为它可能对一些人有用。
ko.bindingHandlers.svgConvert =
{
'init': function ()
{
return { 'controlsDescendantBindings': true };
},
'update': function (element, valueAccessor, allBindings, viewModel, bindingContext)
{
var $img = $(element);
var imgID = $img.attr('id');
var imgClass = $img.attr('class');
var imgURL = $img.attr('src');
$.get(imgURL, function (data)
{
// Get the SVG tag, ignore the rest
var $svg = $(data).find('svg');
// Add replaced image's ID to the new SVG
if (typeof imgID !== 'undefined')
{
$svg = $svg.attr('id', imgID);
}
// Add replaced image's classes to the new SVG
if (typeof imgClass !== 'undefined')
{
$svg = $svg.attr('class', imgClass + ' replaced-svg');
}
// Remove any invalid XML tags as per http://validator.w3.org
$svg = $svg.removeAttr('xmlns:a');
// Replace image with new SVG
$img.replaceWith($svg);
}, 'xml');
}
};
然后对img标签应用data-bind="svgConvert: true"。
这个解决方案完全用SVG替换了img标记,任何附加的绑定都不会受到尊重。