私はインラインSVGとJavaScriptアニメーションを含むHTML5ドキュメントで作業してきました。
ユーザーがどこかをクリックするとボックスがポップアップし、ユーザーがボックス以外の場所をクリックするとボックスが消えるようにしたいのですが。つまり、機能する$(window).click()
を使用できません。
SVGにクラス名を付けて$(".svgclassname").click()
を使用することでSVGを選択しようとしましたが、これは機能しないようです。 $("#svgname").click()
を使用して個別に選択することもできません。
何が問題ですか?
($(".eyesvg")
を$(window)
に置き換えると、ユーザーがウィンドウのどこかをクリックすると、カーソルの近くに青いボックスが表示されます。
これは、SVG DOM仕様がHTML DOMと大きく異なるためです。
SVG DOMは異なる方言であり、一部のプロパティは同じ名前を持っていますが、意味が異なります。たとえば、svg要素のclassNameを取得するには、次を使用します。
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はあまりうまく混合しません。彼らはあなたを誘惑するのにちょうど十分に協力し、それから物事は静かに壊れ、そして別の天使は翼を失います。
SVG要素をラップしてHTML DOMのように見えるようにする小さなjQuery拡張機能を書きました
(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オブジェクトのラッパーを作成し、それらをjQueryに対してHTML DOMのように見せます。私はそれをjQuery-UIで使用して、SVG要素をドロップ可能にしました。
HTMLとSVG間のDOM相互運用性の欠如は、完全に悲惨です。 HTML用に作成されたすべてのスイートユーティリティライブラリは、SVG用に再発明する必要があります。
時々私はそれを得られない...しかし実際にはそれはクラスセレクターで動作しません。 ID $( "#mysvg")または要素$( "svg")を使用すると、機能します!奇妙な..。
そして、ヘッダーから本文にsvg要素の後のonClickスクリプトを移動したときにのみ機能します。 jqueryは、バインディングの前に要素が宣言されている場合にのみ、onclickをバインドできます。
あなたはチャームのように jquery-svg プラグインを使用できます:
<script>
//get svg object, like a jquery object
var svg = $("#cars").getSVG();
//use jquery functions to do some thing
svg.find("g path:first-child()").attr('fill', color);
</script>