jQuery 3 n'a pas ce problème
L'une des modifications répertoriées dans les révisions de jQuery 3.0 est:
ajouter la manipulation de classe SVG ( # 2199 , 20aaed3 )
Une solution à ce problème serait de mettre à niveau vers jQuery 3. Cela fonctionne très bien:
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>
Le problème:
La raison pour laquelle les fonctions de manipulation de classe jQuery ne fonctionnent pas avec les éléments SVG est que les versions jQuery antérieures à 3.0 utilisent la className
propriété de ces fonctions.
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
Cela se comporte comme prévu pour les éléments HTML, mais pour les éléments SVG, className
c'est un peu différent. Pour un élément SVG, className
n'est pas une chaîne, mais une instance de SVGAnimatedString
.
Considérez le code suivant:
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>
Si vous exécutez ce code, vous verrez quelque chose comme le suivant dans votre console de développeur.
test div
SVGAnimatedString { baseVal="test svg", animVal="test svg"}
Si nous devions convertir cet SVGAnimatedString
objet en chaîne comme le fait jQuery, nous l'aurions fait [object SVGAnimatedString]
, c'est là que jQuery échoue.
Comment le plugin jQuery SVG gère cela:
Le plugin jQuery SVG contourne cela en corrigeant les fonctions pertinentes pour ajouter le support SVG.
function getClassNames(elem) {
return (!$.svg.isSVGElem(elem) ? elem.className :
(elem.className ? elem.className.baseVal : elem.getAttribute('class'))) || '';
}
Cette fonction détectera si un élément est un élément SVG, et s'il l'est, il utilisera la baseVal
propriété de l' SVGAnimatedString
objet si elle est disponible, avant de retomber sur l' class
attribut.
Position historique de jQuery sur la question:
jQuery répertorie actuellement ce problème sur leur page Won't Fix . Voici les parties pertinentes.
Bogues SVG / VML ou éléments à espace de noms
jQuery est principalement une bibliothèque pour le DOM HTML, donc la plupart des problèmes liés aux documents SVG / VML ou aux éléments à espace de noms sont hors de portée. Nous essayons de résoudre les problèmes qui «traversent» les documents HTML, tels que les événements qui sortent de SVG.
Évidemment, jQuery considérait la prise en charge complète de SVG en dehors de la portée du noyau jQuery, et mieux adaptée aux plugins.