jQuery 3 не имеет этой проблемы
Одно из изменений, перечисленных на ревизии jQuery 3.0:
добавить манипулирование классом SVG (#2199, 20aaed3)
Одним из решений этой проблемы было бы перейти на jQuery 3. Он отлично работает:
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, заключается в том, что версии jQuery до 3.0 используют 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 считал, что полная поддержка SVG выходит за рамки ядра jQuery и лучше подходит для плагинов.
person
Alexander O'Mara
schedule
08.04.2015