jQuery 3 không có vấn đề này
Một trong những thay đổi được liệt kê trên các bản sửa đổi jQuery 3.0 là:
thêm thao tác lớp SVG ( # 2199 , 20aaed3 )
Một giải pháp cho vấn đề này là nâng cấp lên jQuery 3. Nó hoạt động rất tốt:
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>
Vấn đề:
Lý do các hàm thao tác lớp jQuery không hoạt động với các phần tử SVG là do các phiên bản jQuery trước 3.0 sử dụng thuộc className
tính cho các hàm này.
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
Điều này hoạt động như mong đợi đối với các phần tử HTML, nhưng đối với các phần tử SVG className
thì hơi khác một chút. Đối với một phần tử SVG, className
không phải là một chuỗi, mà là một thể hiện của SVGAnimatedString
.
Hãy xem xét các mã sau đây:
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>
Nếu bạn chạy mã này, bạn sẽ thấy một cái gì đó như sau trong bảng điều khiển dành cho nhà phát triển của bạn.
test div
SVGAnimatedString { baseVal="test svg", animVal="test svg"}
Nếu chúng ta truyền SVGAnimatedString
đối tượng đó thành một chuỗi như jQuery, chúng ta sẽ có [object SVGAnimatedString]
, đó là nơi jQuery thất bại.
Cách plugin jQuery SVG xử lý việc này:
Plugin jQuery SVG hoạt động xung quanh điều này bằng cách vá các chức năng có liên quan để thêm hỗ trợ SVG.
function getClassNames(elem) {
return (!$.svg.isSVGElem(elem) ? elem.className :
(elem.className ? elem.className.baseVal : elem.getAttribute('class'))) || '';
}
Hàm này sẽ phát hiện xem một phần tử có phải là phần tử SVG hay không và nếu có thì nó sẽ sử dụng thuộc baseVal
tính của SVGAnimatedString
đối tượng nếu có, trước khi quay lại class
thuộc tính.
Lập trường lịch sử của jQuery về vấn đề này:
jQuery hiện liệt kê vấn đề này trên trang W't Fix của họ . Đây là những phần có liên quan.
Lỗi SVG / VML hoặc không gian tên
jQuery chủ yếu là một thư viện cho HTML DOM, vì vậy hầu hết các vấn đề liên quan đến tài liệu SVG / VML hoặc các phần tử được đặt tên đều nằm ngoài phạm vi. Chúng tôi cố gắng giải quyết các vấn đề "chảy qua" cho các tài liệu HTML, chẳng hạn như các sự kiện bong bóng ra khỏi SVG.
Rõ ràng jQuery đã xem xét hỗ trợ SVG đầy đủ bên ngoài phạm vi của lõi jQuery và phù hợp hơn với các plugin.