javascript - 在Java中,当我们在WebView中加载HTML时,如何使用鼠标选择一个HTML元素?

标签 javascript java jquery swing javafx

JavaFX 中的 WebView 控件呈现 URL 并执行 JavaScript(包括 jQuery)。我们如何在鼠标悬停时从呈现的 WebView 控件中选择一个元素并在单击时获取其 Xpath?

我尝试添加 mousemove、mouseenter 和 mouseleave,但它同时匹配多个元素(父元素和子元素)。它应该只在一个元素周围添加边框。

主要应用程序:

// main/visualuserinput/VisualUserInput.java
package visualuserinput;

import javafx.application.Platform;
import javafx.concurrent.Worker;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import visualuserinput.FileUtil;

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

public class VisualUserInput extends JFrame {

    private final JFXPanel jfxPanel = new JFXPanel();
    private WebEngine engine;

    private String url = "https://www.bezrealitky.cz/vyhledat?offerType=spolubydleni&estateType=byt&priceFrom=5000&priceTo=8000&disposition=&ownership=&construction=&equipped=&balcony=&order=timeOrder_desc&boundary=%5B%5B%7B%22lat%22%3A50.171436864513%2C%22lng%22%3A14.506905276796942%7D%2C%7B%22lat%22%3A50.154133576294%2C%22lng%22%3A14.599004629591036%7D%2C%7B%22lat%22%3A50.14524430128%2C%22lng%22%3A14.58773054712799%7D%2C%7B%22lat%22%3A50.129307131988%2C%22lng%22%3A14.60087568578706%7D%2C%7B%22lat%22%3A50.122604734575%2C%22lng%22%3A14.659116306376973%7D%2C%7B%22lat%22%3A50.106512499343%2C%22lng%22%3A14.657434650206028%7D%2C%7B%22lat%22%3A50.090685542974%2C%22lng%22%3A14.705099547441932%7D%2C%7B%22lat%22%3A50.072175921973%2C%22lng%22%3A14.700004206235008%7D%2C%7B%22lat%22%3A50.056898491904%2C%22lng%22%3A14.640206899053055%7D%2C%7B%22lat%22%3A50.038528576841%2C%22lng%22%3A14.666852728301023%7D%2C%7B%22lat%22%3A50.030955909657%2C%22lng%22%3A14.656128752460972%7D%2C%7B%22lat%22%3A50.013435368522%2C%22lng%22%3A14.66854956530301%7D%2C%7B%22lat%22%3A49.99444182116%2C%22lng%22%3A14.640153080292066%7D%2C%7B%22lat%22%3A50.010839032542%2C%22lng%22%3A14.527474219359988%7D%2C%7B%22lat%22%3A49.970771602447%2C%22lng%22%3A14.46224174052395%7D%2C%7B%22lat%22%3A49.970669964027%2C%22lng%22%3A14.400648545303966%7D%2C%7B%22lat%22%3A49.941901176098%2C%22lng%22%3A14.395563234671044%7D%2C%7B%22lat%22%3A49.948384148423%2C%22lng%22%3A14.337635637038034%7D%2C%7B%22lat%22%3A49.958376114735%2C%22lng%22%3A14.324977842107955%7D%2C%7B%22lat%22%3A49.9676286223%2C%22lng%22%3A14.34491711110104%7D%2C%7B%22lat%22%3A49.971859099005%2C%22lng%22%3A14.326815050839059%7D%2C%7B%22lat%22%3A49.990608728081%2C%22lng%22%3A14.342731259186962%7D%2C%7B%22lat%22%3A50.002211140429%2C%22lng%22%3A14.29483886971002%7D%2C%7B%22lat%22%3A50.023596577558%2C%22lng%22%3A14.315872285282012%7D%2C%7B%22lat%22%3A50.058309376419%2C%22lng%22%3A14.248086830069042%7D%2C%7B%22lat%22%3A50.073179111%2C%22lng%22%3A14.290193274400963%7D%2C%7B%22lat%22%3A50.102973823639%2C%22lng%22%3A14.224439442359994%7D%2C%7B%22lat%22%3A50.130060800171%2C%22lng%22%3A14.302396419107936%7D%2C%7B%22lat%22%3A50.116019827009%2C%22lng%22%3A14.360785349547996%7D%2C%7B%22lat%22%3A50.148005694843%2C%22lng%22%3A14.365662825877052%7D%2C%7B%22lat%22%3A50.14142969454%2C%22lng%22%3A14.394903042943952%7D%2C%7B%22lat%22%3A50.171436864513%2C%22lng%22%3A14.506905276796942%7D%2C%7B%22lat%22%3A50.171436864513%2C%22lng%22%3A14.506905276796942%7D%5D%5D&hasDrawnBoundary=1&mapBounds=%5B%5B%7B%22lat%22%3A51.58923530498002%2C%22lng%22%3A15.399838165986353%7D%2C%7B%22lat%22%3A51.58923530498002%2C%22lng%22%3A10.593319611298853%7D%2C%7B%22lat%22%3A49.626953225810375%2C%22lng%22%3A10.593319611298853%7D%2C%7B%22lat%22%3A49.626953225810375%2C%22lng%22%3A15.399838165986353%7D%2C%7B%22lat%22%3A51.58923530498002%2C%22lng%22%3A15.399838165986353%7D%5D%5D&center=%7B%22lat%22%3A50.618326631013446%2C%22lng%22%3A12.996578888642588%7D&zoom=8&locationInput=praha&limit=15";

