Dzieje się tak, ponieważ specyfikacja SVG DOM różni się znacznie od HTML DOM.
SVG DOM to inny dialekt, a niektóre właściwości mają te same nazwy, ale oznaczają różne rzeczy. Na przykład, aby uzyskać className elementu SVG, możesz użyć:
svg.className.baseVal
W properites dotknięte przez to są
className is SVGAnimatedString
height,width, x, y, offsetWidth, offsetHeight are SVGAnimatedLength
Te animowane właściwości są kodowanym, z baseVal
posiadających taką samą wartość, którą znaleźć w HTML DOM i animatedVal
trzymając nie jestem pewien co.
W SVG DOM również brakuje niektórych bibliotek właściwości, takich jak innerHTML
.
To łamie jQuery na wiele sposobów, wszystko, co zależy od powyższych właściwości, zawodzi.
Ogólnie SVG DOM i HTML DOM nie mieszają się bardzo dobrze. Pracują razem na tyle, by cię zwabić, a potem wszystko cichnie, a inny anioł traci skrzydła.
pisałem trochę rozszerzenie jQuery, która otacza elementy SVG, aby wyglądały bardziej jak 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);
Tworzy otoki wokół obiektów SVG, który sprawia, że wyglądają jak HTML DOM do jQuery. Używałem go z jQuery-UI do zrzucania elementów SVG.
Brak interoperacyjności DOM między HTML a SVG jest całkowitą katastrofą. Wszystkie słodkie biblioteki narzędziowe napisane dla HTML muszą zostać ponownie utworzone dla SVG.
Hej, Aleksander, dzięki za tę sugestię! Fragment dostał nas dość daleko, ale nie działał w Firefoksie 15 z powodu błędu podniesionego podczas korzystania z prototypowego dziedziczenia bezpośrednio z elementem SVG DOM. Zmodyfikowaliśmy go tak, aby działał w Firefoksie i używa go z powodzeniem. Kod znajduje się tutaj: http://github.com/RedBrainLabs/jquery.wrap-svg –
Po prostu ładowanie skryptu w Safari 8.0 Pojawił się błąd: "SyntaxError: Instrukcje funkcji muszą mieć nazwę." (svg.js, wiersz 1). Umieściłem skrypt w oddzielnym pliku js, svg.js i próbowałem ładować go przed i po pliku jQuery. Ten sam błąd w obu przypadkach. –
To wygląda świetnie - ale jak to ma być użyte? – kris