gpt4 book ai didi

javascript - JSNI 脚本失败,但在 Chrome Devtools 控制台中运行时脚本成功

转载 作者:行者123 更新时间:2023-12-01 00:46:18 25 4
gpt4 key购买 nike

我正在通过 JSNI 使用测试数据来利用名为 cytoscape.js 的外部 JavaScript 库。当我在 java 类中通过 JSNI 运行脚本时,它无法生成图表。但是,当我通过 Chrome Devtools 控制台运行它时,它可以正常工作。

所有值似乎都正确传递到 cytoscape.js 库。目前,JSNI 代码未通过控制台代码能够通过的 Javascript 库执行的测试。

这是我正在使用的 JSNI 代码:

public static native void cytoscape() /*-{
var cy = $wnd.cy = $wnd.cytoscape({container: $wnd.document.getElementById('cy'),
elements: $wnd.glyElements,
style: [ { selector: 'node', style: { 'background-color': '#666', 'label': 'data(id)' } },
{ selector: 'edge', style: { 'width': 3, 'line-color': '#ccc', 'target-arrow-color': '#ccc', 'target-arrow-shape': 'triangle' } } ],
layout: { name: 'grid', rows: 1 } });
}-*/;

“$wnd”。用于获取正确的范围。

这是控制台代码:

var cy = window.cy = cytoscape({ 
container: document.getElementById('cy'),
elements: glyElements,
style: [ { selector: 'node', style: { 'background-color': '#666', 'label': 'data(id)' } }, { selector: 'edge', style: { 'width': 3, 'line-color': '#ccc', 'target-arrow-color': '#ccc', 'target-arrow-shape': 'triangle' } } ],
layout: { name: 'grid', rows: 1 }
});

我在这两种情况下使用的元素都存储在 .js 文件中,并且我确保它们在这两种情况下都可以访问。就像我提到的,Devtools 调试显示正确的值已传递到 cytoscape.js 库中。

JSNI 代码在 cytoscape.js 库中的返回语句失败:

var plainObject = function plainObject(obj) {
return obj != null && _typeof(obj) === typeofobj && !array(obj) && obj.constructor === Object;
};

如果我注释掉“&& obj.constructor === Object;”在 cytoscape.js 的第 145 行,代码与我的 JSNI 脚本一起正确运行。这让我相信 cytoscape 对象是通过 JSNI 创建的,与通过控制台创建的不同。尽管如此,开发工具仍将控制台和 JSNI 方法列为提供相同的对象。如何更新我的 JSNI 代码以使其符合此检查?

理想情况下,JSNI 在这种情况下应该可用。我不确定为什么通过 JSNI 传递值会导致该 if 语句在通过控制台传递 if 语句运行时失败。

最佳答案

问题是 Object 与 Object 并不完全相同,检查 instanceof 几乎肯定比 cytoscape 的作者认为的要多得多 - JS 不是很伟大吗?

cytoscape.js 项目的 instanceof Object 测试不仅仅是测试“这个东西是普通对象还是其他类型的实例”,而是实际上测试“这是我的窗口实例中的 Object 类的实例,而不是来自任何其他 iframe/窗口”。

GWT 的默认链接器会在 iframe 中评估您的代码,以防止意外泄漏全局变量和混淆加载到同一页面的 JS,或者让同一页面上的其他 JS 覆盖或以其他方式弄乱 GWT 的代码。

除了尝试将 cytoscape 的代码纠正为不那么严格和不灵活之外,还有几种方法可以解决此问题。

  • 从外部页面创建对象实例:为此,您必须直接创建对象,而不是使用 {...} 语法,该语法默认为您碰巧所在的任何窗口执行中。像这样:
       public static native void cytoscape() /*-{
var obj = new $wnd.Object();
obj.container = $wnd.document.getElementById('cy');//can also be simply $doc.getElementById('cy')
obj.elements = $wnd.glyElements;
// Note that you may have to repeat this for each of these nested objects, depending
// on how picky the library is being on otherwise identically structured code...
obj.style = [ { selector: 'node', style: { 'background-color': '#666', 'label': 'data(id)' } },
{ selector: 'edge', style: { 'width': 3, 'line-color': '#ccc', 'target-arrow-color': '#ccc',
'target-arrow-shape': 'triangle' } } ];
obj.layout = { name: 'grid', rows: 1 };
var cy = $wnd.cy = $wnd.cytoscape(obj);
}-*/;
  • 将 cytoscape.js 加载到执行 GWT 代码的同一个 iframe 中。请注意,它实际上可能无法在那里工作,这会导致其他问题,但您可以尝试使用 ScriptInjector 将脚本内容插入到 GWT 应用程序中直接在 .html 页面中引用它。

关于javascript - JSNI 脚本失败,但在 Chrome Devtools 控制台中运行时脚本成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57331705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com