2013-08-01 26 views
1

我正在研究一個呈現相同視圖的多個實例的Backbone應用程序。每個視圖都有一個相當大的節點樹,我可以看到用戶代理無法即時呈現視圖。呈現引擎延遲會影響javascript中的測量尺寸

我遇到的問題是,當我的渲染回調觸發時,高度正在通過0,因爲用戶代理的渲染引擎並未實際完成渲染整個視圖。如果我設置超時,則正確的最終高度將通過:

var ChildView = window.Backbone.View.extend({ 
    render: function() { 
     var template = require('templates/ChildTemplate'); 
     this.$el.html(template()); 
     this.afterRender(); 
    }, 
    afterRender: function() { 
     console.log(this.$el.outerHeight()); // 0 
     var _this = this; 
     setTimeout(function(){ 
     console.log(_this.$el.outerHeight()); // 51 (or some non-zero integer) 
     }, 100); 
     setTimeout(function(){ 
     console.log(_this.$el.outerHeight()); // 240, full correct height 
     }, 300); 
    } 
}); 

如何解釋此渲染引擎延遲?

架構:

  • 的jQuery 1.7.2
  • 骨幹0.9.9
+0

它可能比這更復雜。我目前遇到了一個Chrome問題,其中DOM元素的更改不會被JavaScript DOM屬性反映至少幾毫秒。這實際上使我的代碼亂成一團;如果我有一條條件或循環語句鏈,我在其中進行DOM修改,然後在JavaScript中測量某些內容,則必須將我的代碼分解爲可通過setTimeout按順序調用對方的一系列塊。在這種情況下,Chrome優化團隊讓我的生活比需要的困難得多。 –

回答

1

如果模板中包含圖片的話,我建議你使用標準的jQuery load功能

_this.$el.children('img').load(function(){ 
    //the element should exist now 
}); 

否則我不知道是什麼問題。林相當肯定,下劃線的template功能是同步的,所以我不會懷疑有任何問題。可能的工作,而且可能更有意義,從設計的角度來看一兩件事,將是利用initialize

var ChildView = window.Backbone.View.extend({ 
    initialize: function(){ 
     var template = require('templates/ChildTemplate'); 
     this.renderedTemplate = template(); 

    }, 
    render: function() { 
     this.$el.html(this.renderedTemplate); 
     this.afterRender(); 
    }, 
}); 

如果你不想使用名稱renderedTemplate然後多數民衆贊成罰款,只要確保不將它命名template因爲已經在使用

+0

模板包含單個圖像,但我們在加載之前知道其尺寸。問題是渲染的ChildView的總數,而不是任何一個特定視圖的內容。我的猜測是,用戶代理正在向JavaScript引擎發送某種後渲染回調信號,表明它可以在實際完成渲染整個節點樹之前繼續執行。儘管如此,我不知道這是如何工作的。 – biegel

+1

如果你真的非常渴望修復,我會考慮看看[livequery](https://github.com/brandonaaron/livequery)。你可以給它提供一個回調函數,當元素完全加載到DOM中時執行回調函數。 – Scott