Ciò accade perché la specifica SVG DOM differisce molto dal DOM HTML.
SVG DOM è un dialetto diverso e alcune proprietà hanno lo stesso nome ma significano cose diverse. Ad esempio, per ottenere il className di un elemento SVG, si utilizza:
svg.className.baseVal
I properites colpiti da questa sta
className is SVGAnimatedString
height,width, x, y, offsetWidth, offsetHeight are SVGAnimatedLength
Queste proprietà animate sono le strutture, con baseVal
tenendo lo stesso valore che aveva trovare in HTML DOM e animatedVal
tenendo non sono sicuro di cosa.
SVG DOM è anche privo di alcune librerie di proprietà, ad esempio innerHTML
.
Ciò interrompe jQuery in molti modi, tutto ciò che dipende dalle proprietà precedenti non riesce.
In generale, SVG DOM e HTML DOM non si combinano molto bene. Lavorano insieme quel tanto che basta per attirarti, e poi le cose scoppiano in silenzio, e un altro angelo perde le ali.
ho scritto un po 'di estensione jQuery che avvolge elementi SVG per farle sembrare più simile a 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);
Si crea un wrapper per oggetti SVG che li fa apparire come HTML DOM a jQuery. L'ho usato con jQuery-UI per rendere i miei elementi SVG trascinabili.
La mancanza di interoperabilità DOM tra HTML e SVG è un disastro totale. Tutte le librerie di utilità dolce scritte per HTML devono essere reinventate per SVG.
Ehi, Aleksander, grazie per questo suggerimento! Lo snippet ci ha portato molto lontano, ma non ha funzionato in Firefox 15 a causa di un errore generato durante l'utilizzo dell'ereditarietà del prototipo direttamente con un elemento SVG DOM. Lo abbiamo modificato per funzionare in Firefox e lo stiamo usando con successo. Il codice è qui: http://github.com/RedBrainLabs/jquery.wrap-svg –
Basta caricare lo script in Safari 8.0 Ho ricevuto un errore: "SyntaxError: le istruzioni della funzione devono avere un nome." (svg.js, riga 1). Ho messo lo script in un file js separato, svg.js, e ho provato a caricarlo prima e dopo il file jQuery. Stesso errore in entrambi i casi. –
Sembra fantastico, ma come deve essere usato? – kris