Это происходит потому, что спецификация SVG DOM сильно отличается от HTML DOM.
SVG DOM - это другой диалект, и некоторые свойства имеют одинаковые имена, но означают разные вещи. Например, чтобы получить className элемента svg, вы используете:
svg.className.baseVal
Это затрагивает следующие свойства:
className is SVGAnimatedString
height,width, x, y, offsetWidth, offsetHeight are SVGAnimatedLength
Эти свойства Animated являются структурами, где baseVal
содержит то же значение, что и в HTML DOM, а animatedVal
- я не уверен, что именно.
В SVG DOM также отсутствуют некоторые библиотеки свойств, от которых зависят, например, innerHTML
.
Это ломает jQuery разными способами, все, что зависит от вышеуказанных свойств, терпит неудачу.
В общем, SVG DOM и HTML DOM не очень хорошо сочетаются. Они работают вместе ровно настолько, чтобы заманить вас, а затем все тихо ломается, и другой ангел теряет свои крылья.
Я написал небольшое расширение jQuery, которое обертывает элементы SVG, чтобы они больше походили на HTML DOM.
(function (jQuery){
function svgWrapper(el) {
this._svgEl = el;
this.__proto__ = el;
Object.defineProperty(this, "className", {
get: function(){ return this._svgEl.className.baseVal; },
set: function(value){ this._svgEl.className.baseVal = value; }
});
Object.defineProperty(this, "width", {
get: function(){ return this._svgEl.width.baseVal.value; },
set: function(value){ this._svgEl.width.baseVal.value = value; }
});
Object.defineProperty(this, "height", {
get: function(){ return this._svgEl.height.baseVal.value; },
set: function(value){ this._svgEl.height.baseVal.value = value; }
});
Object.defineProperty(this, "x", {
get: function(){ return this._svgEl.x.baseVal.value; },
set: function(value){ this._svgEl.x.baseVal.value = value; }
});
Object.defineProperty(this, "y", {
get: function(){ return this._svgEl.y.baseVal.value; },
set: function(value){ this._svgEl.y.baseVal.value = value; }
});
Object.defineProperty(this, "offsetWidth", {
get: function(){ return this._svgEl.width.baseVal.value; },
set: function(value){ this._svgEl.width.baseVal.value = value; }
});
Object.defineProperty(this, "offsetHeight", {
get: function(){ return this._svgEl.height.baseVal.value; },
set: function(value){ this._svgEl.height.baseVal.value = value; }
});
};
jQuery.fn.wrapSvg = function() {
return this.map(function(i, el) {
if (el.namespaceURI == "http://www.w3.org/2000/svg" && !('_svgEl' in el))
return new svgWrapper(el);
else
return el;
});
};
})(window.jQuery);
Он создает оболочку вокруг объектов SVG, которая делает их похожими на HTML DOM для jQuery. Я использовал его с jQuery-UI, чтобы мои элементы SVG можно было удалять.
Отсутствие совместимости DOM между HTML и SVG - полная катастрофа. Все замечательные служебные библиотеки, написанные для HTML, нужно заново изобрести для SVG.
person
Aleksandar Totic
schedule
22.04.2011