0

以下は私のコードです。画像を読み込んでonclickイベントをそれにバインドしています。私が望むのは、このステージを保存して何か他のものを描画することです。つまり、戻るボタンで次の画面を表示すると、戻るボタンで前の画面が読み込まれます。しかし、json を使用してステージを保存し、ステージをリロードすると、ステージはすべて正常に表示されますが、クリックするとイベントが画像から削除されます。すべての要素とそのイベントをそのままに、前の画面を表示できるようにしたいのですが。これを行うことができるjsonを使用する別の方法はありますか?

<!DOCTYPE HTML>
<html>
<head>
<style>
body {
    margin: 0px;
    padding: 0px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="js/kinetic-v4.3.3.min.js" type="text/javascript"></script> 
<script type="text/javascript">
function loadImages(sources, callback){
    var assetDir = 'http://localhost/kineticdemo/images/';
    var images = {};
    var loadedImages = 0;
    var numImages = 0;
    for(var src in sources) {
      numImages++;
    }
    for(var src in sources){
      images[src] = new Image();
      images[src].onload = function(){
        if(++loadedImages >= numImages){
          callback(images);
        }
      };
      images[src].src = assetDir + sources[src];
    }
}

function initStage(images)
{
    var stage = new Kinetic.Stage({
      container: 'container',
      width: 730,
      height: 700
    });
    var outerLayer = new Kinetic.Layer();
    var logo = new Kinetic.Image({
              image:images.logo,
              x:450,
              y:75,
              id:"logo"
            });

    logo.on('click',function(){
        alert('aaa');
    });

    outerLayer.add(logo);
    stage.add(outerLayer);

    var json = stage.toJSON();
    stage.destroy();
    stage = Kinetic.Node.create(json, 'container');
    stage.get('#logo').apply('setImage',images.logo);
    stage.draw();
}
var sources = {
    logo: 'logo.png'
};
loadImages(sources, initStage);
</script>
</body>
</html>
4

1 に答える 1

0

はい、KineticJS は Node プロパティをシリアル化しますが、Node イベント ハンドラーはシリアル化しません。

そのため、リハイドレートされたステージはどのノードが「リッスン」しているかを認識しますが、イベント ハンドラーを手動で再バインドする必要があります。

クリック イベント ハンドラの再水和

// re-bind event listener
stage.get('#logo').on('click',  function(e) {  alert('aaa');  }   );

文字列にシリアル化されたクリック イベント ハンドラーの再水和

元のイベント ハンドラーのコードがあると仮定すると、JavaScript の「Function()」を使用して、文字列にシリアル化されたイベント ハンドラーを再水和することができます。

考えられる落とし穴: 「new Function()」のコンテキストは常にウィンドウ コンテキストであるため、リハイドレートされたイベント ハンドラはクロージャを壊します (クロージャを使用している場合)。

考えられる落とし穴: 文字列を関数として実行することは危険なほどハッキング可能です。あなたは「alert('goodness')」を意図していますが、ハッカーは「alert('evil')」に置き換えています。

// bind an event listener that was serialized to a string
var myStringFn="alert('aaa')";
stage.get('#logo').on('click', new Function("event", myStringFn) );
于 2013-03-16T14:01:12.230 に答える