将 JavaScript 对象初始化为全局对象,然后在 Iframe 中使用

Initialize JavaScript object as global object for then use in Iframe

我有一个 class 需要初始化。

class ROS {
  static init() {
    // do ros initialization
    ROS.ros = new ROSLIB.Ros({
            url: 'ws://' + ROS.host + ':' + ROS.ws_port.toString()
        });
    // and so on
    }
  static topic_publisher(topic_name, msg){
    var topic = new ROSLIB.Topic({
            ros: ROS.ros,
            name: topic_name,
        });
        topic.publish(msg);
    }
}

如果我想向主题发布消息(调用 topic_publisher),我只需要这样做 ROS.topic_publisher("x_param', '0.1')

但是,在那些受人尊敬的页面中,应该有一个已经调用 ROS.init() 的脚本(我导入的所有 scripts.js 中至少有一个)。

我设计的网页由 4 iframes 和 1 parent 组成。假设他们都需要使用 ROS.topic_publisher("x_param', '0.1').

在目前的设计中,我需要跨所有页面调用ROS.init()。它使服务器有 5 个 ROS 客户端。

我想知道,我是否可以让初始化一次(可能在父级中),让其余的我框架只调用 ROS.topic_publisher("x_param', '0.1') 而无需重新导入或重新初始化 ROS.init().

我也尝试用parent.object。于是就变成了这样:

在父页面上:

var obj = ROS.init();
ROS.topic_publisher("x_param', '0.1'); // success

在 Iframe 页面上:

var obj = parent.obj;
obj.ROS.topic_publisher("x_param', '0.1'); // error 

任何信息都会有帮助...谢谢!

有几个问题。第一个是,据我所知,与 function 不同,class 不会创建全局绑定,因此 parent.ROS 不会找到任何东西。第二个,次要的是你需要在每个 window 中加载 ROSLIB。第三,这里的 init 并不是真正必要的,除非有更多的东西 — 一个简单的静态声明就可以了。

这样的事情可能会缓解所有这些问题。 (注意:代码未经测试;我不知道 ROSLIB 是什么)

window.ROS = class ROS {
  static ROSLIB = top.ROSLIB;
  static ros = top.ROS?.ros ?? new this.ROSLIB.Ros(...);

  static topic_publisher(topic_name, msg) {
    const topic = new this.ROSLIB.Topic(...);
    topic.publish(msg);
  }
}

请注意,所有这些仅在 top 与 child windows 的来源相同时才有效。如果没有,您将不得不使用 postMessage 代替。

编辑:另一个想法是不在每一帧中使用 ROS,而只在最上面的一个中使用。 (我相信这是我误解的原始概念。)这样更好,只需要对代码进行微小的修改:

// only in top window
window.ROS = class ROS {
  ...
};
ROS.init();

然后你可以在任何 windows.

中使用 top.ROS.topic_publisher(...)