O jQuery 3 não tem esse problema
Uma das alterações listadas nas revisões do jQuery 3.0 é:
adicionar manipulação de classe SVG ( # 2199 , 20aaed3 )
Uma solução para esse problema seria atualizar para o jQuery 3. Ele funciona muito bem:
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>
O problema:
A razão pela qual as funções de manipulação da classe jQuery não funcionam com os elementos SVG é porque as versões do jQuery anteriores ao 3.0 usam a className
propriedade para essas funções.
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
Isso se comporta conforme o esperado para elementos HTML, mas para elementos SVG className
é um pouco diferente. Para um elemento SVG, className
não é uma sequência, mas uma instância de SVGAnimatedString
.
Considere o seguinte código:
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>
Se você executar esse código, verá algo como o seguinte no console do desenvolvedor.
test div
SVGAnimatedString { baseVal="test svg", animVal="test svg"}
Se formos converter esse SVGAnimatedString
objeto em uma string como o jQuery, teríamos [object SVGAnimatedString]
, e é aí que o jQuery falha.
Como o plugin SVG jQuery lida com isso:
O plug-in jQuery SVG soluciona esse problema corrigindo as funções relevantes para adicionar suporte ao SVG.
function getClassNames(elem) {
return (!$.svg.isSVGElem(elem) ? elem.className :
(elem.className ? elem.className.baseVal : elem.getAttribute('class'))) || '';
}
Essa função detectará se um elemento é um elemento SVG e, se for, usará a baseVal
propriedade do SVGAnimatedString
objeto, se disponível, antes de recorrer ao class
atributo.
A posição histórica do jQuery sobre o assunto:
No momento, o jQuery lista esse problema na página Won't Fix . Aqui estão as partes relevantes.
Erros SVG / VML ou elementos com espaço para nome
O jQuery é principalmente uma biblioteca para o HTML DOM, portanto, a maioria dos problemas relacionados a documentos SVG / VML ou elementos no espaço para nome estão fora do escopo. Tentamos resolver problemas que "vazam" para documentos HTML, como eventos que surgem do SVG.
Evidentemente, o jQuery considerou o suporte completo ao SVG fora do escopo do núcleo do jQuery e mais adequado para plug-ins.