Ответ 1
Это происходит потому, что спецификация SVG DOM сильно отличается от HTML DOM.
SVG DOM - это другой диалект, и некоторые свойства имеют одинаковые имена, но имеют разные значения. Например, чтобы получить className элемента svg, вы используете:
svg.className.baseVal
Влияющие на это проблемы
className is SVGAnimatedString
height,width, x, y, offsetWidth, offsetHeight are SVGAnimatedLength
Эти анимированные свойства - это структуры, при этом 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.