1. ホーム
  2. jquery

[解決済み] jqueryのappendはsvg要素で動作しない?

2022-04-18 02:07:46

質問

これを想定して。

<html>
<head>
 <script type="text/javascript" src="jquery.js"></script>
 <script type="text/javascript">
 $(document).ready(function(){
  $("svg").append('<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>');
 });
 </script>
</head>
<body>
 <svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
 </svg>
</body>

なぜ何も表示されないのですか?

解決方法は?

にマークアップ文字列を渡すと $ でHTMLとしてパースされます。 innerHTML プロパティで <div> (のような特殊なケースには、他の適切なコンテナ)。 <tr> ). innerHTML はSVGなどの非HTMLコンテンツを解析できませんし、解析できたとしても <circle> はSVG名前空間であるべきだったのです。

innerHTML はSVGElementでは利用できない-HTMLElementのプロパティのみである。また、現在 innerSVG プロパティなど、SVGElementにコンテンツをパースする方法(*)があります。このため、DOMスタイルのメソッドを使用する必要があります。jQueryはSVG要素の作成に必要な名前空間メソッドに簡単にアクセスすることを許しません。本当にjQueryはSVGを使うために全く設計されておらず、多くの操作で失敗する可能性があります。

HTML5 では <svg> がなければ xmlns プレーンなHTMLの内側( text/html ) ドキュメントを将来的に作成します。しかし、これは単なるパーサーハック(**)で、SVGのコンテンツはHTMLElementsではなく、SVG名前空間のSVGElementsのままなので、このままでは innerHTML であっても 外観 は、HTML ドキュメントの一部のようなものです。

ただし、現在のブラウザでは X HTML(正しくは application/xhtml+xml ローカルでのテスト用に拡張子.xhtmlで保存してください) を使用すると、SVGがまったく動作しなくなります。(SVGは正しくXMLベースの規格です。 < 記号をスクリプトブロックの中に入れ(またはCDATAセクションで囲み)、XHTMLの xmlns の宣言があります。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head>
</head><body>
    <svg id="s" xmlns="http://www.w3.org/2000/svg"/>
    <script type="text/javascript">
        function makeSVG(tag, attrs) {
            var el= document.createElementNS('http://www.w3.org/2000/svg', tag);
            for (var k in attrs)
                el.setAttribute(k, attrs[k]);
            return el;
        }

        var circle= makeSVG('circle', {cx: 100, cy: 50, r:40, stroke: 'black', 'stroke-width': 2, fill: 'red'});
        document.getElementById('s').appendChild(circle);
        circle.onmousedown= function() {
            alert('hello');
        };
    </script>
</body></html>

*: さて、DOMレベル3のLSの parseWithContext しかし、ブラウザのサポートは非常に貧弱です。編集から追加:しかし、SVGElementにマークアップを注入することはできませんが、新しいSVGElementをHTMLElementに注入することは可能です。 innerHTML そして、それを目的のターゲットに転送します。しかし、少し遅くなる可能性があります。

<script type="text/javascript"><![CDATA[
    function parseSVG(s) {
        var div= document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
        div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+s+'</svg>';
        var frag= document.createDocumentFragment();
        while (div.firstChild.firstChild)
            frag.appendChild(div.firstChild.firstChild);
        return frag;
    }

    document.getElementById('s').appendChild(parseSVG(
        '<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" onmousedown="alert(\'hello\');"/>'
    ));
]]></script>

**: HTML5の作者はXMLを恐れているようで、XMLベースの機能をHTMLという無骨な混乱に押し込もうとする姿勢が嫌ですね。XHTMLは何年も前にこれらの問題を解決しています。