从JavaFX中的Javascript访问返回值

时间:2016-09-27 12:59:57

标签: javascript java javafx webengine

我在webengine中执行了以下Javascript。 资料来源:Execute a Javascript function for a WebView from a JavaFX program

此Javascript突出显示网站上的特定字词。

WebView webView = new WebView();
final WebEngine engine = webView.getEngine();
engine.load("https://stackoverflow.com/questions/14029964/execute-a-javascript-function-for-a-webview-from-a-javafx-program");

engine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
    @Override
    public void changed(ObservableValue ov, State oldState, State newState) {
        if (newState == State.SUCCEEDED) {
            engine.executeScript(
                "function highlightWord(root,word){"
                + "  textNodesUnder(root).forEach(highlightWords);"
                + ""
                + "  function textNodesUnder(root){"
                + "    var n,a=[],w=document.createTreeWalker(root,NodeFilter.SHOW_TEXT,null,false);"
                + "    while(n=w.nextNode()) a.push(n);"
                + "    return a;"
                + "  }"
                + ""
                + "  function highlightWords(n){"
                + "    for (var i; (i=n.nodeValue.indexOf(word,i)) > -1; n=after){"
                + "      var after = n.splitText(i+word.length);"
                + "      var highlighted = n.splitText(i);"
                + "      var span = document.createElement('span');"
                + "      span.style.backgroundColor='#f00';"
                + "      span.appendChild(highlighted);"
                + "      after.parentNode.insertBefore(span,after);"
                + "    }"
                + "  }"
                + "}"
                + "\n"
                + "highlightWord(document.body,'function');");
        }
    }
});

我想检查一个网站是否包含一个特定的单词,我认为这个代码是一个很好的起点,因为它工作正常并突出显示单词。 我现在需要的是,在突出显示时应该计算Javascript。 然后,如果包含一个单词(counter> = 1),我想得到一个布尔返回值,我可以在JavaFX中访问它。

我尝试了一些东西,但我真的不知道如何使脚本能够添加一个计数器和一个可以在脚本之外访问的返回值。

谢谢大家阅读。

1 个答案:

答案 0 :(得分:0)

使用executeScript时,将根据方法的javadoc中编写的规则返回评估结果。 javadoc of WebEngine也会告诉您这种可能性。

  

执行结果,使用以下内容转换为Java对象   规则:

     
      
  • JavaScript Int32转换为java.lang.Integer
  •   
  • java.lang.Double的其他JavaScript编号
  •   
  • JavaScript字符串到java.lang.String
  •   
  • JavaScript boolean to java.lang.Boolean
  •   
  • JavaScript null to null
  •   
  • 大多数JavaScript对象都被包装为netscape.javascript.JSObject
  •   
  • JavaScript JSNode对象被映射到netscape.javascript.JSObject的实例,它们也实现了org.w3c.dom.Node

  •   
  • 一个特殊情况是JavaScript类JavaRuntimeObject,它用于将Java对象包装为JavaScript值 - 在本例中我们   只提取原始Java值。

  •   

因此,如果javascript脚本返回一个Int32,你可以得到它:

Integer executeScript = (Integer) engine.executeScript(...);

您更新的示例(例如):

Integer numOfHighlights = (Integer) engine.executeScript(
    "function highlightWord(root,word){"
    + "  count = 0;"
    + "  textNodesUnder(root).forEach(highlightWords);"
    + ""
    + "  function textNodesUnder(root){"
    + "    var n,a=[],w=document.createTreeWalker(root,NodeFilter.SHOW_TEXT,null,false);"
    + "    while(n=w.nextNode()) a.push(n);"
    + "    return a;"
    + "  }"
    + ""
    + "  function highlightWords(n){"
    + "    for (var i; (i=n.nodeValue.indexOf(word,i)) > -1; n=after){"
    + "      var after = n.splitText(i+word.length);"
    + "      var highlighted = n.splitText(i);"
    + "      var span = document.createElement('span');"
    + "      span.style.backgroundColor='#f00';"
    + "      span.appendChild(highlighted);"
    + "      after.parentNode.insertBefore(span,after);"
    + "      count = count + 1;"
    + "    }"
    + "  }"
    + "  return count;"
    + "}"
    + "\n"
    + "highlightWord(document.body,'execute');");

System.out.println("Number of highlights are: " + numOfHighlights);

输出

Number of highlights are: 9

我只添加了一个计数器变量,该变量针对每个突出显示的项目递增,然后最终返回此变量。