首页 > 解决方案 > 将 JavaScript 对象初始化为全局对象,然后在 Iframe 中使用

问题描述

我有一个需要初始化的类。

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我导入的所有脚本中的一个)。

我设计了由 4iframes和 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 

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

标签: javascriptjqueryiframeros

解决方案


有几个问题。第一个是,与 AFAIK 不同functionclass它不会创建全局绑定,因此parent.ROS不会找到任何东西。第二个次要的问题是您需要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与子窗口的来源相同时才有效。如果没有,您将不得不使用postMessage

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

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

然后您可以top.ROS.topic_publisher(...)在任何窗口中使用。


推荐阅读