初学者问题。我试图建立一个famo.us应用程序。到目前为止,我在一个简单的实验中得到了很好的结果。
现在我的应用程序正在增长,我想允许在"屏幕之间移动" :登陆屏幕 - >信息屏幕 - >回到登陆屏幕 - >等
我的"屏幕"是View()
的表面,修饰符等添加到View()
我使用RenderController()
在屏幕之间切换hide()
和show()
功能。
问题在于,当回到以前使用的屏幕时,表面不再显示了!
代码:
var app_render_controller = new RenderController();
app_render_controller.show(landing_screen); // ok
app_render_controller.hide(landing_screen); // ok
app_render_controller.show(info_screen); // ok
app_render_controller.hide(info_screen); // ok
app_render_controller.show(landing_screen); // NOK -> I only see my background surface !
在检查DOM时,我能够在他们应该看到的地方看到我的表面轮廓,但它们是隐藏的。看起来背景表面现在位于内容表面(ScrollView)的前面。如果我隐藏背景,我会再次看到Scrollview。
我读到元素的重叠与它们添加到渲染树的顺序相对应。所以,因为我的View()基于"屏幕"还没有改变,Scrollview应该像第一次一样在背景之上绘制?
这是预期的吗?难道我做错了什么 ?我想念一下吗?
-------编辑------
我的代码(大致):
var main_context = Engine.createContext();
var root_render_controller = new RenderController();
main_context.add(root_render_controller);
var landing_screen = new View();
landing_screen.add(new Surface(...background texture...));
var scrollview = new Scrollview();
landing_screen.add(scrollview);
// (add stuff to the scrollview)
var info_screen = new View();
info_screen.add(new Surface(...background texture...));
info_screen.add(new Surface(...some message...));
root_render_controller.show(landing_screen);
// display is fine
root_render_controller.hide(landing_screen);
root_render_controller.show(info_screen);
// display is fine
root_render_controller.hide(info_screen);
root_render_controller.show(landing_screen); // again
// display is wrecked : the background surface is now hiding the scrollview !
在查看DOM时,我们可以看到翻转:
答案 0 :(得分:1)
我读到元素的重叠对应于它们被添加到渲染树的顺序
从我所看到的,元素的重叠是由创建顺序的倒数(例如,最后一个在顶部)设置,而不是添加到渲染树。
创建Surface时,会在Entity
注册:
https://github.com/Famous/core/blob/master/Surface.js#L60
function Surface(options) {
...
this.id = Entity.register(this);
...
}
当提交RenderNode
上的更改时,将根据创建顺序应用它们(因为Object.keys
以数字顺序返回数组中的索引):
https://github.com/Famous/core/blob/master/RenderNode.js#L106
function _applyCommit(spec, context, cacheStorage) {
var result = SpecParser.parse(spec, context);
var keys = Object.keys(result);
for (var i = 0; i < keys.length; i++) {
var id = keys[i];
var childNode = Entity.get(id);
....
}
您可以通过创建两个Surface
并在第一个Context
之前将您创建的第二个添加到define(function(require, exports, module) {
var Engine = require("famous/core/Engine");
var Surface = require("famous/core/Surface");
var mainContext = Engine.createContext();
var surface1 = new Surface({
size: [200, 200],
content: "Red",
properties: {
lineHeight: "200px",
textAlign: "center",
backgroundColor: "#f00"
}
});
var surface2 = new Surface({
size: [200, 200],
content: "Green",
properties: {
lineHeight: "200px",
textAlign: "center",
backgroundColor: "#0f0"
}
});
// Doesn't matter what order you add these - surface2 will be on top
mainContext.add(surface2);
mainContext.add(surface1);
});
来对此进行测试。它仍然是最重要的:
Context
希望这给你一个开始寻找的好地方。如果您分享了将背景添加到{{1}}的位置,以便了解它现在在前面的原因,将会有所帮助。
答案 1 :(得分:1)
您似乎在RenderController
中发现了一个错误。下面的简单示例展示了您描述的相同行为。我已经在https://github.com/Famous/views/issues/42提交了回购邮件。
注意:如果您在显示下一个视图之前不隐藏当前视图,则会得到相同的行为。有趣的是,如果你在隐藏/显示操作之间等待,你会看到不同的错误行为。
define(function(require, exports, module) {
var Engine = require("famous/core/Engine");
var Surface = require("famous/core/Surface");
var View = require("famous/core/View");
var RenderController = require("famous/views/RenderController");
var Timer = require("famous/utilities/Timer");
var mainContext = Engine.createContext();
var renderController = new RenderController();
mainContext.add(renderController);
var view1 = new View();
var view2 = new View();
var surface1 = new Surface({
size: [200, 200],
content: "Red Background",
properties: {
lineHeight: "200px",
textAlign: "center",
backgroundColor: "#f00"
}
});
var surface2 = new Surface({
size: [200, 200],
content: "Green Foreground",
properties: {
lineHeight: "200px",
textAlign: "center",
backgroundColor: "#0f0"
}
});
var surface3 = new Surface({
size: [200, 200],
content: "Blue Background",
properties: {
lineHeight: "200px",
textAlign: "center",
backgroundColor: "#00f"
}
});
var surface4 = new Surface({
size: [200, 200],
content: "Black Foreground",
properties: {
lineHeight: "200px",
textAlign: "center",
backgroundColor: "#000",
color: "white"
}
});
view1.add(surface1);
view1.add(surface2);
view2.add(surface3);
view2.add(surface4);
// If performing hide/show on same tick (or not hiding before show),
// you get green-fg, black-fg, red-bg (wrong)
renderController.show(view1);
Timer.setTimeout(function() {
renderController.hide(view1); // <- commenting this out results in same behavior
renderController.show(view2);
Timer.setTimeout(function() {
renderController.hide(view2); // <- commenting this out results in same behavior
renderController.show(view1);
}, 1000);
}, 1000);
// If waiting between each hide/show
// you get green-fg, blue-bg (wrong), green-fg
// renderController.show(view1);
// Timer.setTimeout(function() {
// renderController.hide(view1);
// Timer.setTimeout(function() {
// renderController.show(view2);
// Timer.setTimeout(function() {
// renderController.hide(view2);
// Timer.setTimeout(function() {
// renderController.show(view1);
// }, 1000)
// }, 1000)
// }, 1000)
// }, 1000)
});
答案 2 :(得分:1)
一个视图不知道应该将Surfaces分层的顺序。当使用RenderController隐藏某些内容时,它会释放Surface正在管理的文档片段。当该视图返回场景图时,Surfaces将获取一个文档片段,以填充未使用元素池中的内容(如果存在),如果池为空,则会创建新元素。
由于浏览器实现分层的方式,如果新DOM节点存在于Z中的相同变换并且具有相同的CSS zIndex,则新创建的DOM节点存在于旧DOM节点之上。如果需要显式分层,则不应依赖创建顺序。尝试通过添加Modifiers在z空间中转换它们或添加显式CSS zIndexing来表示你的图层应该是什么来解决这个问题。