2017-01-04 21 views
1

Snap.svg APIに関数Element.append(el)を使用する際に問題があります。 SVGのインスタンスを変数の配列に格納して、実行時に特定のSVGにアクセスできるようにする必要があります。読み込み用の配列にSVGオブジェクトを格納する

groupViewsに保存するだけでこのコードを試してみましょう。しかし、それを配列(groupView)を置くことは私にこのエラーをもたらします:

Uncaught TypeError: Cannot read proerty 'append' of undefined

コンソールは私が私が試して他に何かわからないgroupViewsgroupView[i]を記録し、同じ出力を示しています。

どのように私はこれを解決することができますか?ありがとう。

for(var i = 0; i < numOfGroups; i++) 
    { 
    var sel = '#GroupView' + i; 
    groupView[i] = Snap(sel); 
    console.log(groupView[i]); 
    groupViews = Snap('#GroupView0'); 
    console.log(groupViews); 


    Snap.load("/svg/groupView-12_13_2016-01.svg", function(f) { 
     groupView[i].append(f); 
     groupViews.append(f); 


    }); //end of Snap.load(groupView) 


    } 

編集(1/5):ここで

は私が空SVGsがロードされているHTMLコードです:したがって

<div class = "groupView0"> 
    <svg viewBox='0 0 3640.9 540.5' id='GroupView0'></svg> 
</div> 

<div class = "groupView1"> 
    <svg viewBox='0 0 3640.9 540.5' id='GroupView1'></svg> 
</div> 

、これは私が特定のSVGファイルをロードしています理由ですそれをJSに追加します。これを行うより良い方法はありますか?

編集(1/6):ここで

は私のSVGファイルのごく一部です:

<?xml version="1.0" encoding="utf-8"?> 
<!-- Generator: Adobe Illustrator 20.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> 
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
    viewBox="0 0 3640.9 540.5" style="enable-background:new 0 0 3640.9 540.5;" xml:space="preserve"> 

<g id="A" onclick="detailedView();" cursor="pointer"> 
    <rect id="PanelBackground" x="35.4" y="55.5" class="st2" width="173.2" height="155"/> <!--height="444" --> 
    <g id="UpperBar"> 
     <linearGradient id="Header_20_" gradientUnits="userSpaceOnUse" x1="35.3937" y1="67.0279" x2="208.5774" y2="67.0279"> 
      <stop offset="0" style="stop-color:#F68E1E"/> 
      <stop offset="0.5" style="stop-color:#F16A22"/> 
      <stop offset="0.903" style="stop-color:#F05F22"/> 
      <stop offset="1" style="stop-color:#F05C22"/> 
     </linearGradient> 
     <polygon id="Header" class="st3" points="35.4,55.5 208.6,55.5 208.6,78.6 35.4,78.6  "/> 
     <g> 
      <rect x="82.1" y="61.8" class="st4" width="121" height="10.8"/> 
      <text id="GroupName" transform="matrix(1 0 0 1 82.0885 71.6627)" class="st5 st6 st7">A</text> 
      <text id="FloorNumber" transform="matrix(1 0 0 1 182.3287 141.8773)" class="st2 st19 st7">X</text> 
     </g> 
    </g> 
</svg> 

あなたが投稿したコードを実行した後... 私のようなコードを実行しようとした場合

groupName[0] = groupView[0].select('#GroupName'); 
groupName[0].attr({ 
    text: "something" 
}); 

私はこのエラーを取得する:Uncaught TypeError: Cannot set property '0' of undefined

+0

は、すでにロードされてSVGですか?それとも、Snap.loadにロードしていますか? – MiltoxBeyond

+0

@MiltoxBeyondええ、SVGは私のHTMLページに読み込まれます。 – KS7X

+0

何をしようとしていますか?後で追加する要素を保存しますか?また、DOMのいくつかまたはすべての要素を同時にDOMに追加しながらSVG要素を格納するので、それらはすべてDOMにあり、表示されますが、後でアクセスするだけです。おそらく(f)を2回追加するのは意味がありませんが、もう少し情報が必要です。 – Ian

答えて

1

それはあなたが同じSVGファイルたびにロードされているように見えるとしてクローンを()を使用して、このような何かを試してみてください、私たちは、一度にそれを読み込むことができ、その後、クローン()サーバーへの繰り返し呼び出しを保存します。

これは、svgファイルに外部マークアップがあることに基づいています。部分的なsvgで、要素しかない場合は、select( 'svg')を選択( 'group')するか、それを変更します。

次に、クローンへの参照を格納し、その要素をインデックス付きのsvg要素に追加します。ここで

は完全な例である、にロードされたSVG test.svgは単に..です

<svg> 
    <rect x="20" y="20" width="100" height="100" /> 
