将javascript添加到webview JavaFX,HTML Highlighter

时间:2015-02-06 15:23:33

标签: java javascript jquery webview javafx

在我的程序的某些部分,我想在webview JavaFX中加载一个网页,并使用javascript代码进行自定义。在这种情况下,我想在网页中突出显示一些单词。

当我搜索时,这个网站有需要的javascript代码(突出显示单词):" highlight: JavaScript text higlighting jQuery plugin"要使用此代码,我应该在webview中加载,然后使用javascript命令突出显示单词。

当我搜索时,我发现this code on github将JQuery嵌入到加载的webview中。 所以我结合这些代码并创建: (engine.executeScript参数是highlight.js代码)

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class HtmlHighlighter extends Application {

    public static final String DEFAULT_JQUERY_MIN_VERSION = "1.7.2";
    public static final String JQUERY_LOCATION = "http://code.jquery.com/jquery-1.7.2.min.js";

    @Override
    public void start(Stage primaryStage) {

        WebView browser = new WebView();
        final WebEngine engine = browser.getEngine();

        engine.getLoadWorker().stateProperty().addListener(
                new ChangeListener<Worker.State>() {
                    @Override
                    public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
                        if (newState == Worker.State.SUCCEEDED) {
                            System.out.println(engine.getDocument().getDocumentURI() + " was Successfully loaded");

                            executejQuery(engine, DEFAULT_JQUERY_MIN_VERSION, JQUERY_LOCATION, "$(\"a\").click(function(event){"
                                    + "  event.preventDefault();"
                                    + "  $(this).hide(\"slow\");"
                                    + "});");
                        }
                    }
                });

        engine.load("https://gist.github.com/jewelsea/3077942");

        Button highlight = new Button("highlight");
        highlight.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                engine.executeScript("jQuery.fn.highlight = function(pat) {\n"
                        + " function innerHighlight(node, pat) {\n"
                        + "  var skip = 0;\n"
                        + "  if (node.nodeType == 3) {\n"
                        + "   var pos = node.data.toUpperCase().indexOf(pat);\n"
                        + "   pos -= (node.data.substr(0, pos).toUpperCase().length - node.data.substr(0, pos).length);\n"
                        + "   if (pos >= 0) {\n"
                        + "    var spannode = document.createElement('span');\n"
                        + "    spannode.className = 'highlight';\n"
                        + "    var middlebit = node.splitText(pos);\n"
                        + "    var endbit = middlebit.splitText(pat.length);\n"
                        + "    var middleclone = middlebit.cloneNode(true);\n"
                        + "    spannode.appendChild(middleclone);\n"
                        + "    middlebit.parentNode.replaceChild(spannode, middlebit);\n"
                        + "    skip = 1;\n"
                        + "   }\n"
                        + "  }\n"
                        + "  else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {\n"
                        + "   for (var i = 0; i < node.childNodes.length; ++i) {\n"
                        + "    i += innerHighlight(node.childNodes[i], pat);\n"
                        + "   }\n"
                        + "  }\n"
                        + "  return skip;\n"
                        + " }\n"
                        + " return this.length && pat && pat.length ? this.each(function() {\n"
                        + "  innerHighlight(this, pat.toUpperCase());\n"
                        + " }) : this;\n"
                        + "};\n"
                        + "\n"
                        + "jQuery.fn.removeHighlight = function() {\n"
                        + " return this.find(\"span.highlight\").each(function() {\n"
                        + "  this.parentNode.firstChild.nodeName;\n"
                        + "  with (this.parentNode) {\n"
                        + "   replaceChild(this.firstChild, this);\n"
                        + "   normalize();\n"
                        + "  }\n"
                        + " }).end();\n"
                        + "}; $('body').highlight('t');");
            }
        });

        VBox v = new VBox(10);
        v.getChildren().setAll(browser, highlight);

        primaryStage.setScene(new Scene(v));
        primaryStage.show();
    }

    /**
     * Executes a script which may reference jQuery function on a document.
     * Checks if the document loaded in a webEngine has a version of jQuery
     * corresponding to the minimum required version loaded, and, if not, then
     * loads jQuery into the document from the default JQUERY_LOCATION.
     *
     * @param engine the webView engine to be used.
     * @Param jQueryLocation the location of the jQuery script to be executed.
     * @param minVersion the minimum version of jQuery which needs to be
     * included in the document.
     * @param script provided javascript script string (which may include use of
     * jQuery functions on the document).
     * @return the result of the script execution.
     */
    private static Object executejQuery(final WebEngine engine, String minVersion, String jQueryLocation, String script) {
        return engine.executeScript(
                "(function(window, document, version, callback) { "
                + "var j, d;"
                + "var loaded = false;"
                + "if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) {"
                + "  var script = document.createElement(\"script\");"
                + "  script.type = \"text/javascript\";"
                + "  script.src = \"" + jQueryLocation + "\";"
                + "  script.onload = script.onreadystatechange = function() {"
                + "    if (!loaded && (!(d = this.readyState) || d == \"loaded\" || d == \"complete\")) {"
                + "      callback((j = window.jQuery).noConflict(1), loaded = true);"
                + "      j(script).remove();"
                + "    }"
                + "  };"
                + "  document.documentElement.childNodes[0].appendChild(script) "
                + "} "
                + "})(window, document, \"" + minVersion + "\", function($, jquery_loaded) {" + script + "});"
        );
    }

    public static void main(String[] args) {
        launch(args);
    }
}

(在此代码中,我只想强调字母&#39; t&#39;)

但此代码无法正常运行。我的意思是它只适用于某些页面!例如它适用于&#34; gist.github.com/jewelsea/3077942"或&#34; stackoverflow.com&#34;但它并没有在&#34; wikipedia.org&#34;或&#34; sunset.usc.edu/Research_Group/barry.html" (我得到错误,如&#34; TypeError:&#39;未定义&#39;不是对象&#34;)

问题出在哪里? 感谢您的帮助:)

0 个答案:

没有答案