1

何時間もかけて取り組んできた特定の Javascript の質問について助けが必要です。私はJavascriptも初めてで、.NETのバックグラウンドがあります。

私のアプリケーションは、ウィジェットを操作するためのインライン JS 関数 (回転など) を含む個別の SVG ファイルにコード化されたウィジェットで構成されています。これらの SVG ウィジェットをライブラリ ポップアップからメイン ページにドラッグ アンド ドロップしたいと考えています。エンド ユーザーが必要に応じてウィジェット ファイルを追加または削除できるように、ウィジェットを個別のファイルに配置したいと考えています。

SVG ウィジェットは、メイン ページの HTML にオブジェクトとして動的に追加されます。表示するオブジェクトを取得し、SVG で Javascript を操作できます。<g>また、ページ上のウィジェットを一意に識別できるように、SVG をラップするSVG タグの ID を動的に変更します。

HTML5 のドラッグ アンド ドロップ機能を使用したいのですが、dragstart イベント ハンドラに渡されるイベント オブジェクトから SVG ID 名を抽出する方法がわかりません (そのため、オブジェクト ID をデータ転送オブジェクトに保存できます)。後で使用します)。オブジェクト タグにイベントを添付できないことはわかっているので<g>、SVG のタグで ID を使用し、svg オブジェクトをドラッグするときに dragstart イベントを呼び出すことができます。興味深いことに、SVG を動的に追加しない場合、<g>ID を 抽出できますが、動的event.currentTarget.parentWindow.gID.idに追加すると、gID はイベント オブジェクトで null になります。

さらに奇妙なのは、SVG<g>タグの ID を変更した後にアラートを追加すると、イベント オブジェクトから ID を取得できることです。したがって、何らかのタイミングの問題があるに違いありませんが、スクリプトを機能させるアラートは SVG の ID を変更する<g>であるため、その理由はわかりません。また、プロパティを設定する前に SVG が適切に読み込まれるように、SVG で load イベントを使用します。

コード:

    var svgDialObj
    var svgDialDoc
    var svgDialWin
    window.onload = function () {               // Startup function after DOM is loaded 
            var object2 = document.createElement("object");
            object2.type = "image/svg+xml";
            object2.data = "dial.svg"
            object2.className = "widget"
            object2.id = "svgDial1";
            object2.draggable = "true"
            document.getElementById('container').appendChild(object2);
            svgDialObj = document.getElementById("svgDial1");
            svgDialObj.addEventListener("load", function () { // access properties once the file is loaded
                svgDialDoc = svgDialObj.contentDocument;
                var oldDialID = svgDialDoc.getElementById("svgDial");
                alert(oldDialID.id);    // EVENT OBJECT ONLY WORKS IF THIS ALERT IS INSERTED HERE
                oldDialID.setAttribute("id", "svgDial1");
                svgDialWin = svgDialDoc.defaultView;
                svgDialDoc.addEventListener('dragstart', drag_start, false);
            }, false);
        }

    function drag_start(event) {
        alert(event.currentTarget.parentWindow.gID.id);   // fails with null if I don't use the alert before setting the event handler
        event.dataTransfer.setData("text", event.currentTarget.parentWindow.gID.id + ',' + event.clientX + ',' + event.clientY);
    }

SVG

 <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" onload="startup(evt)">
   <g id="svgDial" transform="">
     <path id="seg1" fill="none" stroke="rgb(0, 134, 0)" d="M13.46,66.27 A40,40,0,0,1,10.1,52.79" stroke-width="20" />
     <path id="seg2" fill="none" stroke="rgb(50, 134, 0)" d="M10.01,50.7 A40,40,0,0,1,12.18,36.98" stroke-width="20" />
     <path id="seg3" fill="none" stroke="rgb(100, 134, 0)" d="M12.91,35.02 A40,40,0,0,1,20.27,23.23" stroke-width="20" />
     <path id="seg4" fill="none" stroke="rgb(150, 134, 0)" d="M21.72,21.72 A40,40,0,0,1,33.1,13.75" stroke-width="20" />
     <path id="seg5" fill="none" stroke="rgb(200, 134, 0)" d="M35.02,12.91 A40,40,0,0,1,48.6,10.02" stroke-width="20" />
     <path id="seg6" fill="none" stroke="rgb(255, 134, 0)" d="M50.7,10.01 A40,40,0,0,1,64.33,12.66" stroke-width="20" />
     <path id="seg7" fill="none" stroke="rgb(255, 100, 0)" d="M66.27,13.46 A40,40,0,0,1,77.79,21.23" stroke-width="20" />
     <path id="seg8" fill="none" stroke="rgb(255, 70, 0)" d="M79.25,22.72 A40,40,0,0,1,86.82,34.37" stroke-width="20" />
     <path id="seg9" fill="none" stroke="rgb(255, 35, 0)" d="M87.59,36.32 A40,40,0,0,1,90,50" stroke-width="20" />
     <path id="seg10" fill="none" stroke="rgb(255, 0, 0)" d="M89.95,52.09 A40,40,0,0,1,86.82,65.63" stroke-width="20" />
     <path id="needle" fill="rgb(100, 100, 100)" stroke="rgb(90, 90, 90)" stroke-width="2" d="M24.39,54.51 A26,26,0,1,1,27.48,63 l-20,4 Z" />
     <text id="numVal" x="34" y="58" fill="rgb(255, 255, 255)" style="font-family: 'Segoe UI'; font-size: 24px; text-align: center">0.0</text>
   </g>
 <script>
    <![CDATA[
     ...
     //]]>
 </script>
</svg>

質問:

  1. ここで発生するタイミング エラーとは何ですか?また、それを回避するにはどうすればよいですか?

  2. 私はまだ DOM をよく理解していませんevent.currentTarget.parentWindow.gID.id。イベントから一意の識別子を抽出する正しい方法はありますか? (HTMLオブジェクトからはできず、SVGに到達する必要があると思います)

  3. object タグは、Javascript を使用して外部 SVG ファイルを含めるための最良の方法ですか?

  4. HTML5のドラッグ/ドロップは機能するはずですが、ドラッグ/ドロップのサポートにJqueryのようなライブラリを使用するか、このシナリオのマウスダウン/マウスアップイベントハンドラーを介して手動のドラッグ/ドロップサポートを実装する方がよいでしょうか?

  5. 私は JavaScript に非常に慣れていないので、コードで他に何かばかげたことがある場合はお知らせください。

4

1 に答える 1

0

ID を (警告なしで) 取得しようとしている場合、新しい ID はまだレンダリングされていません。そのため、svgDialObj.addEventListener("load", function () { setTimeout の後にコードを追加して、100ms 程度後に呼び出す必要があります。

それは問題を解決するはずです。

于 2013-05-06T11:20:32.500 に答える