在Javascript中,我有以下代码:
var r=applet.foo({var0:99,var1:'foo',var2:applet});在我的小程序中,我有以下内容:
public JSObject foo(JSObject args){
System.out.println("The function is correctly invoked");
//In fact, the following works perfectly:
System.out.println("var1 is:"+(String)args.getMember("var1"));
JSObject w=JSObject.getWindow(this);
JSObject j=(JSObject)w.eval("new Object();");
Map m=new Hashmap();
//TODO here all the keys and values of args should be added to m
m.put("hello","world");
//TODO here all the keys and values of m should be added to j
return j;
}如何做到这一点?(TODOs)
在阅读06.html时,我注意到JSObject有一个getSlot方法,但如果有
args.getSlot(0)我只有一个例外:
netscape.javascript.JSException: No such slot 0 on JavaScript object
...发布于 2012-12-20 23:33:06
不幸的是,Errandir的解决方案只有在您知道全局变量的名称时才有效,该名称可用于访问您希望获得属性名称的对象。您需要知道这个名称才能将keys方法添加到对象中,并在稍后使用JSObject的打电话方法调用它。当然,如果您有对象的全局名称,则可以将它的全局名称传递给Java。这个解决方案看起来不太好,特别是当您不能在全局上下文中引用对象时。
作为另一种选择,我建议在评论中使用this of JSObject的评估方法,前提是它可以完成所有工作。但令人失望的是,它只能在Mozilla和Opera中正常工作。在Internet 9和Google (在Windows 7和Ubuntu12.04 LTS下测试)中,eval方法总是引用applet的文档窗口,忽略JavaScript对象JSObject实例实际上代表的内容。我不知道它是一个bug,还是这些浏览器支持的LiveConnect非常糟糕。
好消息是,call方法的JSObject在适当的上下文上执行指定的函数。记住这一点,我终于找到了一个如何检索JavaScript对象属性名称列表的解决方案。其思想是使用eval方法在全局上下文中定义一个临时函数。此函数必须接收我们希望获得属性的JavaScript对象,并将这些属性的名称作为数组返回。然后,通过JSObject的call方法调用临时函数,传递相关JavaScript对象的jsObject表示(以下方法中的jsObject或问题中的args ),最后删除临时函数。
public static ArrayList<String> getJsObjectPropertiesNames(Applet applet, JSObject jsObject) {
if (applet == null || jsObject == null)
return null;
// Retrieving global context - a JSObject representing a window applet belongs to
JSObject globalContext;
try {
globalContext = JSObject.getWindow(applet);
}
catch (JSException ex) {
return null;
}
// Checking whether passed object is not an array
try {
jsObject.getSlot(0);
return null;
}
catch (JSException e) {
}
String keysFunctionName = String.format("_getKeys%d", Calendar.getInstance().getTimeInMillis());
jsObject.eval("window['" + keysFunctionName + "'] = function(jsObject) { return Object.keys(jsObject) }");
JSObject propertiesNamesJsObject = (JSObject)globalContext.call(keysFunctionName, new Object[] { jsObject });
jsObject.eval("delete(window['" + keysFunctionName + "'])");
ArrayList<String> propertiesNames = new ArrayList<>();
try {
int slotIndex = 0;
while (true) {
Object propertyName = propertiesNamesJsObject.getSlot(slotIndex);
if (propertyName instanceof String)
propertiesNames.add((String)propertyName);
slotIndex++;
}
}
catch (JSException e) {
}
return propertiesNames;
}发布于 2012-10-17 10:21:10
作为一种解决方案,您可以将方法keys定义为建议的这里 (您可以在java代码中使用JSObject.eval(...)完成它)。然后你就可以得到这样的钥匙:
JSObject keys = (JSObject)args.call("keys", Collections.EMPTY_LIST);
keys.getSlot(0);发布于 2015-08-07 02:13:52
在这里,我打印一个字符串,请修改它,以获得任何您需要的。
public final static String getKeys = "{var keys = [];for (var key in this) {keys.push(key);} keys;}";
private static String printProperties(final Object o,
final boolean printType,
final int level,
final String tab) {
final StringBuilder sb = new StringBuilder(100);
if (printType) {
sb.append("(");
sb.append(o.getClass().getSimpleName());
sb.append(") ");
}
if (o instanceof JSObject) {
sb.append("{\n");
final JSObject js = (JSObject) o;
final JSObject keys = (JSObject) js.eval(getKeys);
boolean needComma = false;
for (int i = 0;; i++) {
final String key = (String) keys.getSlot(i);
if ((key != null) && !(key.equals("undefined"))) {
final Object val = js.getMember(key);
if (!needComma) {
needComma = true;
} else {
sb.append(",\n");
}
sb.append(multitab(tab, level));
sb.append(key);
sb.append(":");
sb.append(printProperties(val, printType, level + 1, tab));
} else {
break;
}
}
sb.append("\n");
sb.append(multitab(tab, level - 1));
sb.append("}");
} else {
sb.append(o);
}
return sb.toString();
}
private final static String tab = " ";
private static String multitab(final String tab,
int i) {
final StringBuilder sb = new StringBuilder();
while (i-- > 0) {
sb.append(tab);
}
return sb.toString();
}https://stackoverflow.com/questions/11350967
复制相似问题