我试图在渲染后重新定位骨干视图中的元素,但无法获得高度。我已经开始使用setTimeout,但我仍然非常困惑和沮丧。为什么height()仅在主干渲染函数内返回null
?
我设法在jsfiddle中重现:http://jsfiddle.net/turpana/3nh9916a/2/
答案 0 :(得分:1)
这是因为在调用view.$el
之后将render
插入到DOM中而不是之前。如果在实例化视图时指定el
var view = new View( { el : $('.bb-container') } );
然后this.$el
中的render
已经插入到DOM中,您的height()
将正常工作updated jsfiddle:
// in backbone view
var View = Backbone.View.extend({
render: function () {
this.$el.html('<p class="hello">hello</p>');
var heightInline = $('.hello').height();
setTimeout(function () {
var heightInTimeout = $('.hello').height();
$('.heights').append(
'<p><strong>In backbone view:</strong></p>'
+ '<p>height inline: ' + heightInline + '</p>'
+ '<p>height after 1 ms: ' + heightInTimeout + '</p>'
);
}, 1);
return this;
}
});
var view = new View( { el : $('.bb-container') } )
view.render()
// just jquery
$('.jq-container').html('<p class="hello-again">hello again</p>');
var jqHeightInline = $('.hello-again').height();
$('.heights').append(
'<p><strong>With just jQuery:</strong></p>'
+ '<p>height: ' + jqHeightInline + '</p>'
);
答案 1 :(得分:1)
尝试使用这样的render
,您应该更好地了解正在发生的事情:
render: function () {
this.$el.html('<p class="hello">hello</p>');
console.log('In render:');
console.log('There is a .hello:', $('.hello').length !== 0);
console.log('And it has height:', $('.hello').height());
console.log('There is a .hello in this.el:', this.$('.hello').length !== 0);
console.log('And it has height:', this.$('.hello').height());
setTimeout(function () {
console.log('After timeout:');
console.log('There is a .hello:', $('.hello').length !== 0);
console.log('And it has height:', $('.hello').height());
console.log('There is a .hello in this.el:', this.$('.hello').length !== 0);
console.log('And it has height:', this.$('.hello').height());
}, 1);
return this;
}
演示:http://jsfiddle.net/ambiguous/7c04rma4/
您将在控制台中获得如下输出:
In render:
There is a .hello: false
And it has height: null
There is a .hello in this.el: true
And it has height: 0
After timeout:
There is a .hello: true
And it has height: 18
There is a .hello in this.el: true
And it has height: 18
您的null
高度为$('.hello')
,因为.hello
为空。在之后 之后, el
已经添加到DOM中并且在之后发生 1}}返回。
如果您切换到render
,您会找到该元素(因为它位于this.$('.hello')
内,this.el
内搜索this.$
。当然,你的高度为零,所以这也不是非常有用。为什么高度为零?高度为零,因为浏览器在呈现之前不知道this.el
有多大。同样,在 <p>
返回后发生了这种情况。
您在render
回调中获得了有用的结果,因为只有在setTimeout
返回之后以及所有内容都添加到DOM之后才会触发。 JavaScript是单线程的,因此在浏览器再次获得控制权并且浏览器已清除其工作队列(包括DOM更新和呈现)之前,不会触发render
回调。您有时会看到_.defer
或setTimeout
来电,以便利用此功能。
有两种常见的方法摆脱这种困境:
setTimeout(..., 0)
或setTimeout
技巧以正确的顺序发生事情。这假设调用者将立即将内容放入DOM中。