0

我确实有以下设置:

    var LayerItemView = Backbone.Marionette.ItemView.extend({

    tagName: 'li',
    className: 'stage-layer',
    template: '#layer-item-tpl',

    initialize: function() {
           $(this.el).attr('id' 'layer-'+this.model.id);
    },

    onRender: function() {
    App.vent.trigger('layer:rendered', this.model);
    }

});

我相信,DOM 元素 layer-[id] 现在应该可用了。eventHandler 然后为每个模型创建一个 Raphael 画布到新创建的 DOM 元素,如下所示:

var paper1 = new Raphael(document.getElementById('layer-1'), 896,504);  
var paper2 = new Raphael(document.getElementById('layer-2'), 896,504);  
var paper3 = new Raphael(document.getElementById('layer-3'), 896,504);  
etc.

但是我从 Raphael 收到了一个错误:未捕获的类型错误:无法读取未定义的属性“x”

这告诉我具有 layer-ids 的元素在 DOM 中尚不可用。我用一个简单的 setTimeout 解决了这个问题(有点这样做):

setTimeout(function() {
  var paper1 = new Raphael(document.getElementById('layer-1'), 896,504);  
  var paper2 = new Raphael(document.getElementById('layer-2'), 896,504);  
  var paper3 = new Raphael(document.getElementById('layer-3'), 896,504);    
},0);

我对此感到不舒服。会不会是正确的练习?我想了解为什么这是有效的以及这是否是好的做法

4

1 回答 1

2

此代码具有欺骗性,因为乍一看有人可能会认为

var paper1 = new Raphael(document.getElementById('layer-1'), 896,504);  
var paper2 = new Raphael(document.getElementById('layer-2'), 896,504);  
var paper3 = new Raphael(document.getElementById('layer-3'), 896,504); 

setTimeout(function() {
  var paper1 = new Raphael(document.getElementById('layer-1'), 896,504);  
  var paper2 = new Raphael(document.getElementById('layer-2'), 896,504);  
  var paper3 = new Raphael(document.getElementById('layer-3'), 896,504);    
},0);

是相同的。实际上,它们是非常不同的。

使这两个代码块不同的原因是 Javascript 是一种单线程语言。setTimeout当计时器在 setTimeout 中达到 0 时,不会准确调用任何创建的函数。它将大约在那个时间范围内执行。首先 Javascript 将继续执行它所在的当前代码块。

因此setTimeout,在您的情况下,线程在其所在的当前代码块中完成后执行。

此处提供了一个很好的参考资料和更多详细信息。由 John Resig (jQuery) 编写。

于 2013-02-17T22:06:43.520 回答