    public VisualUserInput() {
        super();
        initComponents();

        getContentPane().add(jfxPanel);

        setSize(500, 500);
        // Kill everything on closing the frame
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    private void initComponents() {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                WebView view = new WebView();
                engine = view.getEngine();
                engine.setJavaScriptEnabled(true);
                engine.setOnAlert(event -> {
                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                    alert.setTitle("Custom Alert");
                    alert.setContentText(event.getData());
                    alert.showAndWait();
                });
                engine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
                    if (Worker.State.SUCCEEDED.equals(newState)) {
                        Document doc = engine.getDocument();
                        Element styleNode = doc.createElement("script");
                        Text styleContent = null;
                        try {
                            styleContent = doc.createTextNode(FileUtil.gulp("test.js"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        styleNode.appendChild(styleContent);
                    doc.getDocumentElement().getElementsByTagName("head").item(0).appendChild(styleNode);

                    System.out.println(engine.executeScript("document.documentElement.innerHTML"));
                    }
                });
                engine.load(url);

                Button btn2 = new Button();
                btn2.setText("JS action");
                btn2.setPrefSize(100, 100);
                btn2.setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent event) {
                        engine.executeScript("testing()");
                    }
                });

                BorderPane borderPane = new BorderPane();
                borderPane.setTop(btn2);
                borderPane.setCenter(view);
                Scene scene = new Scene(borderPane);


                jfxPanel.setScene(scene);
            }
        });
    }

    public static void main(String[] args) {
        VisualUserInput main = new VisualUserInput();
        main.setVisible(true);
    }
}

FileUtil.java:

// main/visualuserinput/FileUtil.java
package visualuserinput;

import java.io.*;

public class FileUtil {
    public static String gulp(String filename) throws IOException {
        StringBuilder builder = new StringBuilder();
        try (InputStream stream = FileUtil.class.getClassLoader().getResourceAsStream(filename);
             InputStreamReader streamReader = new InputStreamReader(stream);
             BufferedReader reader = new BufferedReader(streamReader)) {
            for (String s = reader.readLine(); s != null; s = reader.readLine()) {
                builder.append(s).append(System.lineSeparator());
            }
        }

        return builder.toString();
    }
 }

测试.js:

// resources/test.js

// inject jQuery when it's not loaded yet
if (typeof jQuery === "undefined") {
    var scriptTag = document.createElement("script");
    scriptTag.setAttribute("type", "text/javascript");
    scriptTag.setAttribute("src", "https://code.jquery.com/jquery-3.4.1.slim.min.js");
    document.getElementsByTagName("head")[0].appendChild(scriptTag);
}

$("html *").click(function (e) {
    e.preventDefault();
    var value = getXPath(this);
    alert(value);
    return false;
});


$("html *").mousemove(
    function (e) {
        e.preventDefault();
        $(this).mouseenter(function () {
            $(this).css("border", "3px solid red");
        });

        $(this).mouseleave(function () {
            $(this).css("border", "none");
        });
        return false;
    }
);


function getXPath(element) {
    var val = element.value;
    var xpath = '';
    for (; element && element.nodeType === 1; element = element.parentNode) {
        //alert(element);
        var id = $(element.parentNode).children(element.tagName).index(element) + 1;
        id > 1 ? (id = '[' + id + ']') : (id = '');
        xpath = '/' + element.tagName.toLowerCase() + id + xpath;
    }

    return xpath;
}

function testing() {
    alert("executed");
    var articles = $("article");
    for (var i = 0; i < articles.length; i++) {
        var article = $(articles[i]);
        article.addClass("ScraperTableRow");
        article.css("border", "3px solid yellow");
    }
}

当前结果选择了多个元素并在它们周围添加了边框。

Image

预期结果应选择一个元素并在其周围添加边框。 单击时,它会显示一条警报,其中包含所选元素的 XPath。

最佳答案

您需要阻止事件在树上传播。

请参阅此示例:

https://www.w3schools.com/jquery/event_stoppropagation.asp

关于javascript - 在Java中,当我们在WebView中加载HTML时,如何使用鼠标选择一个HTML元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57171927/

相关文章:

javascript - AngularJS ui-router 无法解析服务调用

java - 当使用 HBase 作为 MapReduce 的源时,我可以扩展 TableInputFormatBase 来为每个区域创建多个拆分和多个映射器吗?

javascript - 如何从 html 输入获取属性值?

javascript - 设置 openlayers 弹出窗口大小的正确方法是什么?

javascript - 网络显示 Dom 内容已加载。 Console.log 不会记录到开发人员控制台。调试器没有命中。函数未被调用

javascript - 使用命令行运行任何 js 时,PhantomJS 会出现段错误

javascript - 在没有 .concat 的情况下基于索引合并 JavaScript 数组

java - Spring Security OAuth2 改变JSON错误响应格式

java - 在 O(n) 时间内找到正确的路径

javascript - JQuery无法获取上一张图片的src