2012-01-12 8 views
0

Raphaelを使用して、テキストオブジェクトを含む図形(下の例では楕円形)をドラッグして、図形またはテキストのいずれかをドラッグできるようにします。私はこれを行うために、テキスト要素のdrag()メソッドに渡された関数を関連する形状にデリゲートするように設定しました(this other oneへのより多態的なアプローチを試みています)。ただし、text.drag(...)が呼び出されたときに、 "obj.addEventListener is not function"というエラーが発生します。Raphaelでドラッグ機能を委任する

私はjavascriptを使い慣れていないので、おそらく本当に明白な失敗を作ったでしょうが、私はそれを見つけられません。委任関数にcall()を誤って使用しましたかmoveTextdragText、およびupText?それともラファエルのものですか?どんな助けでも大歓迎です。より冗長な名前にこれらを変更する(と競合する可能性が低い

​​

<html> 
<head> 
<title>Raphael delegated drag test</title> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<script src="js/raphael.js" type="text/javascript" charset="utf-8"></script> 
</head> 
<body> 
<script type="text/javascript"> 
window.onload = function initPage() { 
    'use strict'; 
    var paper = Raphael("holder", 640, 480); 
    var shape = paper.ellipse(190,100,30, 20).attr({ 
      fill: "green", 
      stroke: "green", 
      "fill-opacity": 0, 
      "stroke-width": 2, 
      cursor: "move" 
     }); 
    var text = paper.text(190,100,"Ellipse").attr({ 
      fill: "green", 
      stroke: "none", 
      cursor: "move" 
     }); 

    // Associate the shape and text elements with each other 
    shape.text = text; 
    text.shape = shape; 

    // Drag start 
    var dragShape = function() { 
     this.ox = this.attr("cx"); 
     this.oy = this.attr("cy"); 
    } 
    var dragText = function() { 
     dragShape.call(this.shape); 
    } 

    // Drag move 
    var moveShape = function (dx, dy) { 
     this.attr({cx: this.ox + dx, cy: this.oy + dy}); 
     this.text.attr({x: this.ox + dx, y: this.oy + dy}); 
    } 
    var moveText = function (dx,dy) { 
     moveShape.call(this.shape,dx,dy); 
    } 

    // Drag release 
    var upShape = function() { 
    }  
    var upText = function() { 
     upShape.call(this.shape); 
    } 

    shape.drag(moveShape, dragShape, upShape); 
    text.drag(moveText, dragText, upText); 
}; 
</script> 
    <div id="holder"></div> 
</body> 
</html> 

ソリューションはthis answerで指摘したように

、問題は、属性名の選択から生じますRaphaelと一緒に)問題を解決しますが、dataという属性に設定する方が安全です:

// Associate the shape and text elements with each other 
shape.data("enclosedText",text); 
text.data("parentShape",shape); 

// Drag start 
var dragShape = function() { 
    this.ox = this.attr("cx"); 
    this.oy = this.attr("cy"); 
} 
var dragText = function() { 
    dragShape.call(this.data("parentShape")); 
} 

// Drag move 
var moveShape = function (dx, dy) { 
    this.attr({cx: this.ox + dx, cy: this.oy + dy}); 
    this.data("enclosedText").attr({x: this.ox + dx, y: this.oy + dy}); 
} 
var moveText = function (dx,dy) { 
    moveShape.call(this.data("parentShape"),dx,dy); 
} 

答えて

3
​​

属性をRaphaelオブジェクトに追加しています。 Raphaelがどのように動作するのか(または将来的には動作するか)を知らなければ、これは危険であり、明らかに問題の原因となっています。本当に関連付ける場合は、Raphaels Element.dataを使用することをお勧めします。http://raphaeljs.com/reference.html#Element.data

+0

ドラッグするとラッパーはどのように機能しますか? Javascriptを非常に汎用的にするものがあれば、属性を追加できるようになりますが、これはコアの問題だとはっきりしているとは思いません。私はラファエルの固定版を使用しているので、将来のプルーフィングはそれほど問題ではありません。 – beldaz

+0

申し訳ありませんが、私は、「明らかになった」ことを「判明した」ものとして意味しました。そのような属性を追加することは強力な特性ですが、自分のコード以外でやってはならないことや、明示的に奨励されている場所で行うことを強くお勧めします。ドラッグすることについてRaphaelは 'set'以外のサポートを欠いています。したがって、実際にはプロジェクトの要件に依存します。簡単な解決策は、楕円とテキストオブジェクトをクロージャに挿入し、内部でハンドラをバインドすることです。欠点は、多くのオブジェクトが機能/ハンドラをたくさん意味することです。別の方法は、相互クラス名を使用し、オブジェクト(dict /ハッシュテーブルとして使用される)を介してルックアップを行うことです。 – bennedich

+0

私は問題の領域として識別した2行の属性名を置き換えることで、すべてを動作させることができます。それで本当に正しい。私はこのアプローチに固執し、将来は属性名でさらに注意を払うことを忘れないでください。あなたの選択肢はあまりにも私のために先進的な音;) – beldaz