jQuery 3没有这个问题
jQuery 3.0修订版中列出的更改之一是:
添加SVG类的操作(#2199,20aaed3)
解决此问题的一种方法是升级到jQuery3。它的效果很好:
var flip = true;
setInterval(function() {
// Could use toggleClass, but demonstrating addClass.
if (flip) {
$('svg circle').addClass('green');
}
else {
$('svg circle').removeClass('green');
}
flip = !flip;
}, 1000);
svg circle {
fill: red;
stroke: black;
stroke-width: 5;
}
svg circle.green {
fill: green;
}
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<svg>
<circle cx="50" cy="50" r="25" />
</svg>
问题:
jQuery类操作函数不能与SVG元素一起使用的原因是因为3.0之前的jQuery版本将className
这些属性用于这些函数。
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
对于HTML元素,这的行为符合预期,但对于SVG元素,className
则有所不同。对于SVG元素,className
不是字符串,而是的实例SVGAnimatedString
。
考虑以下代码:
var test_div = document.getElementById('test-div');
var test_svg = document.getElementById('test-svg');
console.log(test_div.className);
console.log(test_svg.className);
#test-div {
width: 200px;
height: 50px;
background: blue;
}
<div class="test div" id="test-div"></div>
<svg width="200" height="50" viewBox="0 0 200 50">
<rect width="200" height="50" fill="green" class="test svg" id="test-svg" />
</svg>
如果运行此代码,则在开发人员控制台中将看到类似以下的内容。
test div
SVGAnimatedString { baseVal="test svg", animVal="test svg"}
如果SVGAnimatedString
像jQuery一样将对象转换为字符串,则将具有[object SVGAnimatedString]
,这是jQuery失败的地方。
jQuery SVG插件如何处理此问题:
jQuery SVG插件通过修补相关功能以添加SVG支持来解决此问题。
function getClassNames(elem) {
return (!$.svg.isSVGElem(elem) ? elem.className :
(elem.className ? elem.className.baseVal : elem.getAttribute('class'))) || '';
}
此函数将检测元素是否为SVG元素,如果可用,则将使用对象的baseVal
属性(SVGAnimatedString
如果可用),然后返回class
属性。
jQuery在此问题上的历史立场:
jQuery当前在“无法修复”页面上列出了此问题。这是相关的部分。
SVG / VML或命名空间元素错误
jQuery主要是HTML DOM的库,因此大多数与SVG / VML文档或命名空间元素有关的问题不在范围之内。我们确实试图解决“渗入” HTML文档的问题,例如从SVG冒出来的事件。
显然,jQuery考虑了在jQuery核心范围之外的完整SVG支持,并且更适合于插件。