</svg> 

メインのHTML/JS

<body> 
<div class="groupView0"> 
    <svg id="groupView0"></svg> 
</div> 
<div class="groupView1"> 
    <svg id="groupView1"></svg> 
</div> 
<div class="groupView2"> 
    <svg id="groupView2"></svg> 
</div> 

<script> 

var sel = "#groupView"; 
var groupView = []; 
var numOfGroups = 3; 

Snap.load("test.svg",onSVGLoaded); 

function onSVGLoaded (fragment) { 
    groupView[0] = Snap(sel + '0').append(fragment).select('svg'); 

    for(var i = 1; i < numOfGroups; i++) { 
    groupView[i] = groupView[0].clone().appendTo(Snap(sel + i)); 
    } 

    groupView[0].attr({ fill: 'yellow' }); 
    groupView[1].attr({ fill: 'red' }); 
    groupView[2].attr({ fill: 'green' }); 
} 

Working example

+0

こんにちはイアン、私はDOM内のwhatsに関して私の投稿を編集しました。その配列が必要なので、SVGの各インスタンスを参照して、Element.animateやElement.attrなどの関数を各インスタンスに使用できるようにしています。 – KS7X

+0

これは、各グループビューに読み込まれるのと同じSVGですか、あるいは異なるSVGがたくさんありますか?あなたが読み込んでいるsvgファイルの内容ははっきりしません。 – Ian

+0

これは私がロードしているのと同じです。バックエンドのデータとの関連付けを行うには、そのsvgの複数のインスタンスが必要です。 svgファイルには、バックエンドの変数にすべて関連する複数の要素が含まれています。 – KS7X

0

問題はヨーヨーですuはループの中で非同期関数を使用しているので、ファイルが終了した後はロードされません(特に、同じファイルを同じファイルnumOfGroups - 1回呼び出しているため)。基本的に結果が返ってくると、私はすでに配列全体を処理していますが、iの値は期待した範囲にありません(正確にはnumOfGroups)。

groupView[numOfGroups]は決して値に設定されていないため、未定義です。

理想的な解決策は、いずれかのようなので(コールバック関数に)ループの前にロードする外部ファイルを待機する。

var sel = '#GroupView'; 
var groupView = []; 
Snap.load("/svg/groupView-12_13_2016-01.svg", function(f) { 
     for(var i = 0; i < numOfGroups; i++) { 
      groupView[i] = new Snap(sel+i); 
      groupView[i].append(f); 
     }  
}); 

または中にコールバック関数をだますために、ループ範囲内で変数を定義します負荷の値を割り当てるときに再びそのように、スコープの変数を使用して:

for(var i = 0; i < numOfGroups; i++) 
    { 
    var sel = '#GroupView' + i; 
    var cur = i; //This creates a scope variable for the current callback. 
    groupView[i] = Snap(sel); 
    console.log(groupView[i]); 
    groupViews = Snap('#GroupView0'); 
    console.log(groupViews); 


    Snap.load("/svg/groupView-12_13_2016-01.svg", function(f) { 
     groupView[cur].append(f); 
     groupViews.append(f); 


    }); //end of Snap.load(groupView) 
    } 

はしかし、第2の解決策は、実際には同じファイルのための時間の要求numOfGroupsを作る考えると、非常に非効率的であり、かつ負荷numOfGroupsコールバックをメモリに保存します。必要なのは、実際に別のファイルを呼び出す場合だけです。

最後に、起こっていることの簡単な例をお伝えします。

var d = document.getElementById("testOutput"); 
 
var b = document.getElementById("trigger"); 
 

 
function RunTest() { 
 
    var arr = []; 
 
    d.innerHTML = ""; 
 
    for (var i = 0; i < 10; i++) { 
 
    d.innerHTML += "Loop: " + i; 
 
    arr[i] = i; 
 
    setTimeout(function() { 
 
     d.innerHTML += "i is " + i + "<br />"; 
 
    }, 1000); //Simulates Delay while loading... 
 
    d.innerHTML += "...Finished Loop </br>"; 
 
    } 
 
}
<input id="trigger" type="button" onClick="RunTest()" value="Test" /> 
 
<div id="testOutput"></div>

+0

私のコードで何が起こっているかの深い説明と例をありがとうございました。私はあなたが提供した両方のソリューションを試しましたが、私はまだ問題にぶつかります。 'Uncaught TypeError:未定義のプロパティ '0'を設定できません。 ' – KS7X

+0

2番目の例ではスコープが作成されていないとは思いませんか? 2つの追加があるかどうかは不明ですが、それは元の質問にもっと明快に必要なものです。 – Ian

+0

最初の例は完全なコードではありません。あなたは 'groupView = [];'を設定する必要があります – MiltoxBeyond

関連する問題