簡體   English   中英

JSNI腳本失敗,但在Chrome Devtools控制台中運行時腳本成功

[英]JSNI script fails, but script succeeds when ran in Chrome Devtools console

我正在努力通過JSNI使用測試數據來利用名為cytoscape.js的外部JavaScript庫。 當我按我的Java類的要求運行腳本時,它無法生成圖形。 但是,當我通過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庫中的以下return語句失敗:

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

如果我注釋掉“ && obj.constructor ===對象;” 在cytoscape.js的第145行上,代碼使用我的JSNI腳本正確運行。 這使我相信通過JSNI和控制台創建cytoscape對象的方式有所不同。 盡管如此,Dev工具仍將控制台和JSNI方法列為提供相同的對象。 如何更新我的JSNI代碼以使其符合此檢查要求?

理想情況下,在這種情況下,JSNI應該可用。 我不確定為什么通過JSNI傳遞值會導致此if語句在通過控制台運行時失敗,而通過if語句。

問題在於Object與Object不完全相同,檢查instanceof幾乎可以肯定比cytoscape的作者所認為的要多得多-JS難道不是嗎?

cytoscape.js項目的instanceof Object測試不僅是針對“這是一個普通的Object,還是其他類型的實例”的測試,而是實際上測試“這是我的 Window實例中Object類的實例,並且而不是來自其他任何iframe /窗口”。

GWT的默認鏈接器會在iframe中評估您的代碼,以防止意外泄漏全局變量並使加載到同一頁面的JS混亂,或使同一頁面上的其他JS覆蓋或以其他方式干擾GWT的代碼。

除了嘗試將cytoscape的代碼更正為不太僵化和不靈活的方式以外,還有幾種方法可以解決此問題。

  • 從外部頁面創建Object的實例:為此,您必須直接創建對象,而不是使用{...}語法,該語法默認為您恰巧在其中執行的任何窗口。
       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);
       }-*/; 
  • 在執行GWT代碼的情況下,將cytoscape.js加載到同一iframe中。請注意,它可能在那里實際上不起作用,這會導致其他問題,但是您可以嘗試使用ScriptInjector將腳本內容插入GWT應用程序中,而不用引用它直接在您的.html頁面中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM