jQuery 3 non presenta questo problema
Una delle modifiche elencate nelle revisioni jQuery 3.0 è:
aggiungi manipolazione classe SVG ( # 2199 , 20aaed3 )
Una soluzione per questo problema sarebbe l'aggiornamento a jQuery 3. Funziona alla grande:
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>
Il problema:
Il motivo per cui le funzioni di manipolazione della classe jQuery non funzionano con gli elementi SVG è perché le versioni jQuery precedenti alla 3.0 utilizzano la className
proprietà per queste funzioni.
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
Questo si comporta come previsto per gli elementi HTML, ma per gli elementi SVG className
è leggermente diverso. Per un elemento SVG, className
non è una stringa, ma un'istanza di SVGAnimatedString
.
Considera il seguente codice:
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 esegui questo codice, vedrai qualcosa di simile al seguente nella tua console di sviluppo.
test div
SVGAnimatedString { baseVal="test svg", animVal="test svg"}
Se dovessimo lanciare SVGAnimatedString
quell'oggetto su una stringa come fa jQuery, avremmo [object SVGAnimatedString]
, che è dove jQuery fallisce.
In che modo il plug-in SVG di jQuery gestisce questo:
Il plug-in SVG di jQuery aggira questo problema rattoppando le relative funzioni per aggiungere il supporto SVG.
function getClassNames(elem) {
return (!$.svg.isSVGElem(elem) ? elem.className :
(elem.className ? elem.className.baseVal : elem.getAttribute('class'))) || '';
}
Questa funzione rileverà se un elemento è un elemento SVG e, se lo è, utilizzerà la baseVal
proprietà SVGAnimatedString
dell'oggetto se disponibile, prima di ricadere sull'attributo class
.
Posizione storica di jQuery sulla questione:
jQuery attualmente elenca questo problema sulla loro pagina Won't Fix . Ecco le parti rilevanti.
Bug SVG / VML o Namespaced Elements
jQuery è principalmente una libreria per il DOM HTML, quindi la maggior parte dei problemi relativi ai documenti SVG / VML o agli elementi con spazio dei nomi non rientrano nell'ambito. Cerchiamo di risolvere i problemi che "sfociano" nei documenti HTML, come eventi che escono da SVG.
Evidentemente jQuery ha considerato il pieno supporto SVG al di fuori dell'ambito del core jQuery e più adatto per i plugin.