1

考虑以下代码:

window.stage = bonsai.run(document.getElementById('stage'), {
  code: function() {
    var circle;
    circle = new Circle(200, 200, 50);
    circle.stroke('green', 2);
    circle.addTo(stage);
    circle.on('click', function(ev) {
      stage.sendMessage('click', ev);
    });
  },
  width: 500,
  height: 500
});

stage.on('load', function() {
  console.log('loaded');
  stage.on('message:click', function(ev) {
      console.log('click', ev);
  });
});

所以,点击圆圈会给我错误:DATA_CLONE_ERR: DOM Exception 25

如果我只是发送 ev.x 和 ev.y 之类的属性,它们就会很好地传递出去。我还可以在发送之前从其属性中重建对象,并且它可以正常通过。

如何在不解构-> 重构的情况下将事件对象原封不动地发送到父上下文?顺便说一句,为什么盆景会这样工作?

4

1 回答 1

2

太好了,你问我们为什么要这样分离。刚刚浏览了 BonsaiJS 文档并意识到我们没有明确说明为什么我们将渲染与执行线程分开。

BonsaiJS 代码主要在工作人员中执行(如果工作人员不可用,则回退到 iframe)并用于postMessage与创建工作人员的上下文进行通信。被DATA_CLONE_ERR: DOM Exception 25引发是因为 DOM 事件对象不能被postMessage. 为了解决您的问题,您可以创建一个简单的函数,该函数删除应该传递的对象的所有嵌套对象/函数:

window.stage = bonsai.run(document.getElementById('stage'), {
  code: function() {
    var circle;
    var makeSerializable = function(obj) {
      var ret = {}, val;
      Object.keys(obj).forEach(function(key) {
        val = obj[key];
        if (typeof val != 'object' && typeof val != 'function') {
          ret[key] = val;
        };
      });
      return ret; 
    };
    circle = new Circle(200, 200, 50);
    circle.stroke('green', 2);
    circle.addTo(stage);
    circle.on('click', function(ev) {
      stage.sendMessage('click', makeSerializable(ev));
    });
  },
  width: 500,
  height: 500
});

stage.on('load', function() {
  console.log('loaded');
  stage.on('message:click', function(ev) {
    console.log('click', ev);
  });
});

或者您可以强制 BonsaiJS 在 iF​​rame 中执行。然后你就可以访问 DOM 并且可以序列化任何对象(注意:见下文,为什么我不建议这样做):

window.stage = bonsai.setup({
  runnerContext: bonsai.IframeRunnerContext
}).run({...});

将主要代码执行放到worker中的主要原因是,我们不希望任何计算阻塞渲染“线程”,这样我们可以获得更流畅的动画(如果代码在iFrame中执行,渲染+代码执行将发生在同一个线程中,并且不会像工作线程那样流畅)。在 worker 中执行 JS 代码的另一个好处是,我们不依赖 DOM,还可以获取相同的 JS 代码并在 Rhino 或 NodeJS 等不同的 JS 环境中执行它(这里有一些示例代码,你如何可以在节点上执行 BonsaiJS 并通过 SocketIO 将渲染消息发送到浏览器:https ://github.com/uxebu/bonsai-server )。

于 2013-01-22T23:57:52.623 回答