JavaFX Webview: 为非超链接的点击添加事件监听器?

huangapple 未分类评论44阅读模式
英文:

JavaFX Webview: addEventListener for clicks NOT on an hyperlink?

问题

在 WebView 中,是否有一种方法可以对任何不在给定超链接上的点击执行函数?

我尝试在 WebView 上添加事件处理程序,始终执行该函数,然后在超链接上添加事件侦听器,以尝试消耗事件。但是,event.preventDefault()event.stopPropagation() 实际上并不能停止事件,所以当单击超链接时仍然会执行该函数。

在这个示例中,当单击超链接时仍然会打印消息:

import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;

public class Main extends Application {
    public static void main(String[] args) { launch(args); }

    public void start(Stage primaryStage) {
        // 设置 WebView
        WebView webView = new WebView();
        String content = "<br>some text<br> a link: <a href='www.google.com'>google</a></body>";
        webView.getEngine().loadContent(content);

        // 添加超链接侦听器
        webView.getEngine().getLoadWorker().stateProperty().addListener(
                (o, old, state) -> {
                    if (state != Worker.State.SUCCEEDED) { return; }

                    // 创建事件侦听器
                    EventListener listenerA = event -> {
                        System.out.println("Attempting to block the click");
                        // 实际上并不会阻止点击
                        event.preventDefault();
                        event.stopPropagation();
                    };

                    Document doc = webView.getEngine().getDocument();
                    // 向 <a> 超链接添加事件处理程序。
                    NodeList nodeList = doc.getElementsByTagName("a");
                    for (int i = 0; i < nodeList.getLength(); i++) {
                        EventTarget hyperlink = (EventTarget) nodeList.item(i);
                        hyperlink.addEventListener("click", listenerA, true);
                    }
                });
        // 添加点击侦听器
        webView.addEventHandler(MouseEvent.MOUSE_CLICKED,
                event -> System.out.println("I want this to be printed only when a click occurs outside an hyperlink"));

        // 设置场景
        VBox vBox = new VBox(webView);
        Scene scene = new Scene(vBox, 960, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

我尝试这样做是因为我将 WebView 用作 Swing UI 的透明覆盖层;我将点击转发到 Swing 组件,但如果用户单击覆盖层超链接,则不希望将点击转发到 Swing。

英文:

In WebView, is there a way to execute a function for any click NOT on an given hyperlink?

I tried to add an event handler on the WebView to always execute the function, and then add an event listener to hyperlinks in an attempt to consume the event. However, event.preventDefault() and event.stopPropagation() don't actually stop the event, so the function is still executed when an hyperlink is clicked.

In this example, the message is still printed when an hyperlink is clicked:

import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;

public class Main extends Application {
    public static void main(String[] args) { launch(args); }

    public void start(Stage primaryStage) {
        // Setup the WebView
        WebView webView = new WebView();
        String content = &quot;&lt;br&gt;some text&lt;br&gt; a link: &lt;a href=&#39;www.google.com&#39;&gt;google&lt;/a&gt;&lt;/body&gt;&quot;;
        webView.getEngine().loadContent(content);

        // Add the hyperlink listener
        webView.getEngine().getLoadWorker().stateProperty().addListener(
                (o, old, state) -&gt; {
                    if (state != Worker.State.SUCCEEDED) { return; }

                    // Create the event listener
                    EventListener listenerA = event -&gt; {
                        System.out.println(&quot;Attempting to block the click&quot;);
                        // Doesn&#39;t actually block the click
                        event.preventDefault();
                        event.stopPropagation();
                    };

                    Document doc = webView.getEngine().getDocument();
                    // Add event handler to &lt;a&gt; hyperlinks.
                    NodeList nodeList = doc.getElementsByTagName(&quot;a&quot;);
                    for (int i = 0; i &lt; nodeList.getLength(); i++) {
                        EventTarget hyperlink = (EventTarget) nodeList.item(i);
                        hyperlink.addEventListener(&quot;click&quot;, listenerA, true);
                    }
                });
        // Add the click listener
        webView.addEventHandler(MouseEvent.MOUSE_CLICKED,
                event -&gt; System.out.println(&quot;I want this to be printed only when a click occurs outside an hyperlink&quot;));

        // Setup the scene
        VBox vBox = new VBox(webView);
        Scene scene = new Scene(vBox, 960, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

I'm trying to do this because I use WebView as a transparent overlay for my Swing UI; I have clicks forwarded to the Swing components but I want to not forward clicks to Swing if the user clicks on an overlay hyperlink.

huangapple
  • 本文由 发表于 2020年4月7日 18:29:13
  • 转载请务必保留本文链接:https://java.coder-hub.com/61077921.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定