1

一个初学者的问题。我正在尝试建立一个 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() 的“屏幕”下的树没有改变,滚动视图仍应像第一次一样绘制在背景之上?

这是预期的吗?难道我做错了什么 ?我错过了什么吗?

- - - - 编辑 - - -

我的代码(大致):

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 时,我们可以看到翻转:

登陆屏幕的第一个显示:背景,然后是滚动视图及其 6 个元素

登陆屏幕的第一个显示:背景,然后是滚动视图及其 6 个元素

登陆屏幕的第二个显示:滚动视图及其 6 个元素,然后是背景!

登陆屏幕的第二次显示:滚动视图及其 6 个元素,然后是背景

4

3 回答 3

1

我读到元素的重叠与它们添加到渲染树的顺序相对应

从我所见,元素的重叠是由创建顺序的倒数设置的(例如,顶部的最后一个),而不是渲染树的添加。

创建 Surface 时,它​​会注册到Entityhttps ://github.com/Famous/core/blob/master/Surface.js#L60

function Surface(options) {
   ...
    this.id = Entity.register(this);
   ...
}

当 a 上的更改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);
    ....
}

您可以通过创建两个Surfaces 并将您创建的第二个添加到第一个Context之前的 a 来测试这一点。它仍将位于顶部:

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以了解为什么它现在在前面,这将有所帮助。

于 2014-05-10T21:41:17.967 回答
1

View 不知道 Surface 的分层顺序。当使用 RenderController 隐藏某些内容时,它会释放 Surface 管理的文档片段。当该视图被带回场景图时,Surfaces 会从未使用的元素池中获取一个文档片段以填充其内容(如果存在),如果池为空,它会创建新元素。

由于浏览器实现分层的方式,如果新创建的 DOM 节点存在于 Z 中的相同变换处并且具有相同的 CSS zIndex,则它们存在于旧 DOM 节点之上。如果需要显式分层,则不应依赖创建顺序。尝试通过添加修饰符以在 z 空间中转换它们或添加显式 CSS zIndexing 来表示您的图层应该是什么来解决这个问题。

于 2014-05-11T20:27:27.410 回答
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)


});
于 2014-05-11T15:49:36.327 回答